乐趣区

关于java:RocketMQ-50-多语言客户端的设计与实现

本文作者:古崟佑,阿里云中间件开发。

RocketMQ 5.0 版本领有十分多新个性,比方存储计算拆散、batch 能力的晋升等,它是具备里程碑意义的版本。

提到新版本,咱们往往会首先想到服务端架构的设计变动,很容易疏忽客户端的设计理念。客户端也是音讯产品的必要组成部分,许多个性须要 client 与 server 两端相互合作,能力更好地实现。

轻量化、云原生以及对立模型是 RocketMQ 5.0 客户端的三个设计理念。

01 轻量化

轻量化的重点在于轻逻辑、轻流程,化繁为简,缩小多语言生态倒退的妨碍。

上图列举了 RocketMQ 4.x 版本和 RocketMQ 5.0 版本的差别。

①4.x 版本的序列化应用 JsonCodecs 和 RocketMQCodecs,5.0 版本应用的则是规范的 Protobuf 协定。多语言倒退的妨碍包含许多不标准,比方 RocketMQ 自定义序列化对于其余的语言须要本人实现一套协定以实现正反序列化解析。而 Json 作为规范序列化协定,根本能够实现所有语言的正反序列化,但毛病也非常明显,冗余信息过多,体积占用太大,因而更多用于 restful 架构等前后端交互的场景。此外,消息中间件场景无需关怀传输数据时是否可读。因而,Protobuf 成为了抉择,它原生反对多语言,且传输时体积占用十分小,成熟且规范。

②此前客户端应用 consumer 生产信息时,会存在计算逻辑比方重均衡 以及零碎级 topic 解决。然而 RocketMQ 5.0 版本将所有计算逻辑上移到了服务端,客户端只需简略地调用 Receive 接口,也无需额定解决零碎级 topic,整体逻辑变得十分轻量。

③4.x 版本的实现和保护老本十分高,因而 5.0 版本并没有基于 4.x 进行迭代和更新。设计之初有一种思路为间接在 4.x 客户端上减少 gRPC 协定,迭代降级成为 5.0,但这相当于扛着历史包袱往前走,也违反了轻量化准则,因而被否定。

02 云原生

云的弹性、高可用性以及交互运维能力在 RocketMQ 5.0 客户端中均有体现,别离对应极致弹性伸缩、低耦合以及云端一体。

上图为 4.x 版本和 5.0 版本的客户端。在 4.x 版本中,一个 Queue 最多对应一个 consumer,减少 consumer 不肯定能晋升生产并发,其弹性有下限。但在 RocketMQ 5.0,每一个 consumer 能够向所有 broker 发动 Pop 申请。此前为 push 模式,当初改为 pop 申请。晋升 consumer 数量可能晋升生产并发,即便只有一个队列,也能够生成数百数千个消费者对立拉取队列音讯。

比方购物网站突发退货流量顶峰,此前最简略无效的形式为减少业务利用数量、减少解决并发,比方减少退货零碎和客户系统核心的利用数据。但如果一开始队列数设置并没有这么多,则须要先扩容队列,再扩容外围业务数。同时,扩容后也仅对新入队的音讯处理速度有晋升,曾经造成沉积的队列生产速度仍然迟缓。此时会呈现一种状况,先提交的退货申请后被解决,会对用户体验造成影响。

而 RocketMQ 5.0 的 pop 生产模型只需间接减少业务解决节点数即可解决问题。

已沉积队列无奈通过扩容的形式减速生产,与低耦合场景类似。比方在 4.x 版本中,如果某生产节点产生 FullGC,生产比较慢,然而没有齐全下线,仍然与服务端放弃着心跳。因而队列仍然会被调配至该节点,调配队列逐步沉积可能会引发一系列问题。

但在 RocketMQ 5.0,如果某节点产生 FullGC,调配粒度会从队列进化为音讯,调配的音讯生产迟缓,不会产生沉积。

因而,从极致弹性和低耦合上能够看出 RocketMQ 5.0 之后应用 Pop 协定的优越性,只须要简略地在生产能力有余时扩容、充裕时缩容,繁多节点故障也不会影响到全局。

云能够了解为远在机房的服务端,端则嵌在业务 SDK。此前,在管制台上进行运维操作时,只能管制服务端,对客户端的掌控十分无限,应用体验十分割裂。比方更改服务端配置,除了白屏也能够通过命令工具轻松批改配置,且及时失效。但如果客户端批改配置,则会波及到业务公布,很容易呈现问题。

RocketMQ 5.0 采纳 telemetry 遥测协定与服务端进行协同。遥测协定的作用为使云和端之间通过 telemetry 进行交互,包含但不限于限流策略、重试策略、公布和订阅关系管控、可观测开关、接入点信息、堆栈信息等。次要实现形式为间接由 SDK 向服务端发动 telemetry 申请,而后往 observer 读写上图所示的指令即可。

指令类型包含设置、打印堆栈、验证音讯、生产以及事务音讯回查,其中比拟要害的能力为可观测开关以及 OTLP 接入点信息。

以往的可观测是基于音讯轨迹实现,在发送音讯和生产音讯时,将上下文中的参数增加进轨迹音讯,在后盾攒批异步发送。上图为发送音讯的所有 context,包含 MessageQueue、MessageID、IP 等信息。

上图为生产时的 context。对于单个 MessageID,端对端会产生三条轨迹音讯,别离为发送后、生产前和生产后。如果想要跟踪音讯轮转轨迹,能够通过查问轨迹的音讯数据找到它,因其将 MessageID 作为 key 值插入到 topic。而此前须要在控制台依据 MessageID 查问轨迹音讯。

RocketMQ 此前曾经具备可观测能力,但自定义可观测形式无奈很好地对接现有的可观测产品和能力。而 5.0 版本领有了标准化的可观测协定,能够应用更丰盛、更业余的剖析和展现工具,让可观测数据有了更高的价值。

Telemetry 遥测协定是将可观测开关以及接入点下发到客户端,Proxy 会默认将接入点信息设置为本人,能够将客户端上报的所有可观测音讯在服务端做收敛,再对立应用规范的 OpenTelemetry 和 Opencensu 两个协定上报到 SLS,SLS 再通过 TLog 的形式与 Prometheus、Grafana 进行对接。

Tracing 的数据链路比较复杂,也须要先通过 proxy 将可观测数据导到 proxy 上。而 Tracing 的数据量较大,此前也曾思考过间接通过用户自定义配置导出接入点,不通过 proxy,但这会引发其余问题,比方 4.x 用户心愿接入 RocketMQ 5.0 服务端应用可观测能力,则须要通过轨迹音讯解码进行解析再通过标准化可观测协定输入。

多语言方面,最新出的 OpenTelemetry 反对不肯定足够全面,因而也会须要一些旧的可观测协定比方 Opencensu,但整体来说,它们都是规范的协定。

03 对立模型

此前的 RocketMQ API 不足精心设计的音讯模型,很多概念没有明确的定义。比方发送音讯时有两个 ID,别离是用户本人定义的 MessageID 和服务端下发的 offsetID。然而在生产时,下发的 offsetID 又变成了 MessageID,不置可否的定义使得预测客户行为变得更加艰难。并且,此前大多以执行为导向,对开发者并不敌对,许多性能是基于实现而不是接口。因而用户须要涉及到很多细节,须要面对过多冗余和简单界面,出错概率极大。

另外,倒退多语言生态时,也须要对立模型疏导多语言的倒退实现。

主题类型是其中一个显著的扭转。

此前,客户端不做 topic 类型校验,任何一种类型音讯都能够发往 topic。然而在 RocketMQ 5.0 之后会对 topic 类型做校验,真正从 topic 主题类型上做了辨别,比方程序音讯 topic 只能发程序音讯。此前的 delay 音讯为分级别延时音讯,而当初为反对毫秒级精度的定时音讯,能够反对任意工夫精度。

同时,模型定义了各种各样的消费者,有不同的消费者实现,比方 PushConsumer、PullConsumer 以及 SimpleConsumer,底层均应用 pop 协定实现。比方以前的 PushConsumer 是基于手动拉的形式,而当初采纳了 pop 形式。

SimpleConsumer 的应用办法非常简单,间接调用 receive message 接口,获取到音讯之后进行生产,生产胜利则进行 Ack;如果生产失败,则更改可见工夫。整体流程十分直观,齐全基于接口定义。

新版本的启动流程减少了筹备工作,为了可能更早地捕捉到显著的谬误以及异样,比方尝试从服务端获取设置,能够对此类设置进行热更新,称为服务器和客户遥测,任何筹备失败都会导致客户端启动失败,而以往能够强行将客户端拉起,而后一直进行重试。

减少了筹备工作后,配置问题或自身网络问题能够提前被发现,比方 topic 路由信息不存在,启动时会先对 bonding topic 做查看,每一个发送者、生产者能够提前设置预留 topic 信息,再依据错误信息进行查看,判断是否能够启动。

退出移动版