RPC基础用法
首先copy下RPC的基本定义:
远程过程调用(Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。
golang官方库为net/rpc,提供encoding/gob方法实现编解码
RPC相关内容:
数据传输:JSON Protobuf thrift
负载:随机算法 轮询 一致性hash 加权
异常容错:健康检测 熔断 限流
golang编写rpc程序必须满足以下条件:
- 结构体首字母得大写
- 必须是公有的方法,即方法首字母大写
- 只有两个参数,第一个为接收参数,第二个为返回给客户端的指针类型的参数,所以通信时需要将信息封装好才能满足要求
- 一个返回值:error
大致框架流程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import "net/rpc"
// 服务端注册的结构体 type ServiceName struct{ //your field here }
type Request struct{
}
// 返回给客户端的参数 type ResponseParam struct{
}
// 传参均通过第二个指针类型的参数 func (s *ServiceName)Method1(request Request, response *ResponseParam)error{
}
//主函数 func main(){ // 注册服务 rpc.Register(new(ServiceName)) // 服务绑定到http协议,即通过http来传输 rpc.HandleHttp() // 监听服务 err := http.ListenAndServe(":8000", nil) if err != nil{ log.Fatal("Listening error :", err) }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // 端口号要一致 conn ,err := rpc.DialHTTP("tcp", ":8000") if err != nil{ log.Fatal("Dailing error :", err) } //客户端定义请求 req := Request{} var res ResponseParam // 拨号RPC服务 // 第一个参数含义为 服务名.方法名 err = rpc.Call("ServiceName.MethodName", req, &res) if err != nil{ log.Fatal("Listening error :", err) } // 对传回来的res的操作 ...
|
下载 rpcx
库
服务端编写类似:
注意定义方法时多了第一个参数为context.Context,在并发编程时介绍过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import "context"
type Args struct { A int B int }
type Reply struct { C int }
type Arith int
func (t *Arith) Mul(ctx context.Context, args *Args, reply *Reply) error { reply.C = args.A * args.B return nil }
|
主函数中也是类似函数注册服务:
1 2 3 4
| s := server.NewServer() s.RegisterName("Arith", new(Arith), "") // or s.Register(new(Arith), "") s.Serve("tcp", ":8972")
|