欢迎来到 常德足轴土石方工程有限公司
全国咨询热线:
RocketMQ 一走代码造成大量新闻发送战败

原标题:RocketMQ 一走代码造成大量新闻发送战败

随州纾刊投资有限公司

作者 | 丁威

来源 | 中间件有趣圈

题目表象

最先接到项现在逆馈操纵 RocketMQ 会展现如下舛讹:

舛讹新闻关键点:MQBrokerException:CODE:2DESC:[TIMEOUT_CLEAN_QUEUE]broker busy,start flow control for a while,period in queue:205ms,size of queue:880。

由于项现在组并异国对新闻发送战败做任何赔偿,导致丢失新闻发送战败,故必要对这个题目进走深层次的探讨,并添以解决。

题目分析

最先吾们根据关键字:TIMEOUT_CLEAN_QUEUE 往 RocketMQ 中查询,往探究在什么时候会抛出如上舛讹。根据全文搜索如下图所示:

该形式是在BrokerFastFailure中定义的,议定名称即能够望成其设计现在标:Broker端迅速战败机制。

Broker端迅速战败其原理图如下:

倘若Broker端受到垃圾回收等等因素造成单条写入数据发生抖动,单个 Broker 端积压的乞求太众从而得不到及时处理,会极大的造成客户端新闻发送的时间拉长。

设想一下,倘若由于Broker压力添大,写入一条新闻必要500ms甚至超过1s,并且队列中积压了5000条新闻,新闻发送端的默认超往往间为3s,倘若根据如许的速度,这些乞求在轮到 Broker 实走写入乞求时,客户端已经将这个乞求超时了,如许不光会造成大量的无效处理,还会导致客户端发送超时。

故 RocketMQ 为晓畅决该题目,引入 Broker 端迅速战败机制,即开启一个准时调度线程,每隔10毫秒往检查队列中的第一个列队节点,倘若该节点的列队时间已经超过了 200ms,就会作废该队列中一切已超过 200ms 的乞求,立即向客户端返回战败,如许客户端能尽快进走重试,由于 Broker都是集群安放,下次重试能够发送到其他 Broker 上,如许能最大水平保证新闻发送在默认 3s 的时间内经过重试机制,能有效避免某一台 Broker 由于瞬时压力大而造成的新闻发送不走用,从而实现新闻发送的高可用。

从 Broker 端迅速战败机制引入的初衷来望,迅速战败后会发首重试,除非联相符时刻集群内一切的 Broker 都繁忙,不然新闻会发送成功,用户是不会感知这个舛讹的,那为什么用户感知了呢?难道 TIMEOUT_ CLEAN _ QUEUE 舛讹,Broker 不重试?

为晓畅开这个谜团,接下来会采用源码分析的形式往探究原形。接下来将以新闻同步发送为例展现其新闻发送处理流程中的核心关键点。

MQClient 新闻发送端最先会行使网络通道将乞求发送到 Broker,然后授与到乞求效果后并调用 ProcessSendResponse 形式对回响反映效果进走解析,如下图所示:

在这边返回的Code 为 RemotingSysResponseCode .SYSTEM_BUSY。

吾们从proccessSendResponse形式中能够得知倘若Code为SYSTEM_BUSY,该形式会抛出MQBrokerException,回响反映Code为 SYSTEM_BUSY,其舛讹描述为起头片面的舛讹新闻。

那吾们沿着该形式的调用链路,能够找到其直接调用方:DefaultMQProducerImpl 的 SendKernelImpl,吾们重点考虑倘若底层形式抛出 MQBrokerException 该形式会如那里理。

其关键代码如下图所示:

能够望出在SendKernelImpl形式中最先会捕捉变态,先实走注册的钩子函数,即就算实走战败,联系我们对答的新闻发送后置钩子函数也会实走,然后再原封不动的将该变态向上抛出。

SendKernelImpl形式被DefaultMQProducerImpl 的 SendDefaultImpl 形式调用,下面是其核心实现截图:

从这边能够望出 RocketMQ 新闻发送高可用设计一个特意关键的点,重试机制,其实现是在 For 循环中操纵 Try Catch 将SendKernelImpl 形式包裹,就能够保证该形式抛出变态后能不息重试。从上文可知,倘若 SYSTEM_BUSY 会抛出 MQBrokerException,但发现只有上述几个舛讹码才会重试,由于倘若不是上述舛讹码,会不息向表抛出变态,此时For循环会被休止,即不会重试。

这边特意令人意表的是连SYSTEM_ERROR都会重试,却异国包含 SYSTEM_BUSY,隐微违背了迅速战败的设计初衷,故笔者断定,这是RocketMQ 的一个BUG, 将SYSTEM_BUSY 遗漏了,后续会挑一个PR,增补一走代码,将 SYSTEM_BUSY 添上即可。

题目分析到这边,该题目答该就特意清新。

解决方案

倘若行家在网上搜索 TIMEOUT_CLEAN_QUEUE 的解决形式,行家不约而同挑出的解决方案是增补WaitTimeMillsInSendQueue的值,该值默认为200ms,例如将其竖立为1000s等等,以前吾是指斥的,由于吾的认知里 Broker 会重试,但现在发现 Broker不会重试,因而吾现在认为该 BUG未解决的情况下正当挑高该值能有效的缓解。

但这是并不是益的解决方案,吾会在近期向官方挑交一个PR,将这个题目修复,提出行家在公司尽量对本身操纵的版本进走修改,重新打一个包即可,由于这已经违背了 Broker 端迅速战败的设计初衷。

但在新闻发送的营业方,尽量本身实现新闻的重试机制,即不倚赖RocketMQ 本身挑供的重试机制,由于受制于网络等因素,新闻发送不能够百分之百成功,提出行家在新闻发送时捕获一下变态,倘若发送战败,能够将新闻存入数据库,再结相符准时义务对新闻进走重试,尽最大水平保证新闻不丢失。

原标题:广州富力两球员 租借加盟贵州恒丰

周一(4月27日)加拿大帝国商业银行讨论了澳元/美元的前景,并将第二季度的目标价位定为0.62。

原标题:《我才不要和你做朋友呢》8.4分爆款后,更期待贾玲的电影了

原标题:10天内事事顺心,霉运消散,有望富甲一方的生肖



Powered by 常德足轴土石方工程有限公司 @2018 RSS地图 html地图

Copyright 站群系统 © 2013-2023 版权所有