Golang微服务应统一用Protocol Buffers定义契约,gin/echo处理REST对外API,gRPC处理内部高频通信,通过grpc-gateway实现双协议共存;共享service层与中间件/拦截器保障可观测性与一致性。

用 Golang 构建微服务 Web 接口,核心是把服务拆成独立、可通信的模块,同时支持 REST(面向资源、HTTP/JSON)和 RPC(面向方法、高效调用)。关键不在于堆砌框架,而在于合理分层、统一通信契约、避免重复造轮子。
选型:轻量但可扩展的组合
推荐使用 gin 或 echo 处理 REST 请求,它们路由清晰、中间件友好;RPC 层推荐 gRPC(基于 Protocol Buffers),天然支持多语言、双向流、强类型契约。两者共存不冲突——REST 对外暴露 API,gRPC 用于服务间内部调用。
- REST 接口走 HTTP/1.1,返回 JSON,适合前端、第三方系统集成
- gRPC 接口走 HTTP/2,二进制传输,性能高、延迟低,适合服务间高频通信
- 共享同一套业务逻辑(如 service 层),避免 REST handler 和 gRPC server 各写一遍业务
定义统一的数据契约(Protocol Buffers)
用 .proto 文件定义请求/响应结构和 RPC 方法,既是 gRPC 的接口描述,也可生成 REST 映射(通过 grpc-gateway 自动生成反向代理)。
例如:// api/v1/user.proto
立即学习“go语言免费学习笔记(深入)”;
syntax = "proto3"; package v1;service UserService { rpc GetUser(GetUserRequest) returns (GetUserResponse); }
message GetUserRequest { string user_id = 1; }
message GetUserResponse { string id = 1; string name = 2; int32 age = 3; }
用 protoc 生成 Go 代码(含 gRPC server/client + JSON mapping),再配合 grpc-gateway,就能让同一个 gRPC 方法自动响应 GET /v1/users/{user_id} 这样的 REST 请求。
启动双协议服务(HTTP + gRPC)
一个进程同时监听两个端口:一个给 REST(经 grpc-gateway 转发到 gRPC),一个直连 gRPC Server。
- gRPC Server:绑定
:9000,注册你的 service 实现 - HTTP Server:绑定
:8080,用 grpc-gateway 启动反向代理,转发 /v1/\*\* 到本地 gRPC 地址 - 两者共享同一个底层 service 实例(比如
UserService{repo: userRepo}),确保逻辑一致
添加基础能力:中间件与可观测性
微服务离不开日志、链路追踪、熔断限流。Gin/Echo 支持中间件,gRPC 支持拦截器(interceptor),可以复用逻辑:
- 统一日志:记录请求 ID、耗时、路径、状态码或错误
- OpenTelemetry:用
otelgrpc和otelgin插件自动采集 span - 限流:REST 层用
golang.org/x/time/rate,gRPC 层用 interceptor 包裹 - 错误处理:定义标准错误码(如
ErrNotFound=404),在 gateway 和 gRPC 层统一转成 HTTP 状态码或 gRPC status










