简历服务从 PHP 迁移到 Go 微服务后,需要和多个服务(用户中心、职位服务、AI 服务)通信。RESTful HTTP 调用在服务间高频调用场景下性能不够,2025年2月全面切换到 gRPC,今天把接口设计实践分享出来。
一、为什么选 gRPC
- 性能高:基于 HTTP/2,二进制协议,比 RESTful JSON 快 5-10 倍
- 强类型:Protobuf 定义接口,编译时检查,减少运行时错误
- 代码生成:自动生成客户端和服务端代码,不用手写 HTTP 调用
- 流式支持:支持双向流,适合简历解析等长耗时任务
- 生态成熟:Go 生态一等公民,拦截器、负载均衡、服务发现都有现成方案
二、Protobuf 接口定义
| |
三、错误码规范
统一错误码,不用 gRPC 默认的 code,用业务错误码:
| |
错误码分段:
- 0-999:通用错误(0成功,1参数错误,2未登录,3无权限,4不存在,5服务器错误)
- 1000-1999:用户服务
- 2000-2999:简历服务
- 3000-3999:职位服务
四、拦截器设计
gRPC 拦截器统一处理横切关注点:
| |
五、服务注册发现
用 etcd 做服务注册发现:
| |
六、踩坑经验
- Protobuf 字段编号不能改:字段编号是序列化的标识,改了会导致旧客户端解析失败。废弃字段要保留编号,不能复用
- 大消息性能问题:简历详情包含工作经历、教育经历等,消息体大时 gRPC 性能下降。用分页或按需加载,不要一次返回所有字段
- 超时设置:gRPC 默认没有超时,要手动设置 context 超时,防止服务 hang 住
- 错误信息不要泄露内部细节:返回给客户端的错误信息要简洁,内部错误详情记日志
七、总结
Go 微服务 gRPC 接口设计核心:
- Protobuf 定义接口:强类型、代码生成、编译时检查
- 统一错误码:业务错误码分段,不依赖 gRPC 默认 code
- 拦截器处理横切:日志、鉴权、限流、监控都用拦截器统一处理
- 服务注册发现:etcd + 客户端负载均衡,服务上下线自动感知
- 流式接口:长耗时任务用流式通信,支持进度反馈
- 兼容性设计:字段编号不能改,废弃字段保留,新增字段用默认值
gRPC 适合服务间高频调用场景,性能和类型安全都比 RESTful 好。但对外 API(前端调用)还是建议用 RESTful,gRPC 主要用于内部服务间通信。技术选型要根据场景,不是所有接口都要用 gRPC。