临汾山东漯河饰品美体美文
投稿投诉
美文创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品
漯河衢州
兴义眉山
桂林阳泉
玉溪简阳
山东遂宁
永城新余
梧州洛阳
泸州温州
临汾清远
营口常熟
浙江大连
桐乡宜昌

弥补延时消息的不足,RocketMQ基于时间轮算法实现了定时

11月23日 菩提门投稿
  在RocketMQ4。x版本,使用延时消息来实现消息的定时消费。延时消息可以一定程度上实现定时发送,但是有一些局限。
  RocketMQ新版本基于时间轮算法引入了定时消息,目前,精确到秒级的定时消息实现的pr已经提交到社区,今天来介绍一下。1延时消息1。1简介
  RocketMQ的延时消息是指Producer发送消息后,Consumer不会立即消费,而是需要等待固定的时间才能消费。在一些场景下,延时消息是很有用的,比如电商场景下关闭30分钟内未支付的订单。
  使用延时消息非常简单,只需要给消息的delayTimeLevel属性赋值就可以。参考下面代码:MessagemessagenewMessage(TestTopic,(Helloscheduledmessagei)。getBytes());第3个级别,10smessage。setDelayTimeLevel(3);producer。send(message);
  延时消息有18个级别,如下:privateStringmessageDelayLevel1s5s10s30s1m2m3m4m5m6m7m8m9m10m20m30m1h2h;1。2实现原理
  延时消息的实现原理如下图:
  Producer把消息发送到Broker后,Broker判断到是延时消息,首先会把消息投递到延时队列(TopicSCHEDULETOPICXXXX,queueIddelayTimeLevel1)。定时任务线程池会有18个线程来对延时队列进行调度,每个线程调度一个延时级别,调度任务把延时消息再投递到原始队列,这样Consumer就可以拉取到了。1。3存在不足
  延时消息存在着一些不足:
  1。延时级别只有18个,并不能满足所有场景;
  2。如果通过修改messageDelayLevel配置来自定义延时级别,并不灵活,比如一个在大规模的平台上,延时级别成百上千,而且随时可能增加新的延时时间;
  3。延时时间不准确,后台的定时线程可能会因为处理消息量大导致延时误差大。2定时消息
  为了弥补延时消息的不足,RocketMQ5。0引入了定时消息。2。1时间轮算法
  为了解决定时任务队列遍历任务导致的性能开销,RocketMQ定时消息引入了秒级的时间轮算法。如下图:
  图中是一个60s的时间轮,时间轮上会有一个指向当前时间的指针定时地移动到下一个时间(秒级)。
  时间轮算法的优势是不用去遍历所有的任务,每一个时间节点上的任务用链表串起来,当时间轮上的指针移动到当前的时间时,这个时间节点上的全部任务都执行。
  虽然上面只是一个60s的时间轮,但是对于所有的时间延时,都是支持的。可以在每个时间节点增加一个round字段,记录时间轮转动的圈数,比如对于延时130s的任务,round就是2,放在第10个时间刻度的链表中。这样当时间轮转到一个节点,执行节点上的任务时,首先判断round是否等于0,如果等于0,则把这个任务从任务链表中移出交给异步线程执行,否则将round减1继续检查后面的任务。2。2使用方式
  基于时间轮算法的思想,RocketMQ实现了精准的定时消息。使用RocketMQ定时消息时,客户端定义消息的示例代码如下:org。apache。rocketmq。common。message。MessagemessageExtthis。sendMessageActivity。buildMessage(null,Lists。newArrayList(Message。newBuilder()。setTopic(Resource。newBuilder()。setName(TOPIC)。build())。setSystemProperties(SystemProperties。newBuilder()。setMessageId(msgId)。setQueueId(0)。setMessageType(MessageType。DELAY)。setDeliveryTimestamp(Timestamps。fromMillis(deliveryTime))定义消息投递时间。setBornTimestamp(Timestamps。fromMillis(System。currentTimeMillis()))。setBornHost(StringUtils。defaultString(RemotingUtil。getLocalAddress(),127。0。0。1:1234))。build())。setBody(ByteString。copyFromUtf8(123))。build()),Resource。newBuilder()。setName(TOPIC)。build())。get(0);2。3实现原理2。3。1消息投递
  上面的代码构中,Producer创建消息时给消息传了一个系统属性deliveryTimestamp,这个属性指定了消息投递的时间,并且封装到消息的TIMERDELIVERMS属性,代码如下:protectedvoidfillDelayMessageProperty(apache。rocketmq。v2。Messagemessage,org。apache。rocketmq。common。message。MessagemessageWithHeader){if(message。getSystemProperties()。hasDeliveryTimestamp()){TimestampdeliveryTimestampmessage。getSystemProperties()。getDeliveryTimestamp();delayTime这个延时时间默认不能超过1天,可以配置longdeliveryTimestampMsTimestamps。toMillis(deliveryTimestamp);validateDelayTime(deliveryTimestampMs);。。。StringtimestampStringString。valueOf(deliveryTimestampMs);MessageConst。PROPERTYTIMERDELIVERMSTIMERDELIVERMSMessageAccessor。putProperty(messageWithHeader,MessageConst。PROPERTYTIMERDELIVERMS,timestampString);}}
  Broker收到这个消息后,如果判断到TIMERDELIVERMS这个属性有值,就会把这个消息投递到Topic是rmqsyswheeltimer的队列中,queueId是0,同时会保存原始消息的Topic、queueId、投递时间(TIMEROUTMS)。
  TimerMessageStore中有个定时任务TimerEnqueueGetService会从rmqsyswheeltimer这个Topic中读取消息,然后封装TimerRequest请求并放到队列enqueuePutQueue。2。3。2绑定时间轮
  RocketMQ使用TimerLog来保存消息的原始数据绑定到时间轮上。首先看一下TimerLog保存的数据结构,如下图:
  参考下面代码:TimerMessageStore类ByteBuffertmpBuffertimerLogBtmpBuffer。clear();tmpBuffer。putInt(TimerLog。UNITSIZE);sizetmpBuffer。putLong(slot。lastPos);prevpostmpBuffer。putInt(magic);magictmpBuffer。putLong(tmpWriteTimeMs);currWriteTimetmpBuffer。putInt((int)(delayedTimetmpWriteTimeMs));delayTimetmpBuffer。putLong(offsetPy);offsettmpBuffer。putInt(sizePy);sizetmpBuffer。putInt(hashTopicForMetrics(realTopic));hashcodeofrealtopictmpBuffer。putLong(0);reservedvalue,justsetto0nowlongrettimerLog。append(tmpBuffer。array(),0,TimerLog。UNITSIZE);if(1!ret){Ifitsadeletemessage,thenslotstotalnum1TODO:checkifthedeletemsgisinthesameslotwiththemsgtobedeleted。timerWheel。putSlot(delayedTime,slot。firstPos1?ret:slot。firstPos,ret,isDelete?slot。num1:slot。num1,slot。magic);}
  TimerEnqueuePutService这个定时任务从上面的enqueuePutQueue(2。3。1节)取出TimerRequest然后封装成TimerLog。
  那时间轮是怎么跟TimerLog关联起来的呢?RocketMQ使用TimerWheel来描述时间轮,TimerWheel中每一个时间节点是一个Slot,Slot保存了这个延时时间的TimerLog信息。数据结构如下图:
  参考下面代码:类TimerWheelpublicvoidputSlot(longtimeMs,longfirstPos,longlastPos,intnum,intmagic){localBuffer。get()。position(getSlotIndex(timeMs)Slot。SIZE);localBuffer。get()。putLong(timeMsprecisionMs);localBuffer。get()。putLong(firstPos);localBuffer。get()。putLong(lastPos);localBuffer。get()。putInt(num);localBuffer。get()。putInt(magic);}
  这样时间轮跟TimerLog就关联起来了,见下图:
  如果时间轮的一个时间节点(Slot)上有一条新的消息到来,那只要新建一个TimerLog,然后把它的指针指向该时间节点的最后一个TimerLog,然后把Slot的lastPos属性指向新建的这个TimerLog,如下图:
  从源码上看,RocketMQ定义了一个7天的以秒为单位的时间轮。2。3。3时间轮转动
  转动时间轮时,TimerDequeueGetService这个定时任务从当前时间节点(Slot)对应的TimerLog中取出数据,封装成TimerRequest放入dequeueGetQueue队列。2。3。4CommitLog中读取消息
  定时任务TimerDequeueGetMessageService从队列dequeueGetQueue中拉取TimerRequest请求,然后根据TimerRequest中的参数去CommitLog(MessageExt)中查找消息,查出后把消息封装到TimerRequest中,然后把TimerRequest写入dequeuePutQueue这个队列。2。3。5写入原队列
  定时任务TimerDequeuePutMessageService从dequeuePutQueue队列中获取消息,把消息转换成原始消息,投入到原始队列中,这样消费者就可以拉取到了。3总结
  RocketMQ4。x版本只支持延时消息,有一些局限性。而RocketMQ新版本引入了定时消息,弥补了延时消息的不足。定时消息的处理流程如下图:
  可以看到,RocketMQ的定时消息的实现还是有一定复杂度的,这里用到5个定时任务和3个队列来实现。
  最后,对于定时时间的定义,客户端、Broker和时间轮的默认最大延时时间定义是不同的,使用的时候需要注意。来源:https:mp。weixin。qq。comsI91QRel7CraP7zCRh0ISw
  作者:朱晋君

人物志梅西球王三世的加冕仪式,还差卡塔尔的最后一哆嗦球王跟球星的最大区别在哪里?窃以为,球王是超越足球的存在,可以载入史册,出现在教科书里供人瞻仰的人物。他可以和苏格拉底,米开朗琪罗,达芬奇,牛顿,爱因斯坦等人物并列,成为……在外打工的妈妈通过监控看宝宝,孩子一个细节引起注意近日,湖南一位在外地打工的妈妈通过监控发现自家孩子的手经常不自觉地抖动随后孩子妈妈将这段日常发到网上询问网友这是什么情况对此有网……秒杀Grammarly?专业语法纠错,母语级润色,生成写作报笔者在推文:其他翻译工具真的弱爆了!有道学术来了,翻译词典居然可以检索、下载论文了!介绍过有道学术可以检索和下载论文。最近,有道词典又更新了有道写作功能,具有专业语法纠错……这样买货币基金,赚的最多大家好,之前我们介绍了货币基金,关于它的概念、原理、特点,知道了它是打理活钱的好方法。详情请戳货币基金,灵活理财的首选也说到货币基金的典型代表余额宝,近几年的收益一……同样的奇兵不一样的运气!刘晓彤成为福将,李盈莹变成憾将中国女排是一个大家庭,每一个球员的荣誉都与女排这个集体联系在一起。水涨船高,集体成绩好,球员的个人荣誉就高。不同时期,中国女排的成绩有所不同,注定球员的荣誉也会不同。球员的荣誉……福布斯2022全球十大首富2022年4月5日,福布斯杂志公布了第36届全球首富年度排行榜。福布斯认为,由于战事、新冠疫情和市场疲软,2022年全球共有资产上亿者2668位,比2021年减少87位。与此同……迷惑行为!韩国选手领奖台突然跳舞,被网友调侃真是丑人多作怪近日有很多网友关注了韩国短道速滑队在颁奖典礼上的表现,在男子5000米的颁奖典礼上,韩国队的郭润起突然跳起了舞,对于郭润起这样的行为,很多网友都觉得非常疑惑,虽然参加颁奖仪式并……最奇特的一次旅游作者周永久用黑龙江省部分地名飞行去北京和经过的省市地名!我乘坐一条黑龙,加满大庆的石油。装满北大荒的粮仓,带上拜泉的一桶明水。揣上富锦牌手机,带上充满……弹珠弹上月球?玉兔二号在月球发现厘米级玻璃球科幻网2月21日讯(秦莹莹)人们看到的月球始终是它的一面,古往今来,人们对月球的背面有许多猜测,人类揭开月球背面的真面目,还是从环绕月球飞行开始的。但在月球背面,从地球发出的信……篮网惨败马刺!赵四3替补难救主,西蒙斯三双,2射全队三分崩盘北京时间1月18号篮网和马刺的比赛,这场比赛杜兰特没在,而且欧文还缺席了,这也造成全场比赛篮网都很难占据优势。即便比赛中期篮网一度追平,然而马刺一波小高潮之后再度拉开,就此10……上海豫园灯会年味浓打卡指南大放送要说全上海年味最浓的地方在哪里,那应该就是豫园吧!今年豫园灯会以中国传统神话《山海经》为蓝本,融非遗艺术灯彩、沉浸式国风体验、线上线下趣味互动于一体。九曲桥敲……乐歌智能学习桌,助力家长探索科学有效的教育方法心理学家说:爱需要付出,更需要智慧。中国大多数父母习惯把不要、别这些说教性、批评式语言挂在嘴边,例如看到水坑让孩子不要踩,房间乱了让孩子赶紧收。而教训的结果常常事与愿违越是一遍……
妈阁游玩记2娱乐菜市场里的游戏很多有21点、百家LE、大小点、加勒比、轮盘等,人最多的还是百家LE,虽然我们也不懂大家为什么喜欢玩,我想可能就是简单、公平的游戏吧。转了一圈,我们在21点台……缺席世界杯20载,从塔卡尔世界杯浅谈中国男足的落魄之因小时候,看到大人在看各大足球比赛,看来看去都没看到过五星红旗,不禁好奇地问:中国队在哪呢?而大人总是略显落寞地答:这次中国队没去。中国足球队一直没去成了我的童年记忆。长大后,才……快速发面的实用方法,天冷还是热,都非常实用,新手也能成功大家好,这里是小雅美食记,发面,指面团在一定温、湿度条件下,让酵母充分繁殖产气,促使面团膨胀的过程。当酵母菌在面团内部有氧的环境下,将淀粉转化为糖并消耗掉的时候,会释放出二氧化……太阳爆发内讧!艾顿不满队友不传球,保罗在更衣室当众训斥年轻人太阳队从上个赛季开始就内讧不断,蒙蒂和艾顿一直以来都互相看不顺眼对方,甚至就连老板现在都被撵了出去,本赛季更是在比赛中球员之间还有教练这一件再次爆发了矛盾,由此可见他们在镜头前……董明珠和格力的中国芯,铁娘子董明珠打造中国芯视频请点击下方链接:董明珠和格力的中国芯,铁娘子董明珠打造中国芯自从近几年我国的芯片产业被欧美国家卡脖子以来,中国人对中国芯的渴望似乎从来没有像现在这样强烈。但是,……抄书第四十五天,打卡收益抄书第四十五天抄书打卡总收益97。94元今天抄的是《先学会爱自己,再遇见对你的》这本书是今年到目前为止,对我而言最好的一本书。它帮助我去重新认识自己,让……糟糠之妻葛淑珍不靠赵本山不求任何人,一样白手起家挣百万说起赵本山,相信很多人都非常的熟悉。可是说起赵本山背后的糟糠之妻,相信很多人都非常陌生了。赵本山现在的妻子马丽娟,是一个非常有才华、非常善良、非常贤惠的女人。……江苏南通生态修复成效显秋日美景迎客来来源:人民网图片频道2022年10月29日,江苏南通狼山国家森林公园军山绿野美丽秋景。2022年10月29日,市民在江苏南通狼山国家森林公园军山绿野格桑花花海赏花。……婚后不孕,检查显示自己竟是男性?!哪些人群有必要做染色体核型随着社会的发展和国家政策的开放,人们对生殖医学的认识也越来越充分,有越来越多的人也逐渐开始重视生殖医学领域。然而,我们真的对自己的性别有充分的认知吗?我们怎么会不清楚自己……国缘V9国之大者缘开智能科学技术是高质量发展的第一生产力。世界上高端技术无一不是智能化的结晶,飞机、汽车、电脑、手机等无一例外。国缘V9为什么是当今中国超舒适的高端白酒?机械化酿造、智能化裝甑、……超强性能,旗舰新款,泰捷WE40PRO电视盒子国内市场,智能电视已经占据彩电市场半壁江山。智能电视火爆销售背后,行业和使用者的尴尬也越来越多,一方面电视开机广告已经被人诟病了好久,另一方面,随着使用时间延长,系统运行也会越……录音公布!家中失火,4岁萌娃思路清晰打119自救消防员叔叔我家里着火了,你们快来近日,广西南宁消防救援支队指挥中心接到一通萌娃的求助电话视频加载中。。。经接警员了解得知女孩家中起火……
友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找