应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

读RocketMQ源码,学习并发编程三大神器

  笔者是RocketMQ的忠实粉丝,在阅读源码的过程中,学习到了很多编程技巧。
  这篇文章,笔者结合RocketMQ源码,分享并发编程三大神器的相关知识点。
  1CountDownLatch实现网络同步请求
  CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,它能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。
  下图是CountDownLatch的核心方法:
  我们可以认为它内置一个计数器,构造函数初始化计数值。每当线程执行countDown方法,计数器的值就会减一,当计数器的值为0时,表示所有的任务都执行完成,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。
  举例,数据库有100万条数据需要处理,单线程执行比较慢,我们可以将任务分为5个批次,线程池按照每个批次执行,当5个批次整体执行完成后,打印出任务执行的时间。longstartSystem。currentTimeMillis();ExecutorServiceexecutorServiceExecutors。newFixedThreadPool(10);intbatchSize5;CountDownLatchcountDownLatchnewCountDownLatch(batchSize);for(inti0;ibatchSize;i){finalintbatchNumberi;executorService。execute(newRunnable(){Overridepublicvoidrun(){try{doSomething(batchNumber);}catch(Exceptione){e。printStackTrace();}finally{countDownLatch。countDown();}}});}countDownLatch。await();System。out。println(任务执行耗时:(System。currentTimeMillis()start)毫秒);
  温习完CountDownLatch的知识点,回到RocketMQ源码。
  笔者在没有接触网络编程之前,一直很疑惑,网络同步请求是如何实现的?
  同步请求指:客户端线程发起调用后,需要在指定的超时时间内,等到响应结果,才能完成本次调用。如果超时时间内没有得到结果,那么会抛出超时异常。
  RocketMQ的同步发送消息接口见下图:
  追踪源码,真正发送请求的方法是通讯模块的同步请求方法invokeSyncImpl。
  整体流程:发送消息线程Nettychannel对象调用writeAndFlush方法后,它的本质是通过Netty的读写线程将数据包发送到内核,这个过程本身就是异步的;ResponseFuture类中内置一个CountDownLatch对象,responseFuture对象调用waitRepsone方法,发送消息线程会阻塞;
  客户端收到响应命令后,执行processResponseCommand方法,核心逻辑是执行ResponseFuture的putResponse方法。
  该方法的本质就是填充响应对象,并调用countDownLatch的countDown方法,这样发送消息线程就不再阻塞。
  CountDownLatch实现网络同步请求是非常实用的技巧,在很多开源中间件里,比如Metaq,Xmemcached都有类似的实现。2ReadWriteLock名字服务路由管理
  读写锁是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,而写锁则是互斥锁。
  它的规则是:读读不互斥,读写互斥,写写互斥,适用于读多写少的业务场景。
  我们一般都使用ReentrantReadWriteLock,该类实现了ReadWriteLock。ReadWriteLock接口也很简单,其内部主要提供了两个方法,分别返回读锁和写锁。publicinterfaceReadWriteLock{获取读锁LockreadLock();获取写锁LockwriteLock();}
  读写锁的使用方式如下所示:创建ReentrantReadWriteLock对象,当使用ReadWriteLock的时候,并不是直接使用,而是获得其内部的读锁和写锁,然后分别调用lockunlock方法;privateReadWriteLockreadWriteLocknewReentrantReadWriteLock();读取共享数据;LockreadLockreadWriteLock。readLock();readLock。lock();try{TODO查询共享数据}finally{readLock。unlock();}写入共享数据;LockwriteLockreadWriteLock。writeLock();writeLock。lock();try{TODO修改共享数据}finally{writeLock。unlock();}
  RocketMQ架构上主要分为四部分,如下图所示:
  Producer:消息发布的角色,Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递,投递的过程支持快速失败并且低延迟。Consumer:消息消费的角色,支持以push推,pull拉两种模式对消息进行消费。BrokerServer:Broker主要负责消息的存储、投递和查询以及服务高可用保证。NameServer:名字服务是一个非常简单的Topic路由注册中心,其角色类似Dubbo中的zookeeper,支持Broker的动态注册与发现。
  NameServer是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。Broker启动之后会向所有NameServer定期(每30s)发送心跳包(路由信息),NameServer会定期扫描Broker存活列表,如果超过120s没有心跳则移除此Broker相关信息,代表下线。
  那么NameServer如何保存路由信息呢?
  路由信息通过几个HashMap来保存,当Broker向Nameserver发送心跳包(路由信息),Nameserver需要对HashMap进行数据更新,但我们都知道HashMap并不是线程安全的,高并发场景下,容易出现CPU100问题,所以更新HashMap时需要加锁,RocketMQ使用了JDK的读写锁ReentrantReadWriteLock。更新路由信息,操作写锁
  查询主题信息,操作读锁
  读写锁适用于读多写少的场景,比如名字服务,配置服务等。3CompletableFuture异步消息处理
  RocketMQ主从架构中,主节点与从节点之间数据同步复制的方式有同步双写和异步复制两种模式。
  异步复制是指消息在主节点落盘成功后就告诉客户端消息发送成功,无需等待消息从主节点复制到从节点,消息的复制由其他线程完成。
  同步双写是指主节点将消息成功落盘后,需要等待从节点复制成功,再告诉客户端消息发送成功。
  同步双写模式是阻塞的,笔者按照RocketMQ4。6。1源码,整理出主节点处理一个发送消息的请求的时序图。
  整体流程:生产者将消息发送到Broker,Broker接收到消息后,发送消息处理器SendMessageProcessor的执行线程池SendMessageExecutor线程池来处理发送消息命令;执行ComitLog的putMessage方法;ComitLog内部先执行appendMessage方法;然后提交一个GroupCommitRequest到同步复制服务HAService,等待HAService通知GroupCommitRequest完成;返回写入结果并响应客户端。
  我们可以看到:发送消息的执行线程需要等待消息复制从节点,并将消息返回给生产者才能开始处理下一个消息。
  RocketMQ4。6。1源码中,执行线程池的线程数量是1,假如线程处理主从同步速度慢了,系统在这一瞬间无法处理新的发送消息请求,造成CPU资源无法被充分利用,同时系统的吞吐量也会降低。
  那么优化同步双写呢?
  从RocketMQ4。7开始,RocketMQ引入了CompletableFuture实现了异步消息处理。发送消息的执行线程不再等待消息复制到从节点后再处理新的请求,而是提前生成CompletableFuture并返回;HAService中的线程在复制成功后,调用CompletableFuture的complete方法,通知remoting模块响应客户端(线程池:PutMessageExecutor)。
  我们分析下RocketMQ4。9。4核心代码:Broker接收到消息后,发送消息处理器SendMessageProcessor的执行线程池SendMessageExecutor线程池来处理发送消息命令;调用SendMessageProcessor的asyncProcessRequest方法;
  调用Commitlog的aysncPutMessage方法写入消息;这段代码中,当commitLog执行完appendMessage后,需要执行刷盘任务和同步复制两个任务。但这两个任务并不是同步执行,而是异步的方式。复制线程复制消息后,唤醒future;组装响应命令,并将响应命令返回给客户端。
  为了便于理解这一段消息发送处理过程的线程模型,笔者在RocketMQ源码中做了几处埋点,修改Logback的日志配置,发送一条普通的消息,观察服务端日志。
  从日志中,我们可以观察到:发送消息的执行线程(图中红色)在执行完创建刷盘Future和同步复制future之后,并没有等待这两个任务执行完成,而是在结束asyncProcessRequest方法后就可以处理发送消息请求了;刷盘线程和复制线程执行完各自的任务后,唤醒future,然后通过刷盘线程组装存储结果,最后通过PutMessageExecutor线程池(图中黄色)将响应命令返回给客户端。
  笔者一直认为:异步是更细粒度的使用系统资源的一种方式,在异步消息处理的过程中,通过CompletableFuture这个神器,各个线程各司其职,优雅且高效的提升了RocketMQ的性能。
  如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我输出更高质量的文章,非常感谢!

迪瑞医疗荣获出口商品品牌证明书宋维东中国证券报中证网中证网讯(记者宋维东)中国证券报记者11月25日从迪瑞医疗获悉,公司日前荣获由中国贸促会签发的《出口商品品牌证明书》。这也为迪瑞医疗进一步开拓海外市……亚健康肥胖是第一杀手随着时代的推移,我们已经处在这日新月异的时期,人们的生活节奏变快,压力加大,经常熬夜,生活也较混乱,生活也变得没规律,所以导致亚健康一肥胖的人越来越多面临这种生活状况,我……中超最新积分榜武汉三镇重回榜首提前夺冠?降级三队提前出炉12月27日,本赛季中超倒数第二轮全面展开,3场关键保级战率先开打,广州城20胜深圳队提前一轮成功保级,广州队、武汉长江分别输给长春亚泰、成都蓉城提前一轮降级。由于梅州客家放弃……双生病毒操控植物应激反应的新机制被发现近日,中国农业科学院植物保护研究所作物病原生物功能基因组研究创新团队率先发现双生病毒可以时空调节植物的应激反应,适时操控下游基因的表达,促进病毒积累和侵染的新机制。该研究为深入……双11入手16256GB大内存旗舰!游戏党分享体验,旦用难回在今年双11挑手机真的是很容易迷失在选择当中,原因就在于目前真香机型太多了,不过在众多机型当中我最后还是入手了一加AcePro。主要是因为它的价格更符合我的需求,同时在网上也看……黑胶重回大众生活?千元级唱机让无损音乐也无法对抗,格调是关键抬起唱臂,轻轻拨到唱片边缘,落下唱针,随着两者渐渐接触,一首与现代数字化音乐迥然不同的实体音乐声缓缓响起,仿佛为我们在这喧嚣的城市中建立了一个独特而优雅空间。相信这是很多小伙伴……滑稽三人行到夏威夷去夏威夷日本移民的历史故事我的记忆中儿时看的中央八套海外剧场日剧《冷暖人间》中有一段剧情,大致意思是说去夏威夷是日本人的旅游胜地海外旅行首选目的地。在早期游戏杂志中同样记载了一篇夏威夷的趣闻,上世纪八十……抬头!看!抬头!看!9月10日晚在江苏省南京市拍摄的圆月与阅江楼。新华社发(方东旭摄)今天是中秋节而17时59分也是中秋满月最圆的时刻一切的一切都是那……社保缴费基数调整,请注意补退差额调整缴费基数前,原临时缴费基数上限为20599元、下限为4121元。目前,市人社部门已按照上级公布的上下限对威海市参保单位进行了调整。申报的月缴费基数低于下限3980元的……供销社概念领涨,这2股录得三连板,多家上市公司回应相关业务情11月2日,供销社概念持续走强,截至发稿,天禾股份、浙农股份、天鹅股份、中农联合4股涨停,辉隆股份、中再资环、新野纺织、中农立华等纷纷上涨。其中,天鹅股份、中农联合录得三……房地产的春天来了吗?房地产再迎利好新政策。2020年为了遏制房价快速上涨,国务院发布通知,暂停房地产企业上市再融资,时隔12年,房价不但遏制住了,而且还在不断下跌,尤其是某些三四线城市还在跌跌不休……荷甲和英超的两场比赛奈梅亨VS瓦尔韦克布莱顿VS维拉奈梅亨VS瓦尔韦克奈梅亨本赛季13轮比赛取得2胜8平3负的战绩,积14分,目前排名联赛第10位。奈梅亨在本赛季13轮比赛中共打进13球,场均进1球,进攻稍显疲软,共丢15……
经常吃面条,对身体好还是不好?提醒吃面条时或需要注意这4点导语:面条几乎是家家户户厨房中必备的一种食物,虽然说面食是北方人的主食,但是有很多南方人也很喜欢吃面食,再配上美味的菜品,既营养又美味。小小的面条真的有如此大的魅力吗?经……恒丰银行化险三人组相继调任再次换帅一年收十张罚单被罚925万长江商报记者蔡嘉全国12家股份制商业银行之一的恒丰银行改革化险后首次更换掌门人。日前,恒丰银行在官网公布董事会名单,辛树人拟任该行董事长、执行董事。这也意味着,20……乐东黄流猪脚饭要凌晨三点才好吃凌晨三点钟猪脚饭美食攻略最地道的美食在街头巷尾,最正宗的味儿在烟火深处。黄流不仅是人文荟萃之地,美食也值得打卡,今天终于吃到传说中的凌晨三点……去年129家首店落地浦东新区,陆家嘴商圈受青睐上海被视为首店经济的标杆城市,2022年在首店经济发展中继续引领全国。来自中商数据的统计显示,2022年上海共计引入1073家首店(含旗舰店概念店),与2021年基本持平,在首……超市4大裸瓶酒,都是坚决不加1滴香精的纯酿,却因便宜遭人嫌去超市买东西就是图方便。去大润发、沃尔玛这种大超市,虽然东西会稍微贵点儿,但也是为了图个安心。年关将至,用酒量基层,不少超市里都开始搞起了白酒活动。不少白酒都是搞促……广东输球3大国手低迷,杜锋出师不利看出杨鸣机智,他确实成长了北京时间12月27日,此前结束的CBA巅峰一战,最终广东爆冷在首轮崩盘惨败给了浙江广厦,这样一来广东队痛失了反超辽宁冲到第一的机会。而这一次不仅仅是广东完全没有把握住天赐……减字木兰花七十二道拐头上天梯,斗折蛇行云端里。脚随步移。踩云踏雾眼迷离。雄关耸立。峻岭险道关城闭。山秀水奇。无限风光多旖旎。七十二道拐是白陉古道中较……冬奥会开幕式上的河南籍灯光师张俊杰为绚丽的色彩拥抱漆黑的夜大象新闻记者李昌陈伟然北京冬奥会开幕式再次惊艳了世界,在这场美轮美奂又极具深意的开幕式背后,灯光是重要的帮手。在冬奥会开幕式现场效果灯光编程团队里就有一名来自河南的灯光师……首钢大跳台冷却塔,无知外媒眼中的核反应堆,必成网红打卡地蜀黍先平复一下情绪,最近让人笑掉大牙的一件事,无非就是有外媒说人气女王谷爱凌夺冠的北京首钢大跳台后面的建筑是核反应堆这件事。全国人民都知道那是首钢集团原工业园区四座废弃冷……盘点全球足球人才流失最严重的10个国家地区非洲杯,移民球员成为了一个永恒的话题。随着非洲大量足球人才入选欧洲各豪强的国家队,在非洲杯赛场上,一些这里的球队也做出了反击,从欧洲球队那里抢到了一些混血球员。但是总体而言,人……探访古村落北京刘家峪古村落北京周边很多古村落,有的成为了旅游景点,如:爨底下村、灵水举人村等。有的已经废弃。路上,我们探访了京西的刘家峪古村落。村落已经荒芜,有的院子已经残缺,只留了个门楼。里面的……王俊凯宣布解除与英特尔品牌的一切合作关系12月21日,英特尔官网悬挂了一则用简体中文,繁体中文,英文以及日文等多种语言的通告,通告中完全不顾及中国是其连续6年最大营收来源地,要求它的供应商禁用任何来自新疆地区的劳工,……
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网