Go语言怎么做RPC服务_Go语言net/rpc教程【经典】

5次阅读

不能。net/rpc 默认基于 TCP 二进制协议,不注册 HTTP handler,无法直接通过 HTTP 调用;需手动包装 HTTP handler 并配合 jsonrpc 或改用 gRPC/REST。

Go 语言怎么做 RPC 服务_Go 语言 net/rpc 教程【经典】

Go 的 net/rpc 能不能直接对外提供 HTTP RPC?

不能。默认的 net/rpc 是基于 TCP 的二进制协议,客户端必须用 Go 的 rpc.Client 连接,其他语言或 curl 根本没法调。有人试过用浏览器访问 :8080/_rpc_/,结果只看到 404 page not found —— 因为它压根没注册 HTTP handler。

  • 如果真想走 HTTP,得手动包装:用 http.ServeMux 注册一个路径,再把请求 body 交给 rpc.Server.ServeCodec 处理(比如配合 rpc.NewHTTPClientCodec
  • 更现实的做法是别硬扛:改用 net/rpc/jsonrpc + 自定义 HTTP handler,或者直接切到 gRPC / REST
  • net/rpc 的 HTTP 支持仅限于内部调试用的 rpc.DebugHTTP,它暴露的是服务统计页,不是可调用接口

为什么用 jsonrpc 时客户端总报 invalid character '?

这是典型的协议错配:客户端发的是 JSON-RPC 请求,但服务端监听的是原始 TCP,没做解码适配。Go 的 net/rpc 默认用 gob 编码,而 jsonrpc 是另一套独立的 codec 实现,必须显式启用。

  • 服务端启动时不能只调 rpc.Register,还得用 rpc.ServeCodec 配合 jsonrpc.NewServerCodec(通常封装在自定义 listener 里)
  • 客户端必须用 jsonrpc.NewClientjsonrpc.NewClientCodec,不能用默认的 rpc.Dial
  • 常见坑:误以为 rpc.Register 后加个 http.Handle("/rpc", rpc.Handler) 就行——其实 rpc.Handler 只支持 gob,不认 JSON

方法签名不符合 func(*T, *S, *error) 会导致什么?

服务端启动不报错,但调用时返回 method XXX not found 或静默失败。Go 的 rpc.Server 在注册时只检查签名结构,不校验字段导出性或指针层级,等真正调用才反射匹配。

  • 第一个参数必须是指针(*T),代表接收者;第二个是输入参数指针(*S);第三个必须是 *error 类型,不能是 error 或其他名字的错误变量
  • 所有参数结构体里的字段必须首字母大写(导出),否则 JSON/gob 编码会忽略它们,导致传参为空
  • 返回值只能有且仅有三个,顺序不能换,类型不能松动——哪怕写成 *errors.Error 也不行

要不要在生产环境用 net/rpc

除非整个系统全是 Go 且对协议无扩展需求,否则不建议。它没有超时控制、流式响应、中间件、服务发现这些现代 RPC 必备能力,连 context 透传都要自己 hack。

立即学习 go 语言免费学习笔记(深入)”;

  • 内置的 gob 编码不跨语言,jsonrpc 又缺标准规范(比如无统一 error code、无 request id)
  • 连接复用靠客户端自己维护 *rpc.Client,服务端无法优雅关闭活跃连接
  • 真正上线前你大概率要补日志、熔断、指标埋点——这些在 gRPC 或 Kitex 里是开箱即用的,而在 net/rpc 里得一行行拧螺丝

最常被忽略的一点:它的错误传播机制是「全有或全无」——只要 handler 函数 panic,整个连接就断,且错误信息不会透传给客户端,只在服务端日志里留一行 goroutine stack trace。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-25发表,共计1460字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources