gRPC面试题
2026/1/15大约 5 分钟gRPC面试题RPC
gRPC 面试题
一、基础概念
1.1 什么是 gRPC?
答:gRPC 是 Google 开发的高性能、开源的 RPC 框架。
核心特点:
- 基于 HTTP/2 协议
- 使用 Protobuf 作为序列化协议
- 支持多种编程语言
- 支持四种通信模式
- 内置流式传输支持
1.2 gRPC 和 REST 的区别?
答:
| 特性 | gRPC | REST |
|---|---|---|
| 协议 | HTTP/2 | HTTP/1.1 |
| 数据格式 | Protobuf(二进制) | JSON(文本) |
| 性能 | 高 | 中 |
| 流式传输 | 原生支持 | 有限 |
| 浏览器支持 | 需要 gRPC-Web | 原生 |
| 接口定义 | .proto 文件 | OpenAPI |
| 代码生成 | 自动 | 手动 |
选择建议:
- 内部微服务通信:gRPC
- 对外 API:REST
- 实时通信:gRPC
1.3 gRPC 的四种通信模式?
答:
- 一元 RPC(Unary)
rpc GetUser(Request) returns (Response);客户端发送一个请求,服务端返回一个响应。
- 服务端流(Server Streaming)
rpc ListUsers(Request) returns (stream User);客户端发送一个请求,服务端返回多个响应。
- 客户端流(Client Streaming)
rpc UploadFile(stream Chunk) returns (Response);客户端发送多个请求,服务端返回一个响应。
- 双向流(Bidirectional Streaming)
rpc Chat(stream Message) returns (stream Message);客户端和服务端都可以发送多个消息。
二、HTTP/2 相关
2.1 HTTP/2 有哪些特性?
答:
- 多路复用:单连接上并行处理多个请求
- 头部压缩:使用 HPACK 压缩头部
- 二进制分帧:数据以二进制帧传输
- 服务器推送:服务器可主动推送资源
- 流优先级:可设置请求优先级
2.2 为什么 gRPC 使用 HTTP/2?
答:
- 多路复用:减少连接数,提高效率
- 流式传输:原生支持双向流
- 头部压缩:减少传输数据量
- 二进制协议:与 Protobuf 配合更高效
三、拦截器
3.1 什么是拦截器?
答:拦截器是 gRPC 的中间件机制,可以在 RPC 调用前后执行自定义逻辑。
类型:
- UnaryServerInterceptor:服务端一元拦截器
- StreamServerInterceptor:服务端流拦截器
- UnaryClientInterceptor:客户端一元拦截器
- StreamClientInterceptor:客户端流拦截器
常见用途:
- 日志记录
- 认证授权
- 限流
- 错误恢复
- 链路追踪
3.2 如何实现认证拦截器?
答:
func AuthInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
// 获取元数据
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, status.Error(codes.Unauthenticated, "缺少元数据")
}
// 验证 token
tokens := md.Get("authorization")
if len(tokens) == 0 || !validateToken(tokens[0]) {
return nil, status.Error(codes.Unauthenticated, "认证失败")
}
return handler(ctx, req)
}四、错误处理
4.1 gRPC 有哪些状态码?
答:
| 状态码 | 说明 | 使用场景 |
|---|---|---|
| OK | 成功 | 正常响应 |
| INVALID_ARGUMENT | 无效参数 | 参数验证失败 |
| NOT_FOUND | 不存在 | 资源未找到 |
| PERMISSION_DENIED | 权限不足 | 无权访问 |
| UNAUTHENTICATED | 未认证 | 需要登录 |
| INTERNAL | 内部错误 | 服务器错误 |
| UNAVAILABLE | 不可用 | 服务暂时不可用 |
| DEADLINE_EXCEEDED | 超时 | 请求超时 |
4.2 如何处理 gRPC 错误?
答:
// 服务端返回错误
return nil, status.Error(codes.NotFound, "用户不存在")
// 客户端处理错误
resp, err := client.GetUser(ctx, req)
if err != nil {
st, ok := status.FromError(err)
if ok {
switch st.Code() {
case codes.NotFound:
// 处理不存在
case codes.InvalidArgument:
// 处理参数错误
}
}
}五、性能优化
5.1 如何优化 gRPC 性能?
答:
- 连接复用:使用连接池
- 流式传输:大数据使用流
- 压缩:启用 gzip 压缩
- 负载均衡:客户端负载均衡
- 超时设置:合理设置超时
- 批量操作:减少 RPC 调用次数
5.2 如何实现负载均衡?
答:
// 客户端负载均衡
conn, _ := grpc.Dial(
"dns:///service.example.com:50051",
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),
)负载均衡策略:
- pick_first:选择第一个
- round_robin:轮询
- grpclb:gRPC 负载均衡器
六、安全相关
6.1 如何实现 TLS 加密?
答:
// 服务端
creds, _ := credentials.NewServerTLSFromFile("server.crt", "server.key")
s := grpc.NewServer(grpc.Creds(creds))
// 客户端
creds, _ := credentials.NewClientTLSFromFile("ca.crt", "")
conn, _ := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(creds))6.2 如何实现 Token 认证?
答:
// 客户端发送 token
md := metadata.New(map[string]string{
"authorization": "Bearer " + token,
})
ctx := metadata.NewOutgoingContext(context.Background(), md)
resp, err := client.GetUser(ctx, req)
// 服务端验证 token
md, _ := metadata.FromIncomingContext(ctx)
tokens := md.Get("authorization")
// 验证 tokens[0]七、实践问题
7.1 如何处理大文件传输?
答:使用流式传输,分块发送:
service FileService {
rpc Upload(stream FileChunk) returns (UploadResponse);
rpc Download(DownloadRequest) returns (stream FileChunk);
}7.2 如何实现服务发现?
答:
- DNS 解析:使用 DNS SRV 记录
- Consul/Etcd:使用服务注册中心
- Kubernetes:使用 K8s Service
// 使用 Consul
resolver.Register(consul.NewBuilder())
conn, _ := grpc.Dial("consul://localhost:8500/service-name")7.3 如何实现链路追踪?
答:使用 OpenTelemetry:
import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
// 服务端
s := grpc.NewServer(
grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()),
)
// 客户端
conn, _ := grpc.Dial(
"localhost:50051",
grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
)八、面试回答模板
8.1 请介绍一下 gRPC
gRPC 是 Google 开发的高性能 RPC 框架,基于 HTTP/2 和 Protobuf。
核心特点:
- 高性能:HTTP/2 多路复用 + Protobuf 二进制编码
- 跨语言:支持多种编程语言
- 流式传输:支持四种通信模式
- 强类型:IDL 定义接口,自动生成代码
适用场景:
- 微服务间通信
- 实时数据传输
- 移动端与后端通信
与 REST 对比:gRPC 性能更好,但浏览器支持有限;REST 更通用,但性能较低。
8.2 gRPC 如何保证可靠性?
gRPC 通过以下机制保证可靠性:
- 超时控制:设置请求超时,避免无限等待
- 重试机制:配置重试策略,自动重试失败请求
- 健康检查:定期检查服务健康状态
- 负载均衡:分散请求到多个实例
- 熔断降级:配合熔断器使用
最佳实践:
- 设置合理的超时时间
- 只对幂等操作重试
- 使用健康检查剔除故障节点
