贝利信息

Go语言实现简单RPC调用_Golang服务通信实战

日期:2026-01-16 00:00 / 作者:P粉602998670
不能。net/rpc默认用Gob编码、不跨语言、无超时重试和服务发现,仅适合学习或单机通信;生产环境应选gRPC等成熟框架。

Go标准库net/rpc能直接用于生产环境吗

不能。标准库net/rpc默认使用Gob编码,不跨语言,HTTP传输层需手动包装,且无超时控制、重试、服务发现等能力。它适合学习RPC原理或单机模块间轻量通信,但线上微服务应优先选gRPCKitex等成熟框架。

net/rpc服务端注册函数必须满足什么签名

必须是公开方法(首字母大写),接收两个指针参数,返回error

func (t *T) MethodName(argType *ArgType, replyType *ReplyType) error

常见错误包括:

http.ServeMux挂载rpc.Server时为什么客户端连不上

rpc.Server默认注册在"/_goRPC_"路径,但http.ServeMux不会自动转发该路径——必须显式调用rpc.HandleHTTP(),它会注册"/rpc""/debug/rpc"两个handler。

正确做法:

rpc.Register(new(HelloService))
rpc.HandleHTTP()
http.ListenAndServe(":8080", nil)

如果自己用http.ServeMux,需手动绑定:

mux := http.NewServeMux()
rpc.HandleHTTP()
// 此时 rpc.DefaultServer 的 HTTP 

handler 已注册到 DefaultServeMux // 若想用自定义 mux,必须用 rpc.Server.ServeHTTP 手动分发 srv := rpc.NewServer() srv.Register(new(HelloService)) http.Handle("/rpc", srv)

客户端调用Call后一直阻塞,可能原因有哪些

最常见的是网络不通或服务未监听,但还有几个隐蔽点:

建议始终用带超时的拨号:

conn, err := net.DialTimeout("tcp", "127.0.0.1:8080", 3*time.Second)
if err != nil {
    log.Fatal(err)
}
client := rpc.NewClient(conn)

真实 RPC 场景里,序列化格式、连接复用、上下文取消、错误分类这些点,标准库都不管——写完一个能跑的 demo 很快,但让它的行为可预测、可调试、可运维,才是真正花时间的地方。