远程服务调用让微服务间像调用本地方法一样通信。核心问题:用什么协议传输(REST/RPC)、用什么格式序列化(JSON/Protobuf)、如何保证可靠性(超时/重试/幂等)。
| 维度 | REST | RPC |
|---|
| 抽象目标 | 面向资源(名词) | 面向方法(动词) |
| 表达方式 | URL 是资源,HTTP 动词是操作 | 直接调用远程方法 |
| 协议 | HTTP | TCP/HTTP/二进制 |
| 适用场景 | 外部 API、跨平台 | 系统内部高性能通信 |
REST:GET /users/123(获取 123 号用户) RPC:userService.getUserById(123)(调用远程方法)
gRPC 是 Google 开源的高性能 RPC 框架,三大核心优势:
| 优势 | 说明 |
|---|
| Protobuf | 二进制格式,体积比 JSON 小 3-10 倍 |
| HTTP/2 | 多路复用、头部压缩、双向流 |
| 多语言代码生成 | .proto 定义接口,自动生成各语言代码 |
| 模式 | 说明 | 适用场景 |
|---|
| Unary | 一请求一响应 | 普通 API |
| Server Streaming | 一请求流响应 | 实时推送 |
| Client Streaming | 流请求一响应 | 文件上传 |
| Bidirectional Streaming | 双向流 | 即时通讯 |
| 维度 | OpenFeign | Dubbo |
|---|
| 协议 | HTTP 短连接 | TCP 长连接 + 自定义协议 |
| 序列化 | JSON | Hessian/Kryo 二进制 |
| 性能 | 较低 | 高 |
| 服务治理 | 依赖 Spring Cloud 组件 | 内置 |
| 适用场景 | 中小型微服务 | 大型分布式系统 |
分布式场景下超时重试可能触发重复请求,必须保证幂等。
| 方法 | 幂等 | 说明 |
|---|
| GET | 是 | 只读,无副作用 |
| DELETE | 是 | 删除相同资源结果一致 |
| PUT | 是 | 更新/创建,重复结果一致 |
| POST | 否 | 重复提交可能创建多个资源 |
| 方案 | 说明 | 适用场景 |
|---|
| 数据库唯一约束 | 业务字段加唯一索引 | 防重复下单 |
| Redis SetNX | 原子性「设置并检查」 | 接口幂等 Token |
| 乐观锁 | UPDATE ... WHERE version = ? | 库存扣减 |
| 状态机 | 只允许特定状态转换 | 订单状态变更 |
@PostMapping("/orders")
public Order createOrder(@RequestHeader("X-Idempotency-Token") String token,
@RequestBody CreateOrderDTO dto) {
Boolean success = redis.delete("idem:" + token);
if (!success) throw new DuplicateRequestException();
return orderService.create(dto);
}
| 格式 | 大小 | 速度 | 可读性 |
|---|
| JSON | 大 | 中 | 是 |
| Protobuf | 最小 | 最快 | 否(代码生成) |
| Hessian | 小 | 快 | 否 |
选型建议
外部 API → JSON(可读性优先),内部微服务 → Protobuf(性能优先)。
通过在客户端 → CDN → 反向代理 → 应用 → 数据库各层设置缓存,让请求尽早返回。越靠近用户,缓存命中收益越大。
用户请求 → 浏览器缓存 → CDN 边缘节点 → Nginx → 应用层 → Redis → 数据库
| 内容类型 | 策略 |
|---|
| 静态资源(有 hash 名) | max-age=31536000 强缓存 |
| HTML 页面 | no-cache 每次协商 |
| API 接口 | no-store 不缓存 |
| 层级 | 代表技术 | 工作原理 |
|---|
| L4(四层) | LVS、F5 | 基于 IP + 端口转发 |
| L7(七层) | Nginx、Gateway | 解析 HTTP 内容智能路由 |
| 问题 | 解决方案 |
|---|
| 调用超时 | 检查网络连通性;调整连接超时和读超时配置;确认目标服务正常响应 |
| 序列化异常 | 确认客户端和服务端使用相同序列化协议;检查实体类是否实现 Serializable |
| 服务调用失败 | 检查服务是否注册到注册中心;确认版本和分组匹配;检查负载均衡策略 |