第二章:访问远程服务_《凤凰架构:构建可靠的大型分布式系统》

第二章 访问远程服务

2.1 远程服务调用(RPC)
2.1.1 进程间通信机制
  • 核心方式
    • 管道(Pipe):单向通信,用于父子进程
    • 信号(Signal):异步事件通知,不传递数据
    • 套接字(Socket):跨网络通信基础,支持TCP/UDP
    • 共享内存:高效但需同步机制,适用于高频数据交换
    • 消息队列:异步通信,解耦生产消费方
2.1.2 通信成本关键要素
  • 网络延迟:物理距离、路由跳数、协议栈处理时间
  • 序列化开销:JSON/XML文本协议 vs ProtoBuf/Thrift二进制协议
  • 资源消耗:连接池管理、线程模型(阻塞IO vs NIO)
  • 典型延迟对比
    • 本地方法调用:纳秒级
    • 同机房RPC:0.1~1ms
    • 跨地域RPC:10~100ms
2.1.3 三大核心问题
  1. 数据表示(序列化)

    • 类型安全:强类型语言需要严格类型映射
    • 版本兼容:字段增删时的前向/后向兼容策略
    • 性能指标:序列化速度、数据压缩率、内存占用
    • 典型协议:Protobuf(Google)、Thrift(Facebook)、Avro(Hadoop)
  2. 传输协议

    • TCP长连接:复用连接降低握手开销
    • HTTP/1.1:文本协议,支持持久连接
    • HTTP/2:多路复用,头部压缩
    • QUIC:基于UDP的可靠传输,0-RTT握手
  3. 服务定位

    • 接口描述语言(IDL):定义服务契约
      • .proto(gRPC)
      • .thrift(Apache Thrift)
    • 服务发现机制:
      • 客户端直连(硬编码IP)
      • 注册中心(Zookeeper、Consul、Nacos)
      • DNS服务发现
2.1.4 RPC统一化尝试
  • CORBA(公共对象请求代理架构)

    • ORB核心组件实现跨语言调用
    • IDL编译器生成存根代码
    • 失败原因:复杂规范、厂商实现差异、性能问题
  • Web Service体系

    • SOAP协议:XML格式信封
    • WSDL服务描述
    • UDDI服务注册
    • 问题:XML解析开销大,协议臃肿
2.1.5 RPC框架分化
  • 主流实现对比

    框架 协议 序列化 传输 特点
    gRPC HTTP/2 Protobuf TCP 多语言支持,流式通信
    Thrift 自定义二进制 Thrift TCP 跨语言,代码生成
    Dubbo 自定义 Hessian Netty 阿里生态,服务治理
    Spring Cloud HTTP REST JSON HTTP 声明式接口,生态整合
  • 性能关键点

    • 二进制协议相比文本协议节省30%-50%带宽
    • 连接复用减少TCP握手开销
    • 零拷贝技术降低内存复制次数
2.2 REST设计风格
2.2.1 REST本质理解
  • 架构约束

    1. 客户端-服务器分离:前后端独立演进
    2. 无状态:请求包含完整上下文
    3. 可缓存:明确缓存声明(Cache-Control)
    4. 统一接口
      • 资源标识(URI)
      • 表述操作(HTTP方法)
      • 自描述消息(Content-Type)
      • 超媒体驱动(HATEOAS)
    5. 分层系统:代理、网关透明接入
    6. 按需代码:JavaScript扩展客户端
  • 常见误区

    • ≠ HTTP API:REST是架构风格,HTTP是实现载体
    • ≠ CRUD映射:复杂操作可通过资源状态变更表达
2.2.2 RESTful设计实践
  • 资源设计原则

    • 名词化URI:/users/{id}/orders
    • 避免动词:用PUT /orders/{id}/cancel代替POST /cancelOrder
    • 版本控制:URI路径(/v1/users) vs 请求头(Accept-Version)
  • HTTP方法语义

    方法 幂等性 安全 典型应用
    GET 获取资源
    POST 创建资源或触发操作
    PUT 全量更新
    PATCH 部分更新
    DELETE 删除资源
  • 超媒体控制(HATEOAS)

    json 复制代码
    {
      "id": 123,
      "status": "pending",
      "_links": {
        "self": { "href": "/orders/123" },
        "cancel": { "href": "/orders/123", "method": "DELETE" }
      }
    }
2.2.3 Richardson成熟度模型
  • Level 0:使用HTTP作为传输隧道(SOAP over HTTP)
  • Level 1:资源分离(不同端点对应不同操作)
  • Level 2:HTTP动词+状态码规范使用
  • Level 3:超媒体驱动,实现HATEOAS
2.2.4 REST局限性
  • 复杂操作表达
    • 批处理需设计特殊资源(/batch-operations)
    • 事务性操作难以用单一资源表达
  • 性能瓶颈
    • 多次请求问题(n+1查询)
    • 无二进制协议支持(可通过Protocol Buffers over HTTP缓解)
  • 版本管理挑战
    • URI版本导致客户端硬升级
    • 媒体类型协商(Content Negotiation)复杂度高
关键对比:RPC vs REST
维度 RPC REST
通信范式 动作导向(调用方法) 资源导向(操作资源状态)
协议绑定 强绑定(特定协议) 弱绑定(HTTP通用协议)
服务发现 需要IDL和代码生成 通过超媒体动态发现
性能 高(二进制协议) 中(文本协议)
适用场景 内部服务间高效通信 公开API、跨组织集成
变更影响 接口变更需重新生成代码 可通过超媒体减少客户端修改
现代架构融合趋势
  • gRPC-Web:浏览器端支持gRPC协议
  • GraphQL over HTTP:声明式查询与REST端点结合
  • RSocket:双向流式通信,支持RPC模式
  • Service Mesh:在基础设施层统一处理RPC通信(如Istio的Envoy代理)

多选题


题目1:关于远程服务调用(RPC)的三个基本问题,以下哪些描述正确?

A. 如何表示数据(序列化协议)

B. 如何传递数据(传输协议)

C. 如何确定调用哪个方法(服务发现与路由)

D. 如何保证调用的高性能(负载均衡)


题目2:REST设计风格的核心约束条件包括哪些?

A. 客户端-服务器架构

B. 无状态通信

C. 统一接口

D. 必须使用JSON格式


题目3:RMM(Richardson成熟度模型)的四个层级包括哪些?

A. Level 0:基于HTTP的简单RPC

B. Level 1:资源化接口

C. Level 2:使用HTTP动词和状态码

D. Level 3:超媒体驱动(HATEOAS)


题目4:以下哪些是RPC与REST的典型区别?

A. RPC基于方法调用,REST基于资源操作

B. RPC通常使用二进制协议,REST使用文本协议(如HTTP)

C. RPC强调透明性,REST强调显式通信约束

D. RPC天然支持缓存,REST不支持缓存


题目5:关于"透明通信"的挑战,以下哪些描述正确?

A. 网络延迟和分区容错会影响透明性

B. 本地调用和远程调用的错误处理逻辑可以完全一致

C. 序列化/反序列化可能引入性能瓶颈

D. 服务发现与负载均衡是实现透明通信的必要条件


题目6:RESTful系统的"统一接口"原则包含哪些具体约束?

A. 资源的唯一标识(URI)

B. 通过标准HTTP方法操作资源

C. 自描述消息(如Content-Type)

D. 必须使用HATEOAS实现超媒体驱动


题目7:以下哪些是RPC分裂的原因?

A. 不同厂商对性能和协议的优化需求不同

B. 语言和框架的生态系统差异

C. REST设计风格的普及取代了RPC

D. 分布式事务的复杂性


题目8:关于HTTP/2对REST的影响,以下哪些描述正确?

A. 多路复用技术降低了HTTP/1.1的队头阻塞问题

B. 头部压缩减少了网络传输开销

C. HTTP/2的二进制协议更适合REST的文本交互

D. HTTP/2的流式通信与REST的无状态原则冲突


题目9:REST的不足与争议包括哪些?

A. 缺乏强类型接口定义,导致开发效率低

B. 超媒体驱动(HATEOAS)在实际应用中难以实现

C. 无状态约束无法满足复杂业务场景的会话管理需求

D. 对性能敏感的场景(如高频交易)不适用


题目10:以下哪些是设计分布式系统时需权衡的通信成本?

A. 网络延迟与带宽限制

B. 序列化/反序列化的计算开销

C. 服务发现与路由的复杂度

D. 代码的可维护性和团队协作成本


答案与解析


题目1答案:ABC
解析

  • RPC的三个基本问题是:数据表示(序列化)、数据传输(协议)、方法确定(服务定位)。
  • D选项"高性能"是优化目标,但并非基本问题。

题目2答案:ABC
解析

  • REST的六大核心约束包括:客户端-服务器、无状态、统一接口、分层系统、缓存、按需代码(Code-On-Demand)。
  • D选项"必须使用JSON"错误,REST支持多种数据格式(如XML、JSON等)。

题目3答案:ABCD
解析

  • RMM的四个层级为:
    Level 0(简单RPC)、Level 1(资源化)、Level 2(HTTP动词+状态码)、Level 3(HATEOAS)。

题目4答案:ABC
解析

  • D错误,REST通过HTTP缓存机制(如Cache-Control)支持缓存,而RPC通常不原生支持缓存。

题目5答案:ACD
解析

  • B错误,远程调用需处理网络超时、重试等特有错误,与本地调用不同。

题目6答案:ABC
解析

  • D是Level 3的约束,属于RMM的扩展,非"统一接口"原则本身。

题目7答案:AB
解析

  • C错误,REST并未取代RPC;D是分布式系统的通用问题,非RPC分裂的直接原因。

题目8答案:AB
解析

  • C错误,HTTP/2的二进制协议与REST的文本交互无直接关联;D错误,HTTP/2的流式通信与无状态原则不冲突。

题目9答案:ABCD
解析

  • 所有选项均为REST的典型争议点。

题目10答案:ABCD
解析

  • 所有选项均属于通信成本范畴(网络、计算、系统复杂度、开发成本)。
相关推荐
SofterICer3 分钟前
Eclipse Leshan 常见问题解答 (FAQ) 笔记
java·笔记·eclipse
密码小丑32 分钟前
玄机-应急响应-webshell查杀
网络·笔记
郭涤生1 小时前
微服务系统记录
笔记·分布式·微服务·架构
苏卫苏卫苏卫1 小时前
【Python】数据结构练习
开发语言·数据结构·笔记·python·numpy·pandas
_x_w3 小时前
【8】数据结构的栈与队列练习篇章
开发语言·数据结构·笔记·python·链表
zkyqss3 小时前
OpenStack Yoga版安装笔记(十七)安全组笔记
linux·笔记·openstack
郭涤生3 小时前
The whole book test_《C++20Get the details》_notes
开发语言·c++·笔记·c++20
Aska_Lv4 小时前
生产问题讨论---4C8G的机器,各项系统指标,什么范围算是正常
后端·面试·架构
萧鼎4 小时前
下一代AI App架构:前端生成,后端消失
前端·人工智能·架构
Kale又菜又爱玩5 小时前
深入探索Redisson:用法全解析及在微服务中的关键应用
redis·微服务·架构