hello 大家好呀,我是小楼,这是系列文《Go底层原理剖析》的第三篇,依旧分析 Http 模块。我们今天来看 Go内置的 RPC。说起 RPC 大家想到的一般是框架,Go 作为编程语言竟然还内置了 RPC,着实让我有些吃鲸。

从一个 Demo 入手
为了快速进入状态,我们先搞一个 Demo,当然这个 Demo 是参考 Go 源码 src/net/rpc/server.go,做了一丢丢的修改。
- package common
- type Args struct {
- A, B int
- }
- type Quotient struct {
- Quo, Rem int
- }
复制代码- type Arith struct{}
- func (t *Arith) Multiply(args *common.Args, reply *int) error {
- *reply = args.A * args.B
- return nil
- }
- func (t *Arith) Divide(args *common.Args, quo *common.Quotient) error {
- if args.B == 0 {
- return errors.New("divide by zero")
- }
- quo.Quo = args.A / args.B
- quo.Rem = args.A % args.B
- return nil
- }
复制代码- func main() {
- arith := new(Arith)
- rpc.Register(arith)
- rpc.HandleHTTP()
- l, e := net.Listen("tcp", ":9876")
- if e != nil {
- panic(e)
- }
- go http.Serve(l, nil)
- var wg sync.WaitGroup
- wg.Add(1)
- wg.Wait()
- }
复制代码 [code]func main() { client, err := rpc.DialHTTP("tcp", "127.0.0.1:9876") if err != nil { panic(err) } args := common.Args{A: 7, B: 8} var reply int // 同步调用 err = client.Call("Arith.Multiply", &args, &reply) if err != nil { panic(err) } fmt.Printf("Call Arith: %d * %d = %d\n", args.A, args.B, reply) // 异步调用 quotient := new(common.Quotient) divCall := client.Go("Arith.Divide", args, quotient, nil) replyCall := |