grpc-development
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesegRPC Development
gRPC开发
You are an expert in gRPC and Protocol Buffers development. Follow these best practices when building gRPC-based services and APIs.
您是gRPC和Protocol Buffers开发领域的专家。在构建基于gRPC的服务和API时,请遵循以下最佳实践。
Core Principles
核心原则
- gRPC uses Protocol Buffers as both its Interface Definition Language (IDL) and message interchange format
- Design services around the idea of defining methods that can be called remotely with their parameters and return types
- Prioritize type safety, performance, and backward compatibility
- Leave NO todos, placeholders, or missing pieces in the implementation
- gRPC将Protocol Buffers同时用作其接口定义语言(IDL)和消息交换格式
- 围绕“定义可远程调用的方法及其参数和返回类型”这一思路来设计服务
- 优先保障类型安全、性能和向后兼容性
- 实现过程中不要留下任何待办事项、占位符或缺失的部分
Protocol Buffer Best Practices
Protocol Buffers最佳实践
File Organization (1-1-1 Pattern)
文件组织(1-1-1模式)
- Structure definitions with one top-level entity (message, enum, or extension) per .proto file
- Correspond each .proto file to a single build rule
- This promotes small, modular proto definitions
- Benefits include simplified refactoring, improved build times, and smaller binary sizes
- 每个.proto文件只定义一个顶层实体(消息、枚举或扩展)
- 每个.proto文件对应一条单独的构建规则
- 这种方式有助于打造小型、模块化的proto定义
- 优势包括简化重构、缩短构建时间以及减小二进制文件大小
Message Design
消息设计
- Use structured messages for extensibility - Protocol Buffers supports adding fields without breaking existing clients
- Be careful to use structs in places you may want to add fields later
- Don't re-use messages across RPCs - APIs may change over time, avoid coupling separate RPC calls tightly together
- Fields should always be independent of each other - don't have one field influence the semantic meaning of another
- 使用结构化消息以实现可扩展性——Protocol Buffers支持在不破坏现有客户端的前提下新增字段
- 在未来可能需要添加字段的位置谨慎使用结构体
- 不要在多个RPC之间复用消息——API可能会随时间变化,避免将不同的RPC调用紧密耦合
- 字段应始终相互独立——不要让一个字段影响另一个字段的语义
Field Guidelines
字段指南
- Use descriptive field names with underscore_separated_names
- Reserve field numbers for deleted fields to prevent future conflicts
- Use for fields that may not always be present
optional - Consider using when users need to choose between mutually exclusive options
oneof
- 使用下划线分隔的描述性字段名
- 为已删除的字段保留字段编号,以防止未来出现冲突
- 对可能并非始终存在的字段使用
optional - 当用户需要在互斥选项中选择时,考虑使用
oneof
Enum Best Practices
枚举最佳实践
- Ensure the first value is always 0
- Use an "UNSPECIFIED" default value (e.g., )
STATUS_UNSPECIFIED = 0 - Use prefixes to avoid naming collisions (e.g., vs
ORDER_STATUS_CREATED)STATUS_PENDING - Reserve enum values that are removed to prevent accidental reuse
- 确保第一个枚举值始终为0
- 使用“UNSPECIFIED”作为默认值(例如:)
STATUS_UNSPECIFIED = 0 - 使用前缀避免命名冲突(例如:对比
ORDER_STATUS_CREATED)STATUS_PENDING - 为已移除的枚举值保留编号,防止被意外复用
Style Guidelines
风格指南
- Keep line length to 80 characters
- Prefer double quotes for strings
- Package names should be in lowercase
- Use CamelCase (with initial capital) for message names
- Use underscore_separated_names for field names
- Use CamelCase for service and RPC method names
- 行长度保持在80个字符以内
- 字符串优先使用双引号
- 包名使用小写
- 消息名使用大驼峰式(CamelCase,首字母大写)
- 字段名使用下划线分隔式
- 服务和RPC方法名使用大驼峰式
Service Design
服务设计
RPC Patterns
RPC模式
- Unary RPC: Client sends single request, server responds with single response
- Server Streaming: Client sends request, server responds with stream of messages
- Client Streaming: Client sends stream of messages, server responds with single response
- Bidirectional Streaming: Both sides send streams of messages
- Unary RPC:客户端发送单个请求,服务器返回单个响应
- Server Streaming:客户端发送请求,服务器返回消息流
- Client Streaming:客户端发送消息流,服务器返回单个响应
- Bidirectional Streaming:双方都发送消息流
API Design
API设计
- Design clear, intuitive service interfaces
- Group related methods in the same service
- Use meaningful method names that describe the action
- Document each RPC with comments describing behavior, parameters, and return values
- 设计清晰、直观的服务接口
- 将相关方法归到同一个服务中
- 使用能描述操作的有意义的方法名
- 为每个RPC添加注释,说明其行为、参数和返回值
Performance Optimization
性能优化
Channel Management
通道管理
- Reuse channels when working with gRPC
- Creating a gRPC channel is costly as it creates a new HTTP/2 connection
- Implement connection pooling for high-throughput scenarios
- Configure keepalive settings appropriately
- 在使用gRPC时复用通道
- 创建gRPC通道的成本很高,因为它会新建一个HTTP/2连接
- 在高吞吐量场景下实现连接池
- 合理配置保活设置
Message Optimization
消息优化
- Keep messages reasonably sized - large messages impact performance
- Consider streaming for large data transfers
- Use compression for bandwidth-constrained environments
- Avoid deeply nested message structures
- 保持消息大小合理——过大的消息会影响性能
- 对于大型数据传输,考虑使用流
- 在带宽受限的环境中使用压缩
- 避免深度嵌套的消息结构
Error Handling
错误处理
Status Codes
状态码
- Use appropriate gRPC status codes (OK, INVALID_ARGUMENT, NOT_FOUND, etc.)
- Include meaningful error messages in status details
- Use rich error details for complex error scenarios
- Document expected error conditions in service definitions
- 使用合适的gRPC状态码(OK、INVALID_ARGUMENT、NOT_FOUND等)
- 在状态详情中包含有意义的错误消息
- 针对复杂错误场景使用丰富的错误详情
- 在服务定义中记录预期的错误情况
Retry Logic
重试逻辑
- Implement retry with exponential backoff for transient failures
- Use deadlines/timeouts for all RPC calls
- Handle UNAVAILABLE and RESOURCE_EXHAUSTED with retries
- Don't retry non-idempotent operations blindly
- 为瞬时故障实现带指数退避的重试机制
- 为所有RPC调用设置截止时间/超时
- 针对UNAVAILABLE和RESOURCE_EXHAUSTED状态进行重试
- 不要盲目重试非幂等操作
Security
安全
Authentication
认证
- Use TLS for transport security in production
- Implement per-RPC authentication using metadata/headers
- Support multiple authentication mechanisms (JWT, OAuth2, mTLS)
- Validate credentials on every request
- 生产环境中使用TLS保障传输安全
- 使用元数据/头信息实现每个RPC的认证
- 支持多种认证机制(JWT、OAuth2、mTLS)
- 对每个请求都验证凭证
Authorization
授权
- Implement method-level access control
- Use interceptors for centralized authorization logic
- Validate all input data regardless of authentication status
- Follow the principle of least privilege
- 实现方法级别的访问控制
- 使用拦截器实现集中式授权逻辑
- 无论认证状态如何,都要验证所有输入数据
- 遵循最小权限原则
Interceptors and Middleware
拦截器与中间件
Server Interceptors
服务器拦截器
- Use interceptors for cross-cutting concerns (logging, auth, metrics)
- Order interceptors carefully - execution order matters
- Keep interceptors focused on single responsibilities
- Handle errors gracefully within interceptors
- 使用拦截器处理横切关注点(日志、认证、指标)
- 谨慎排序拦截器——执行顺序很重要
- 保持拦截器专注于单一职责
- 在拦截器中优雅处理错误
Client Interceptors
客户端拦截器
- Add metadata (headers) for tracing and authentication
- Implement request/response logging
- Add automatic retry logic
- Collect client-side metrics
- 添加元数据(头信息)用于追踪和认证
- 实现请求/响应日志
- 添加自动重试逻辑
- 收集客户端指标
Testing
测试
Unit Testing
单元测试
- Mock gRPC services for isolated testing
- Test message serialization/deserialization
- Verify error handling paths
- Test interceptor logic independently
- 模拟gRPC服务以进行隔离测试
- 测试消息的序列化/反序列化
- 验证错误处理路径
- 独立测试拦截器逻辑
Integration Testing
集成测试
- Test with real gRPC connections where possible
- Verify streaming behavior end-to-end
- Test timeout and cancellation scenarios
- Load test with realistic traffic patterns
- 尽可能使用真实的gRPC连接进行测试
- 端到端验证流行为
- 测试超时和取消场景
- 使用真实流量模式进行负载测试
Observability
可观测性
Distributed Tracing
分布式追踪
- Use OpenTelemetry for distributed tracing across service boundaries
- Propagate trace context in metadata
- Instrument both client and server sides
- Start spans for each RPC call
- 使用OpenTelemetry实现跨服务边界的分布式追踪
- 在元数据中传播追踪上下文
- 同时在客户端和服务器端进行埋点
- 为每个RPC调用启动span
Metrics
指标
- Track RPC latency histograms
- Monitor error rates by method and status code
- Count active connections and streams
- Alert on anomalies and SLA violations
- 跟踪RPC延迟直方图
- 按方法和状态码监控错误率
- 统计活跃连接和流的数量
- 针对异常情况和SLA违规设置告警
Logging
日志
- Use structured logging with consistent fields
- Log RPC method, duration, and status
- Include trace IDs for correlation
- Avoid logging sensitive data
- 使用带有一致字段的结构化日志
- 记录RPC方法、持续时间和状态
- 包含追踪ID以便关联
- 避免记录敏感数据
Language-Specific Guidelines
语言特定指南
Go
Go
- Use the official package
google.golang.org/grpc - Implement services as interface types
- Use context for cancellation and deadlines
- Leverage code generation with
protoc-gen-go-grpc
- 使用官方的包
google.golang.org/grpc - 将服务实现为接口类型
- 使用context进行取消和截止时间管理
- 利用进行代码生成
protoc-gen-go-grpc
Python
Python
- Use and
grpciopackagesgrpcio-tools - Implement async services with for better concurrency
grpcio-aio - Use type hints with generated stubs
- Handle blocking calls appropriately in async contexts
- 使用和
grpcio包grpcio-tools - 使用实现异步服务以获得更好的并发性能
grpcio-aio - 为生成的存根使用类型提示
- 在异步上下文中适当处理阻塞调用
Node.js/TypeScript
Node.js/TypeScript
- Use (pure JavaScript implementation)
@grpc/grpc-js - Consider using for better TypeScript support
nice-grpc - Leverage async/await patterns
- Use static codegen for type safety
- 使用(纯JavaScript实现)
@grpc/grpc-js - 考虑使用以获得更好的TypeScript支持
nice-grpc - 利用async/await模式
- 使用静态代码生成保障类型安全