文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

你必须知道的消息的推拉机制

2024-12-02 19:02

关注

我们在之前也说了不少RocketMQ的知识点了,这一篇要说的是RocketMQ的消息的推拉机制,这个应该也是属于面试的热点,学起来吧

我们下面要说的推拉模式指的是broker和consumer之间的,producer和broker之间的模式是推的模式,也就是每次producer每次生产了消息,会主动推给broker

其实这个大家也应该好理解,如果producer和broker之间交互用broker来拉取,就会怪怪的,每次消息都要存储到producer的本地,然后等待broker来拉取,这个要取决于多个producer的可靠性,显然这种设计是很糟糕的

我们下面要讨论的是broker和consumer之间的交互是推还是拉,大家也可以自己先思考下到底是推还是拉

推模式指的是broker将消息推向Consumer,也就是Consumer是被动的去接收这个消息,broker来将消息主动的去推给Consumer

那么这种模式的优缺点呢,大家可以想一下

很明显的一个优点就是延迟小,实时性比较好,broker接收到消息之后就会立刻推送到Consumer,实时性相对来说是比较高的

还有一个优点其实就是简化了Consumer端的逻辑,消费端不需要自己去处理这个拉取的逻辑,只需要监听这个消息的topic,然后去专心的处理这个消息的业务逻辑即可

上面说的两点是优点,那么有优点就肯定也会伴随相应的缺点

第二点简化了Consumer消费端的逻辑的同时,也就复杂化了broker端的逻辑,这其实也不算是优点或者缺点吧,算是这个模式的一个特点,需要根据场景来选择自己合适的模式

最大的一个缺点就是推送的速率和消费的速率不好去匹配,这样就是很糟糕的,你想,如果broker拿到消息就推给Consumer,不在乎Consumer的消费能力如何,就往Consumer直接扔,那Consumer有可能会崩溃

就像一个生产线,本来只能接收的最大速度是10立方米每秒,结果呢,你每秒往生产线上扔100立方米每秒,那这个生产线可能就因为无法处理而直接崩盘

当推送速率很快的时候,甚至都像DDos的攻击一样,消费者就更难受了,不同的消费者的消费速率也是不一样的,broker也很难平衡每个消费者的速率,如果broker需要记住每个Consumer的消费能力和速度的话,那broker的复杂度可就直线上升

还以一个缺点就是消费者推出去之后,无法保证消息发送成功,push采用的是广播模式,也就是只有服务端和客户端都在同一个频道的时候,推模式才可以成功的将消息推到消费者

拉模式,也是同样的道理,就是Consumer是主动从broker拉取消息,哎,这次我Consumer主动了,我不需要你来喂我了,我每过一段时间去你那里拿消息就好了,你也别在乎我的消费速率了

咋回事知道了,想想这样的优缺点,知道了优缺点就对这个模式肯定了解的八九不离十了

最大的优点就是主动权掌握在Consumer这边了,每个消费者的消费能力可能不一样,消费者可以根据自身的情况来拉取消息的请求,如果消费者真的出现那种忙不过来的情况下,可以根据一定的策略去暂停拉取

服务端也相对来说轻松了,不需要去进行消息的处理逻辑了,你来了我就给你就好了,你要多少我就给你就好了,broker就是一个没得感情的存储机器

拉模式也更适合批量消息的发送,推模式是来一个消息就推一个,当然也可以缓存一部分消息再推送,但是无法确定Consumer是否能够处理这批推送的消息,拉模式则是Consumer主动来告诉broker,这样broker也可以更好的决定缓存多少消息用于批量发送

说完了优点,就需要说缺点了,拉模式需要Consumer对于服务端有一定的了解,主要的缺点就是实时性较差,针对于服务器端的实时更新的信息,客户端还是难以获取实时的信息

毕竟消费者是去拉取消息,消费者怎么知道消息到了呢,所以消费者能做的就是不断的去拉取,但是又不能频繁的去拉取,这样也耗费性能,因此就必须降低请求的频率,请求间隔时间也就意味着消息的延迟

RocketMQ最终决定的拉模式,kafka也是如此

RocketMQ的使用的拉模式的使用特点

为什么拉模式稍微更合适些呢,现在的消息队列都有持久化消息的需求,削峰主要就是靠持久化来削的,也就是本身需要有个存储的功能,它的使命就是接受消息,保存好消息,然后等着消费者来拉取就好了

消费者也是各种各样,消费者的能力也是参差不齐,所以broker不能和Consumer有太多依赖

拉模式也是有缺点的,上面我们也说过了,最大的缺点就是实时性比较差,所以RocketMQ也尽力的去操作减轻这些缺点

broker来消息的时候,broker会去提醒Consumer来消息了,需要来拉取消息了,总之,就是broke和Consumer相互打配合,下面会详细说

拉模式指的是Consumer主动去找broker拉取消息,拉取模式分为普通轮询和长轮询两种方式

普通轮询也是比较简单的,就是定时发起请求,服务端收到请求之后无论是否有数据更新,都立即回复,也是属于比较好理解的,实现起来也是比较简单的,缺点呢,就是broker比较被动,需要不断的处理客户端连接的,就是服务端属于一种有求必应的方式

长轮询就是属于对普通轮询的一种优化,当然也是Consumer向服务端发起请求,而服务端收到后不会立即去响应,而是hold住客户端连接,等待数据产生变更之后才会回复客户端,或者超过指定时间还未产生变更

其实说白了,就是对普通轮询进行一定程度的限制,客户端可以随时请求服务端,但是我并不一定立即回复你

RocketMQ就是使用长轮询来实现拉模式,Consumer发起pull请求之后,broker在处理请求拉取消息的时候,如果没有查询到消息则不会回复消费者任何消息,而是等待触发通知消费者的这个事件

这里会有两种触发事件的条件:

DefaultMessageStore.ReputMessageService.run,一个定时任务,1毫秒一次,不断的检查是否有消息的产生,如果检测到了,就会通知消费者,将新消息发送给消费者

PullRequestHoldService.run也是定时任务,5秒一次,该任务会逐个的检查其中的请求,判断是否有对应的新消息产生,如果有直接返回消费者,没有就检查该请求是否超过默认的长轮询等待时间(默认15秒),如果超出,则返回消费者

RocketMQ中的PushConsumer其实底层也是拉模式实现的,只是一层披着拉模式的狼而已

因为RocketMQ后台有个ReblanceService线程会自己偷偷的去找broker请求数据,这个线程会根据topic的队列数量和当前的消费组的消费者个数进行负载均衡,每个队列产生的请求都会放入到阻塞队列中

然后有一个PullMessageService线程不断的从该阻塞队列中获取请求,然后通过网络请求broker,这样算是实现了一种准实时的拉取消息

源码在PullMessageProcessor里面的processRequest方法,用来处理拉消息的请求,有消息返回,没有消息就进入了上述说的长轮询过程,这部分源码我就不截了,大家感兴趣的可以去研究研究

 

来源:Java贼船内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯