grpc-development

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

gRPC 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
    optional
    for fields that may not always be present
  • Consider using
    oneof
    when users need to choose between mutually exclusive options
  • 使用下划线分隔的描述性字段名
  • 为已删除的字段保留字段编号,以防止未来出现冲突
  • 对可能并非始终存在的字段使用
    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.,
    ORDER_STATUS_CREATED
    vs
    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
    google.golang.org/grpc
    package
  • 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
    grpcio
    and
    grpcio-tools
    packages
  • Implement async services with
    grpcio-aio
    for better concurrency
  • 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
    @grpc/grpc-js
    (pure JavaScript implementation)
  • Consider using
    nice-grpc
    for better TypeScript support
  • Leverage async/await patterns
  • Use static codegen for type safety
  • 使用
    @grpc/grpc-js
    (纯JavaScript实现)
  • 考虑使用
    nice-grpc
    以获得更好的TypeScript支持
  • 利用async/await模式
  • 使用静态代码生成保障类型安全