1 远程过程调用,是分布式系统中不同节点间流行的通信方式
--简单来说成熟的rpc库相对http容器,更多的是封装了“服务发现”,"负载均衡",“熔断降级”一类面向服务的高级特性。可以这么理解,rpc框架是面向服务的更高级的封装。如果把一个http servlet容器上封装一层服务发现和函数代理调用,那它就已经可以做一个rpc框架了。
所以为什么要用rpc调用?
因为良好的rpc调用是面向服务的封装,针对服务的可用性和效率等都做了优化。单纯使用http调用则缺少了这些特性。
既然有 HTTP 请求,为什么还要用 RPC 调用?
--包含传输协议([gRPC](grpc / grpc.io) 使用的 http2 协议)和序列化协议(的xml json,也有二进制编码的 protobuf hessian等。)。
--**必要性:内部子系统较多、接口非常多的情况下,
1 长链接,不必每次通信都要像http 一样去3次握手什么的,减少了网络开销;
2 有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统 一化的操作。
3 安全性。最后就是最近流行的服务化架构、服务化治理,RPC框架是一个强力的支撑**
--rpc是一种概念,http也是rpc实现的一种方式。
--方法只能有两个可序列化的参数,返回一个 error 类型
`type HelloService struct {}
func (p *HelloService) Hello(request string, reply *string) error {
*reply = "hello:" + request
return nil
}
**注册rpc服务**
func main() {
rpc.RegisterName("HelloService", new(HelloService))
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("ListenTCP error:", err)
}
conn, err := listener.Accept()
if err != nil {
log.Fatal("Accept error:", err)
}
rpc.ServeConn(conn)
}
```
HelloService rpc服务空间,并建立一个唯一的 TCP 连接,
rpc.ServeConn 函数在该 TCP 连接上为对方提供 RPC 服务。
**
```go
func main() {
client, err := rpc.Dial("tcp", "localhost:1234")
if err != nil {
log.Fatal("dialing:", err)
}
var reply string
err = client.Call("HelloService.Hello", "hello", &reply)
if err != nil {
log.Fatal(err)
}
fmt.Println(reply)
}
```
clinet
```go
func flipSale() {
err = client.Call(&ss, "contract_nftApprove", "0xEA9f61B3201012b89F41F13e10fdF1F63f8d70E2", 1)
if err != nil {
panic(err)
}
fmt.Printf("contract_nftApprove %s", reply)
//
(tokenId *big.Int, onSale bool, price float64, currencyAddress string, nftAddr string)
var client, err = rpc.Dial("http://154.83.17.166:8080")
err = client.Call(&ss, "contract_flipSale", 1,
true, float64(12.1), "0x5DEa0651beC7D1Fbec9Ec1905784F3b814F9338D", "0xEA9f61B3201012b89F41F13e10fdF1F63f8d70E2")
if err != nil {
panic(err)
}
fmt.Printf("contract_flipSale %s", reply)
}
```
gRPC 是 Google 公司基于 Protobuf 开发的跨语言的开源 RPC 框架。