首页 > 其他分享 >RocketMQ 5.0 多语言客户端的设计与实现

RocketMQ 5.0 多语言客户端的设计与实现

时间:2023-01-04 14:33:38浏览次数:45  
标签:5.0 topic 消息 RocketMQ 服务端 客户端

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

 

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 信息,再根据错误信息进行检查,判断是否可以启动。

标签:5.0,topic,消息,RocketMQ,服务端,客户端
From: https://www.cnblogs.com/RocketMQ/p/17024724.html

相关文章

  • RocketMQ 5.0 多语言客户端的设计与实现
    本文作者:古崟佑,阿里云中间件开发。RocketMQ5.0版本拥有非常多新特性,比如存储计算分离、batch能力的提升等,它是具有里程碑意义的版本。提到新版本,我们往往会首先想到服务......
  • RocketMQ Compaction Topic的设计与实现
    本文作者:刘涛,阿里云智能技术专家。01 CompactionTopic介绍一般来说,消息队列提供的数据过期机制有如下几种,比如有基于时间的过期机制——数据保存多长时间后即进行清理,也有......
  • RocketMQ Compaction Topic的设计与实现
    本文作者:刘涛,阿里云智能技术专家。 01 CompactionTopic介绍一般来说,消息队列提供的数据过期机制有如下几种,比如有基于时间的过期机制——数据保存多长时间后即进行......
  • 文字页游开发(客户端)1
    客户端搭建 在服务端搭建成功后,在下载好node、npm相关的内容后就可直接下载安装vue相关的内容这边就直接使用vue-cli脚手架去安装vuenpminstall-g@vue/cli具体......
  • HTTP客户端之Spring WebClient
    对于HTTP客户端,其实有很多种,而SpringBoot也提供了一种方式叫SpringWebClient。它是在Spring5中引入的异步、反应式HTTP客户端,用于取代较旧的RestTemplate,以便在使用Sprin......
  • kubenetes v1.25.0 升级 v 1.25.1
    升级K8s版本v1.25.0->v1.25.1:#升级之前v1.25.0:[root@k8s-master-1~]#kubectlgetnode-owideNAMESTATUSROLESAGEVERSIONI......
  • 仿网易新闻客户端
    ​​https://github.com/xiangzhihong/newsApp​​newsApp是一款仿网易新闻的客户端产品,非官方版本,属于个人业余时间做的一个小项目;界面有一些仿网易新闻客户端主要用到......
  • 客户端与服务器之间双向通讯的5种方式总结(完整代码演示)
    客户端与服务器之间双向通讯的5种方式总结(完整代码演示)  目录1.polling轮循2.long-polling长轮循3.iframe流4.EventSource流5.websocket 首......
  • MAUI Blazor学习2-创建移动客户端Razor页面
     MAUIBlazor学习2-创建移动客户端Razor页面 MAUIBlazor系列目录MAUIBlazor学习1-移动客户端Shell布局-SunnyTrudeau-博客园(cnblogs.com)  为了适配......
  • MAUI Blazor学习1-移动客户端Shell布局
    MAUI正式版发布半年了,Net7也发布了,再次学习MAUI跨平台开发。UI类型选择Blazor,因为Html的生态圈比Xaml好太多了,能用Html解决的,就不要用Xaml。Blazor既可以开发网页客户端,又......