gRPC 入门教程

更新时间:2026-03-27 | 阅读时间:约 15 分钟

本文内容:gRPC 是 Google 开源的高性能 RPC 框架,基于 HTTP/2 和 Protocol Buffers。本教程将带你从零开始掌握 gRPC 的核心概念、服务定义、代码生成和实际应用场景。

什么是 gRPC?

gRPC(gRPC Remote Procedure Calls)是 Google 于 2015 年开源的高性能远程过程调用框架。它基于 HTTP/2 协议,使用 Protocol Buffers 作为接口描述语言和数据序列化格式,支持多种编程语言。

gRPC 的核心特点

gRPC vs REST

特性 gRPC REST
协议 HTTP/2 HTTP/1.1 或 HTTP/2
数据格式 Protocol Buffers(二进制) JSON/XML(文本)
性能 高(二进制序列化) 中(文本解析开销)
类型系统 强类型(.proto 定义) 弱类型(需额外文档)
流式支持 原生支持双向流 需要额外实现
浏览器支持 需要 gRPC-Web 代理 原生支持

Protocol Buffers 基础

Protocol Buffers(简称 Protobuf)是 gRPC 的接口描述语言和数据序列化格式。通过 .proto 文件定义消息结构和服务接口。

消息定义

// 定义请求消息
message UserRequest {
  int32 user_id = 1;      // 字段编号,用于二进制编码
  string username = 2;
}

// 定义响应消息
message UserResponse {
  int32 user_id = 1;
  string username = 2;
  string email = 3;
  bool is_active = 4;
}

字段类型

类型 说明 示例
标量类型 基础数据类型 int32, int64, uint32, uint64, float, double, bool, string, bytes
枚举类型 自定义枚举 enum Status { UNKNOWN = 0; SUCCESS = 1; ERROR = 2; }
重复字段 数组/列表 repeated string tags = 5;
Map 字段 键值对 map<string, int32> scores = 6;
嵌套消息 消息中包含消息 Address address = 7;

服务定义

// 定义服务接口
service UserService {
  // 一元 RPC:客户端发送一个请求,服务器返回一个响应
  rpc GetUser(UserRequest) returns (UserResponse);
  
  // 服务器流:客户端发送一个请求,服务器返回流式响应
  rpc ListUsers(ListUsersRequest) returns (stream UserResponse);
  
  // 客户端流:客户端发送流式请求,服务器返回一个响应
  rpc CreateUser(stream UserRequest) returns (UserResponse);
  
  // 双向流:客户端和服务器都使用流式通信
  rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}

快速开始

1. 安装 Protocol Buffers 编译器

# macOS
brew install protobuf

# Linux (Ubuntu/Debian)
sudo apt-get install protobuf-compiler

# 验证安装
protoc --version

2. 安装 gRPC 插件

# Python
pip install grpcio grpcio-tools

# Node.js
npm install @grpc/grpc-js @grpc/proto-loader

# Go
go get google.golang.org/protobuf/cmd/protoc-gen-go
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc

3. 编写 .proto 文件

// user.proto
syntax = "proto3";

package user;

// 请求消息
message GetUserRequest {
  int32 user_id = 1;
}

// 响应消息
message GetUserResponse {
  int32 user_id = 1;
  string username = 2;
  string email = 3;
}

// 服务定义
service UserService {
  rpc GetUser(GetUserRequest) returns (GetUserResponse);
}

4. 生成代码

# Python
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. user.proto

# Node.js (使用 ts-proto 或 protobufjs)
npx protoc --ts_out=. --proto_path=. user.proto

# Go
protoc --go_out=. --go_opt=paths=source_relative \
       --go-grpc_out=. --go-grpc_opt=paths=source_relative \
       user.proto

实现 gRPC 服务

Python 服务端示例

import grpc
from concurrent import futures
import user_pb2
import user_pb2_grpc

class UserServiceServicer(user_pb2_grpc.UserServiceServicer):
    def GetUser(self, request, context):
        # 模拟从数据库获取用户
        user_data = {
            1: {"username": "alice", "email": "alice@example.com"},
            2: {"username": "bob", "email": "bob@example.com"}
        }
        
        user_id = request.user_id
        if user_id in user_data:
            return user_pb2.GetUserResponse(
                user_id=user_id,
                username=user_data[user_id]["username"],
                email=user_data[user_id]["email"]
            )
        else:
            context.set_code(grpc.StatusCode.NOT_FOUND)
            context.set_details("User not found")
            return user_pb2.GetUserResponse()

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    user_pb2_grpc.add_UserServiceServicer_to_server(
        UserServiceServicer(), server
    )
    server.add_insecure_port('[::]:50051')
    server.start()
    print("Server started on port 50051")
    server.wait_for_termination()

if __name__ == '__main__':
    serve()

Python 客户端示例

import grpc
import user_pb2
import user_pb2_grpc

def run():
    # 连接到 gRPC 服务器
    channel = grpc.insecure_channel('localhost:50051')
    stub = user_pb2_grpc.UserServiceStub(channel)
    
    # 调用 RPC 方法
    request = user_pb2.GetUserRequest(user_id=1)
    response = stub.GetUser(request)
    
    print(f"User ID: {response.user_id}")
    print(f"Username: {response.username}")
    print(f"Email: {response.email}")

if __name__ == '__main__':
    run()

四种 RPC 调用模式

1. 一元 RPC(Unary RPC)

最简单的调用模式,客户端发送一个请求,服务器返回一个响应。

// .proto 定义
rpc GetUser(GetUserRequest) returns (GetUserResponse);

// 客户端调用
response = stub.GetUser(request)

2. 服务器流式 RPC(Server Streaming RPC)

客户端发送一个请求,服务器返回一系列响应。

// .proto 定义
rpc ListUsers(ListUsersRequest) returns (stream UserResponse);

// 服务端实现
def ListUsers(self, request, context):
    for user in get_all_users():
        yield user_pb2.UserResponse(**user)

// 客户端调用
for response in stub.ListUsers(request):
    print(response)

3. 客户端流式 RPC(Client Streaming RPC)

客户端发送一系列请求,服务器返回一个响应。

// .proto 定义
rpc CreateUser(stream UserRequest) returns (UserResponse);

// 客户端调用
def generate_requests():
    for user_data in users:
        yield user_pb2.UserRequest(**user_data)

response = stub.CreateUser(generate_requests())

4. 双向流式 RPC(Bidirectional Streaming RPC)

客户端和服务器都使用流式通信,双方可以独立读写。

// .proto 定义
rpc Chat(stream ChatMessage) returns (stream ChatMessage);

// 客户端实现
def generate_messages():
    for msg in messages:
        yield chat_pb2.ChatMessage(text=msg)
        response = stub.Chat(generate_messages())
        for resp in response:
            print(resp.text)

高级特性

认证与安全

# 使用 SSL/TLS 加密
credentials = grpc.ssl_channel_credentials()
channel = grpc.secure_channel('localhost:50051', credentials)

# 添加认证元数据
metadata = [('authorization', 'Bearer token123')]
response = stub.GetUser(request, metadata=metadata)

错误处理

from grpc import StatusCode

try:
    response = stub.GetUser(request)
except grpc.RpcError as e:
    if e.code() == StatusCode.NOT_FOUND:
        print("User not found")
    elif e.code() == StatusCode.UNAVAILABLE:
        print("Server unavailable")
    else:
        print(f"Error: {e.details()}")

超时与重试

# 设置超时
response = stub.GetUser(request, timeout=5.0)

# 使用重试配置
channel = grpc.insecure_channel(
    'localhost:50051',
    options=[
        ('grpc.enable_retries', 1),
        ('grpc.max_receive_message_length', 4 * 1024 * 1024)
    ]
)

实际应用场景

微服务通信

gRPC 是微服务架构中服务间通信的理想选择,具有高性能、强类型、多语言支持等优势。

实时数据流

使用双向流式 RPC 实现实时聊天、实时数据推送、实时协作编辑等场景。

移动端与后端通信

gRPC 的二进制序列化减少了数据传输量,适合移动网络环境。

IoT 设备通信

gRPC 的低开销和高效性能适合资源受限的 IoT 设备。

注意事项:

常用工具

总结

gRPC 是一个强大的 RPC 框架,特别适合微服务架构和高性能通信场景。通过 Protocol Buffers 定义强类型接口,支持多种调用模式,并提供丰富的生态系统支持。掌握 gRPC 将帮助你构建更高效、更可靠的分布式系统。

下一步学习: