12.1.1 net/rpc 的基本使用
net/rpc 是 Go 标准库中提供的一个轻量级的远程过程调用(RPC)框架。它允许你在不同的程序或进程之间调用方法,就像调用本地方法一样,适用于简单的分布式系统。
net/rpc 介绍
- 同步调用:默认情况下,net/rpc 支持同步调用,客户端请求后等待服务器处理并返回结果。
- 传输协议:支持 TCP 和 HTTP 协议,还可以通过自定义实现支持其他协议。
- 数据编码:使用 Go 的 gob 编码,专为高效地传输 Go 原生数据结构设计。
使用场景
- 教育和学习:合适初学者学习 RPC 概念和基本使用方法。
- 小型应用程序:对于简单、低负载的应用,net/rpc 提供了一种快速入门的方法。
- 内部服务通信:适用于内部服务之间需要进行简单的 RPC 调用。
流程图
net/rpc 通信流程:
+-------------------+
| Client Application|
+-------------------+
|
v
+-------------------+
| net/rpc Client |
+-------------------+
|
v Network
+-------------------+
| net/rpc Server |
+-------------------+
|
v
+-------------------+
| Server Application|
+-------------------+
原生代码示例
以下是一个使用 net/rpc 实现简单 RPC 服务的示例,包括服务器和客户端的实现。
RPC 服务
// server.go
package main
import (
"log"
"net"
"net/rpc"
)
// Args holds arguments to be passed to the RPC methods
type Args struct {
A, B int
}
// Arith provides an arithmetic service
type Arith int
// Multiply multiplies two numbers
func (t *Arith) Multiply(args *Args, reply *int) error {
*reply = args.A * args.B
return nil
}
func main() {
arith := new(Arith)
rpc.Register(arith)
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("Listen error:", err)
}
defer listener.Close()
log.Println("Serving RPC handler")
for {
conn, err := listener.Accept()
if err != nil {
log.Fatal("Accept error:", err)
}
go rpc.ServeConn(conn)
}
}
RPC 客户端
// client.go
package main
import (
"fmt"
"log"
"net/rpc"
)
// Args holds arguments to be passed to the RPC methods
type Args struct {
A, B int
}
func main() {
client, er