客户端间通信模式
6 min
经典通信模式
客户端之间的消息通信,通常围绕三种经典模式构建:Request-Reply、Pub-Sub 与 Push-Pull。
| 模式 | 核心思想 | 通信方式 | 典型关系 |
|---|---|---|---|
| Request-Reply | 我问,你答 | 同步 | 1 ↔ 1 |
| Pub-Sub | 事件广播 | 异步 | 1 → N |
| Push-Pull | 任务分发 | 异步 | 1 → 1(负载均衡到多个 worker) |
Request-Reply 模式
Request-Reply 模式 是一种典型的一对一同步通信模式,其中
- 客户端负责发送请求(request),服务端负责返回响应(reply)。
- 通信双方通常存在明确的调用关系,客户端会主动等待服务端返回结果。
- 一个请求通常只对应一个响应。
- Request-Reply 强调“请求 → 处理 → 返回结果”的完整交互流程。
- 通信过程通常是同步的,即客户端在收到响应之前会被阻塞等待。
- 该模式广泛应用于 HTTP、RPC1、数据库查询等需要即时返回结果的场景。
发布者-订阅者模式
发布者-订阅者模式2 是一对多广播模式,其中
- 发布者负责发布消息或事件,订阅者负责接收并处理自己感兴趣的消息。
- 发布者与订阅者之间高度解耦,双方无需感知彼此的具体存在。
- 同一个消息会被多个订阅者接收。
- 发布者不关心消息是否被处理,因此天然异步。
- 订阅者可以通过主题(topic)筛选,只接收特定类型的消息。
- 订阅者可以动态连接或断开,而不会影响发布者运行。
Push-Pull 模式
Push-Pull 模式 是一种典型的任务分发模式,其中
- 生产者(Push)负责发送任务,消费者(Pull)负责获取并处理任务。
- 同一个任务只会被其中一个消费者处理,而不会广播给所有消费者。
- Push-Pull 强调任务的负载均衡与并行处理。
- 生产者通常不关心具体由哪个消费者执行任务,因此双方可以高度解耦。
- 消费者可以动态加入或退出,从而实现系统弹性扩展。
- 该模式天然适合 worker pool、任务队列、分布式计算等场景。
其它通信模式
Router-Dealer 模式
在 RPC 场景中,Request-Reply 可以很好地实现传统同步调用:客户端发送一个请求后,需要等待服务端返回结果,才能继续发送下一个请求。
但在异步 RPC 场景下,情况会发生变化。假设同一个客户端同时产生了多个彼此独立的请求,这些请求之间不存在依赖关系,因此理论上可以被多个 worker 并行处理。然而 Request-Reply 的一问一答同步模型,会强制客户端按照 send, recv, send, recv, … 的顺序串行执行,从而限制系统并发能力。
因此,我们希望客户端能够连续发送多个请求,而无需等待前一个请求完成;同时系统能够将这些请求自动分发给不同接收端并行处理,以提升整体吞吐与资源利用率。
Router-Dealer 模式 是一种面向异步并发场景的高级消息通信模式,可以理解为对 Request-Reply 的去同步化与多路复用扩展。其中:
- 多对多拓扑:多个客户端与多个服务器通信
- Dealer 负责异步发送与接收消息,可以连续发送多个请求,而无需等待前一个请求返回。
- Router 负责维护所有连接端的 identity,并根据 identity 对消息进行路由与转发。
- Router-Dealer 不再强制一问一答的严格同步顺序,因此多个请求可以同时在系统中并发执行。
- 同一个客户端发送的多个任务,可以被不同 worker 同时处理,从而提升吞吐与资源利用率。
- Router 会为每个连接自动维护唯一 identity,因此能够区分不同客户端、不同 worker 的消息来源与目标。
- 消息在传输时通常会携带 identity frame,因此 Router 能够知道“这个消息来自谁、应该转发给谁”。
- 与 Request-Reply 不同,Router-Dealer 更像是一个异步消息路由系统,而不是严格的函数调用模型。
- 该模式天然适合高并发 RPC、任务调度系统、分布式推理框架、异步 worker pool 等场景。
例如:客户端 A 连续发送:task [1-3]
在 Request-Reply 中:
task1 -> 等返回 -> task2 -> 等返回 -> task3 -> 等返回而在 Router-Dealer 中三个任务可以同时执行:
task1 -> worker1 -> 等返回
task2 -> worker2 -> 等返回
task3 -> worker3 -> 等返回