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
相关推荐
Amagi.1 小时前
Spring中Bean的作用域
java·后端·spring
2402_857589361 小时前
Spring Boot新闻推荐系统设计与实现
java·spring boot·后端
J老熊2 小时前
Spring Cloud Netflix Eureka 注册中心讲解和案例示范
java·后端·spring·spring cloud·面试·eureka·系统架构
Benaso2 小时前
Rust 快速入门(一)
开发语言·后端·rust
sco52822 小时前
SpringBoot 集成 Ehcache 实现本地缓存
java·spring boot·后端
原机小子2 小时前
在线教育的未来:SpringBoot技术实现
java·spring boot·后端
吾日三省吾码2 小时前
详解JVM类加载机制
后端
努力的布布2 小时前
SpringMVC源码-AbstractHandlerMethodMapping处理器映射器将@Controller修饰类方法存储到处理器映射器
java·后端·spring
PacosonSWJTU3 小时前
spring揭秘25-springmvc03-其他组件(文件上传+拦截器+处理器适配器+异常统一处理)
java·后端·springmvc
记得开心一点嘛3 小时前
在Java项目中如何使用Scala实现尾递归优化来解决爆栈问题
开发语言·后端·scala