net/rpc服务端必须注册导出结构体的方法,如arith,且方法签名需为func(t, args, *reply) error;客户端需显式关闭连接,参数和返回值须可gob编码,http模式下路径必须严格匹配。

net/rpc 服务端必须注册导出的结构体方法
Go 的 net/rpc 不支持直接导出函数或非结构体方法,只能注册满足「首字母大写 + 接收者是导出类型」的方法。常见错误是把函数包在 main 包里、方法接收者用小写类型、或者忘了加指针接收者导致无法修改状态。
实操建议:
- 定义一个导出结构体(如
Arith),所有 RPC 方法都作为其方法 - 方法签名必须是
func(*T, *Args, *Reply) error,三个参数都得是指针 - 调用
rpc.Register(new(Arith))或rpc.RegisterName("Arith", new(Arith)),不能传值 - HTTP 服务模式下,
http.Handle("/rpc", rpc.DefaultServer)必须在http.ListenAndServe前执行
示例中若写成 func Add(int, int) int 或 func (a arith) Add(...),运行时不会报错,但客户端调用会返回 rpc: can't find service Arith.Add。
客户端 dial 后必须显式关闭连接
rpc.Dial 或 rpc.DialHTTP 返回的 *rpc.Client 底层持有 TCP 连接或 HTTP transport,不关会导致文件描述符泄漏,压测时容易触发 too many open files。
实操建议:
- 用完立即调用
client.Close(),别依赖 GC - 如果复用 client,需确保并发安全:标准库
*rpc.Client是线程安全的,但不要多个 goroutine 共享后又在某处 close - HTTP 模式下,
rpc.DialHTTP实际复用http.DefaultClient,但依然要调Close()—— 它会关底层 TCP 连接 - 注意:
client.Call失败不自动关连接,异常路径也要 defer close
参数和返回值类型必须可被 gob 编码
net/rpc 默认用 gob 编解码,只支持 Go 原生可序列化的类型。常见坑是传了 map[interface{}]interface{}、含闭包的函数、未导出字段的 struct,或自定义类型没实现 gob.GobEncoder 接口。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
实操建议:
- 参数和 reply 结构体所有字段必须首字母大写(导出)
- 避免用
interface{},改用具体类型如string、int、struct{X int} - 时间类型用
time.Time没问题(gob 内置支持),但别用自定义 time wrapper - 如果要用 JSON 编码,得自己实现
rpc.ServerCodec,标准库不提供rpc.DialJSON这类快捷方式
典型错误现象:rpc: gob error: type not registered for interface: xxx,说明传了未注册的接口类型或不可导出类型。
HTTP 模式下路径和协议要严格匹配
用 rpc.ServeHTTP 搭 HTTP RPC 时,客户端必须用 rpc.DialHTTP,且服务端注册路径(如 /rpc)和服务端 http.Handle 的路径必须一致;否则 404 或返回 HTML 页面而非 RPC 响应。
实操建议:
- 服务端:用
http.Handle("/rpc", http.HandlerFunc(rpc.DefaultServer.ServeHTTP)),路径别漏斜杠 - 客户端:
rpc.DialHTTP("tcp", "localhost:8080/rpc")中的路径部分会被忽略(DialHTTP只取 host:port),真正请求的是POST /rpc - 别用
curl直接测 ——gob编码的二进制数据 curl 看不到,也发不对;要用 Go client 或改用 JSON-RPC 才方便调试 - 如果混用
rpc.ServeConn和 HTTP handler,记得禁用默认 HTTP server 的 keep-alive 或设短超时,否则连接可能卡住
最容易被忽略的是:HTTP 模式下,服务端没有显式启动 http.Server,而是靠 http.ListenAndServe 驱动,一旦 handler 注册错位置(比如在 ListenAndServe 之后),RPC 就完全不响应,还查不出错在哪。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










