不能。net/rpc默认用Gob编码、不跨语言、无超时重试和服务发现,仅适合学习或单机通信;生产环境应选gRPC等成熟框架。
net/rpc能直接用于生产环境吗不能。标准库net/rpc默认使用Gob编码,不跨语言,HTTP传输层需手动包装,且无超时控制、重试、服务发现等能力。它适合学习RPC原理或单机模块间轻量通信,但线上微服务应优先选gRPC或Kitex等成熟框架。
net/rpc服务端注册函数必须满足什么签名必须是公开方法(首字母大写),接收两个指针参数,返回error:
func (t *T) MethodName(argType *ArgType, replyType *ReplyType) error
常见错误包括:
argType或replyType不是指针类型 → 报错"rpc: method has wrong number of ins"
"method not found"
"rpc: reply type is not a pointer"
error或数量不对 → 启动时报"method has wrong number of outs"
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 的 HTTPhandler 已注册到 DefaultServeMux // 若想用自定义 mux,必须用 rpc.Server.ServeHTTP 手动分发 srv := rpc.NewServer() srv.Register(new(HelloService)) http.Handle("/rpc", srv)
Call后一直阻塞,可能原因有哪些最常见的是网络不通或服务未监听,但还有几个隐蔽点:
Listen用的是localhost,而客户端连127.0.0.1(或反之)→ IPv4/IPv6解析差异导致连接被拒绝dial未设超时:rpc.DialHTTP("tcp", "127.0.0.1:8080")会无限等待TCP握手完成 → 必须用rpc.DialHTTPPath配合net.DialTimeout封装Call第三个参数传了非指针变量 → 返回值无法写入,但不会报错,只是reply保持零值"connection reset"而非业务错误建议始终用带超时的拨号:
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 很快,但让它的行为可预测、可调试、可运维,才是真正花时间的地方。