跳到主要内容

gRPC 与 RPC

问题

什么是 RPC?gRPC 有什么优势?在什么场景下使用?

答案

RPC vs REST

维度RESTgRPC
协议HTTP/1.1(通常)HTTP/2
数据格式JSON(文本)Protocol Buffers(二进制)
性能一般高(体积小、解析快)
类型安全弱(依赖文档)强(.proto 文件生成代码)
流式传输不支持支持(单向流、双向流)
浏览器支持有限(需要 gRPC-Web)
适用场景对外 API内部服务间通信

Protocol Buffers

user.proto
syntax = "proto3";

package user;

service UserService {
rpc GetUser (GetUserRequest) returns (UserResponse);
rpc ListUsers (ListUsersRequest) returns (stream UserResponse); // 服务端流
rpc CreateUser (CreateUserRequest) returns (UserResponse);
}

message GetUserRequest {
string id = 1;
}

message CreateUserRequest {
string name = 1;
string email = 2;
}

message UserResponse {
string id = 1;
string name = 2;
string email = 3;
int64 created_at = 4;
}

message ListUsersRequest {
int32 page = 1;
int32 page_size = 2;
}

Node.js gRPC 实现

grpc-server.ts
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';

const packageDefinition = protoLoader.loadSync('user.proto');
const proto = grpc.loadPackageDefinition(packageDefinition) as any;

// 实现服务
const server = new grpc.Server();

server.addService(proto.user.UserService.service, {
getUser: async (call: any, callback: any) => {
const user = await db.user.findById(call.request.id);
callback(null, user);
},

listUsers: async (call: any) => {
const users = await db.user.findMany();
for (const user of users) {
call.write(user); // 流式返回
}
call.end();
},

createUser: async (call: any, callback: any) => {
const user = await db.user.create(call.request);
callback(null, user);
},
});

server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
console.log('gRPC server running on port 50051');
});

四种通信模式


常见面试问题

Q1: 什么时候用 gRPC?

答案

  • 微服务内部通信:性能好、类型安全
  • 高性能场景:二进制序列化比 JSON 快 3-10 倍
  • 需要流式传输:实时数据推送

不适合:对外 API(浏览器支持差)、简单 CRUD(REST 更方便)。

Q2: Protocol Buffers 比 JSON 好在哪?

答案

  1. 体积小:二进制编码,比 JSON 小 3-10 倍
  2. 解析快:不需要文本解析
  3. 类型安全:.proto 生成类型代码
  4. 向后兼容:字段编号机制支持 Schema 演进

Q3: 前端能直接调用 gRPC 吗?

答案

浏览器不直接支持 HTTP/2 的 gRPC。需要 gRPC-Web(需要 Envoy 代理转换),或者后端提供 REST/GraphQL 网关。

相关链接