RocketMQ5.0新组件Proxy

前言

RocketMQ 4.x 版本之前,一套完整的 MQ 服务包含的组件有:Namesrv、Broker、Consumer、Producer。 RocketMQ 5.0 版本之后,官方引入了一个新的组件:Proxy,它的作用是什么呢?

架构对比

RocketMQ 4.x 版本之前架构是这样的:

  • Namesrv:命名服务,充当注册中心和路由管理
  • Broker:消息存储中心
  • Consumer:消费者
  • Producer:生产者

先启动 Namesrv 再启动 Broker,Broker 会把元数据注册到 Namesrv,包括一共有哪些 Topic、Topic 下有多少队列等等。Consumer 发消息前要先从 Namesrv 拉取 Topic 的路由信息,然后轮询发送到队列,Broker 收到消息后写入磁盘持久化存储。Producer 也要从 Namesrv 拉取路由信息,再和 Broker 建立长连接拉取消息消费,消费成功后上报消费位点。 这个架构看起来没什么问题,RocketMQ 也用了这么久了,怎么到 5.0 突然要引入个 Proxy 组件呢? 顺应趋势,云原生的时代已经来了,RocketMQ 5.0 要全面拥抱云原生,现在这套架构的问题开始显现:

  • 客户端 SDK 太重,多语言重复开发,工作量大
  • Remoting 私有协议的通用性问题
  • Broker 存算一体,不利于资源调度
  • 现有 PUSH 消费模式的局限性

引入 Proxy 后,我们再来看看 RocketMQ 5.0 的架构图: 表面上看,Proxy 只是做了一个转发,在 Namesrv、Broker 和 Consumer、Producer 之间做了一层代理,但是你别小看这层代理,它带来的好处可是不少,把上面的问题全解决了。

多语言客户端SDK & 私有协议的问题 如今的 RocketMQ 早已经不是只给 Java 语言使用了,为了让 C++、Go 等其它语言也可以很方便的使用 RocketMQ,官方必须开发对应语言的客户端 SDK,这意味着要用不同的语言重复实现客户端逻辑,程序员最讨厌重复了,所以客户端要尽可能做到足够轻量,这样重复编写的代码才最少。 如果你看过 RocketMQ 4.x 的源码,你会发现客户端的逻辑太重了,比如:客户端要同时和 Namesrv 和 Broker 交互、消息队列的重平衡、消费位点的上传等等。于是,RocketMQ 5.0 把客户端的很多功能都下沉到了 Proxy,同时 5.x 的客户端统一用 gRPC 协议和 Proxy 通信,Proxy 再把协议适配成 Remoting 转发到 Broker、Namesrv。 使用 gRPC 协议的好处是:

  • RocketMQ 不用为多语言重复开发 Remoting 协议,gRPC 拿来即用
  • 云原生时代,gRPC 逐渐成为事实上的标准协议,具有更好的通用性

Broker 存算分离 Proxy 不仅承担了客户端的部分功能,还承担了原先 Broker 的部分计算任务,新架构让 Broker 更专注于消息数据的存储,实现了存储计算分离。在云原省时代,更利于资源的调度,Proxy 扩容起来更加方便。

新的 POP 消费模式 RocketMQ 4.x 的 PUSH 消费模式存在一定的局限性,本质上还是 PULL 模式,消息是靠消费者主动去拉取的,PUSH 消费模式的局限性主要体现在:

  • 队列和消费者的强绑定,消费者数量大于队列数时,增加消费者无法提高消费能力
  • 消息积压的风险变高
  • 消费者或队列数量变更,触发重平衡操作,期间无法消费消息,性能出现抖动

新的 POP 消费模式就没有这些问题,消费者可以消费所有队列里的消息,增加消费者就可以提高消费能力,不受队列数和消费者数量的限制,消费者无状态,扩容起来很方便。

部署Proxy

Proxy 有两种部署方式:

  • Local 模式下,Broker 和 Proxy 是同进程部署,只是在原有 Broker 的配置基础上新增 Proxy 的简易配置就可以运行
  • Cluster 模式下,Broker 和 Proxy 分别部署,即在原有的集群基础上,额外再部署 Proxy 即可

Local 模式部署 由于 Local 模式下 Proxy 和 Broker 是同进程部署,Proxy 本身无状态,因此主要的集群配置仍然以 Broker 为基础进行即可。 不论何种部署方式,都要先启动 Names,再启动 Broker:

shell 复制代码
$ sh mqnamesrv

# 假设Namesrv地址是:192.168.1.1:9876
$ sh bin/mqbroker -n 192.168.1.1:9876 --enable-proxy

Local 模式下,因为 Proxy 和 Broker 同属一个进程,所以 Proxy 和 Broker 无需再网络通信,适合对延迟敏感、期望部署架构简单的用户。

Cluster 模式部署 在 Cluster 模式下,Broker 与 Proxy 分开部署,存储计算完全分离,Proxy 可以很好的扩容。Proxy 集群和 Broker 集群必须一一对应,可以在配置文件中指定 ClusterName。

nginx 复制代码
{
  "rocketMQClusterName": "DefaultCluster"
}
shell 复制代码
$ sh mqnamesrv

# 假设Namesrv地址是:192.168.1.1:9876
$ sh bin/mqbroker -n 192.168.1.1:9876
$ sh bin/mqproxy -n 192.168.1.1:9876
相关推荐
轻语呢喃8 分钟前
JavaScript :字符串模板——优雅编程的基石
前端·javascript·后端
MikeWe14 分钟前
Paddle张量操作全解析:从基础创建到高级应用
后端
岫珩22 分钟前
Ubuntu系统关闭防火墙的正确方式
后端
心之语歌27 分钟前
Java高效压缩技巧:ZipOutputStream详解
java·后端
不死的精灵1 小时前
【Java21】在spring boot中使用ScopedValue
java·spring boot·后端
M1A12 小时前
TCP/IP协议精解:IP协议——互联网世界的邮政编码系统
后端·网络协议·tcp/ip
逸风尊者2 小时前
开发易掌握的知识:GeoHash查找附近空闲车辆
java·后端
程序猿阿越3 小时前
Kafka源码(一)Controller选举与创建Topic
java·后端·源码
程序员爱钓鱼3 小时前
Go语言项目工程化 — 常见开发工具与 CI/CD 支持
开发语言·后端·golang·gin
Jiude3 小时前
MinIO 社区版被故意阉割,Web管理功能全面移除。我来试试国产RustFS
后端·docker·架构