正在加载,请稍候…

微服务通信:REST、gRPC 与消息队列

选择合适的微服务通信模式。比较同步 REST 和 gRPC 与异步消息队列,学习服务发现并处理故障。

微服务通信:REST、gRPC 与消息队列

微服务通信模式

同步 vs 异步

同步(REST/gRPC):
  + 简单的请求/响应
  + 即时反馈
  - 紧耦合(调用方等待)
  用于:面向用户的查询、实时数据需求

异步(消息队列):
  + 松耦合
  + 更好的故障隔离
  - 最终一致性
  用于:命令、通知、数据同步

微服务通信:REST、gRPC 与消息队列 插图

gRPC 模式

syntax = "proto3";
service UserService {
  rpc GetUser(GetUserRequest) returns (UserResponse);
  rpc ListUsers(ListUsersRequest) returns (stream UserResponse);
}

message GetUserRequest { string id = 1; }
message UserResponse {
  string id = 1;
  string email = 2;
  string name = 3;
}

消息队列模式

微服务通信:REST、gRPC 与消息队列 插图

命令模式(一对一)

// 订单服务向库存发送命令
await messageQueue.send('inventory.reserve', {
  orderId: order.id,
  items: order.items,
}, { messageId: generateId() }); // 幂等键

// 库存服务处理命令
consumer.subscribe('inventory.reserve', async (msg) => {
  if (await processedMessages.has(msg.messageId)) return; // 已处理
  await inventoryService.reserve(msg.payload.items);
  await processedMessages.add(msg.messageId);
  await messageQueue.send('inventory.reserved', { orderId: msg.payload.orderId });
});

事件模式(一对多)

// 用户服务发布事件
await eventBus.publish('user.registered', { userId: user.id, email: user.email });

// 多个服务独立订阅
eventBus.subscribe('user.registered', async (e) => emailService.sendWelcome(e.email));
eventBus.subscribe('user.registered', async (e) => analytics.track('signup', e));

微服务通信:REST、gRPC 与消息队列 插图

断路器

class CircuitBreaker {
  private failures = 0;
  private state: 'closed' | 'open' | 'half-open' = 'closed';

  async execute<T>(fn: () => Promise<T>): Promise<T> {
    if (this.state === 'open') throw new Error('Circuit breaker is open');
    try {
      const result = await fn();
      if (this.state === 'half-open') this.reset();
      return result;
    } catch (err) {
      this.failures++;
      if (this.failures >= 5) this.state = 'open';
      throw err;
    }
  }

  private reset() { this.failures = 0; this.state = 'closed'; }
}

Saga 模式(分布式事务)

订单已下单
  -> 支付已扣款
  -> 库存已预留
  -> 物流已安排
  -> 订单已确认

如果物流失败:
  -> 库存释放(补偿事务)
  -> 支付退款(补偿事务)
  -> 订单失败

从单体开始,当你有清晰的领域边界时再提取服务。