最近正在研究rocketmq,简单记录下设计的不同

互联网系统中Rpc、服务治理、消息中间件基本都是标配,消息中间件能解耦,削峰,高可用并能间接提供达到最终一致性

消息中间件中,消息消费分为最多一次,至少一次和刚好一次,如果需要实现刚好一次,则系统设计难度增大,系统性能损失增加,权衡利弊,rocket实现的是最少一次,消费端可能会重复接收消息(ACK模式下,ACK消息可能丢失),由消费端幂等消费

为什么不用zk,还是从实际需求出发,Topic路由信息无需在集群之间保持强一致性,最终一致即可,从而减少对zk的依赖和性能的损失

消息存储方面,rocket引入文件组,无限循环使用,commitlog文件每个1G,以第一个偏移值为文件名,为了和consumequeue一致,log中还包含了tag,key等信息便于恢复,顺序写,引入内存映射,相同主题的消息被顺序存储在同一文件中,还提供定时清理等防止过度堆积,利用消费队列文件和索引文件及pagecache等提升读性能,ConsumeQueue是消息的逻辑队列,类似数据库的索引文件,存储的是指向物理存储的地址。每个Topic下的每个Message Queue都有一个对应的ConsumeQueue文件, 里面有一部分是存储了tag对应的hashcode,经过对比,符合要求的消息被从commitlog中读取出来,消息在消费前,会对比完整的Message Tag字符串,清除hash冲突造成的误读

消息过滤,基于tag等,在存储设计上基于hash等方式提升过滤效率,可以从Broker或者消费端过滤,broker端过滤可以减少传递到消费端的消息,减少网络损失,消费端过滤可以由消费者任意定义

定时消息,如果要支持任意精度的定时消息消费,必须在消息服务端对消息进行排序,势必带来很大的性能损耗,rocketmq设计不支持任意进度的定时消息,只支持特定延迟级别

客户端支持Push(被推送)、pull(自主控制messagequeue的遍历及消息的读取)两种模式

线程池设计,rocketmq会根据不同的任务类型创建不同的线程池,如果该类型没注册,则由other之类的线程池统一处理

Namesrv之间数据可以不一致,彼此之间互不通信

消息发送端提供容错机制,这个地方之前我就有疑问,为什么在客户端或者消费端获取消息存储meta信息之后,namesrv发现变化后不会通知他们。。。原来是由meta使用端的容错机制来保证高可用,降低namesrv的复杂性

消息的顺序性保证,如果要全局一致,必须单一topic,单一生产者及消费者,清除一切并发,可行性比较低,性能和吞吐量无法接受,结合业务,一般是部分顺序消息,发送端将同一业务ID的消息发送到同一个Message Queue,在消费过程中,不并发处理

CommitLog同步,不是经过netty命令的方式,而是直接TCP连接,效率更高,连接成功后,通过对比master和slave的offset,不断进行同步

从broker获得的消息,因为是提交到线程池里并行执行,很难监控和控制执行状态,RocketMQ定义了一个快照类ProcessQueue来解决

负载均衡或消息分配是在消费者端代码中完成,Consumer从broker处获取全局消息,然后自己做负载均衡,只处理分给自己的部分

跟kafka一样,总的消费者数量不要超过topic的队列数,否则多余的消费者收不到消息

Namesrv本身无状态,其中的Broker,topic等状态信息不会持久存储,都是由各个角色定期上报并存储到内存中

事物消息的实现:发送方向RocketMQ发送“待确认”消息,RocketMQ将收到的“待确认”消息持久化后,向发送方回复消息已经发送成功,发送方开始执行本地事件逻辑,发送方根据本地事件逻辑想RocketMQ发送二次确认,RocketMQ收到commit状态则将第一阶段消息标记为可投递,订阅方将能收到该消息,收到rollback状态则删除第一阶段的消息,如果出现异常,服务器在一段时间后未收到确认消息,则服务器将对“待确认”消息发起回查请求,发送方收到回查请求后通过检查对应消息的本地事件执行结果返回对应的状态,RocketMQ收到后继续处理

服务端接受到新请求后,如果队列没有新消息,并不急于返回,通过一个循环不断查看状态,长轮询的核心是,broker端hold住客户端过来的请求一小段时间,在这个时间内有新消息到达,就利用现有的链接立即返回给消息的consumer,长轮询主动权还是掌握在消费端手中,即使broker消息大量积压,也不会主动推送给消费者

在同步刷盘过程种,有一个设计,避免了任务提交与任务执行的锁冲突,由于避免同步刷盘消费任务与其他消费生产者提交任务直接的锁竞争,GroupCommitService提供读容器与写容器,这两个容器每执行完一次任务后,交互,继续消费任务。

        private volatile List<GroupCommitRequest> requestsWrite = new ArrayList<GroupCommitRequest>();
private volatile List<GroupCommitRequest> requestsRead = new ArrayList<GroupCommitRequest>(); public synchronized void putRequest(final GroupCommitRequest request) {
synchronized (this.requestsWrite) {
this.requestsWrite.add(request);
}
if (hasNotified.compareAndSet(false, true)) {
waitPoint.countDown(); // notify
}
} private void swapRequests() {
List<GroupCommitRequest> tmp = this.requestsWrite;
this.requestsWrite = this.requestsRead;
this.requestsRead = tmp;
}

阅读rocketmq技术内幕、实战与原理杂记 - 设计的更多相关文章

  1. Spring技术内幕:SpringIOC原理学习总结

    前一段时候我把Spring技术内幕的关于IOC原理一章看完,感觉代码太多,不好掌握,我特意又各方搜集了一些关于IOC原理的资料,特加深一下印象,以便真正掌握IOC的原理. IOC的思想是:Spring ...

  2. 社区布道师揭秘消息中间件技术内幕,撰写MQ架构设计与实现原理

    RocketMQ是什么 RocketMQ是由阿里捐赠给Apache的一款分布式.队列模型的开源消息中间件,经历了淘宝双十一的洗礼. RocketMQ的特性 RocketMQ基本概念 Client端 P ...

  3. jQuery技术内幕 深入解析jQuery架构设计与实现原理

    jquery的外衣 jquery是一个轻量级的JS框架 //以下截取自jquery源码片段 (function( window, undefined ) { /* 源码内容 */ })( window ...

  4. 【RocketMQ】事务的实现原理

    事务的使用 RocketMQ事务的使用场景 单体架构下的事务 在单体系统的开发过程中,假如某个场景下需要对数据库的多张表进行操作,为了保证数据的一致性,一般会使用事务,将所有的操作全部提交或者在出错的 ...

  5. Struts2技术内幕 读书笔记一 框架的本质

    本读书笔记系列,主要针对陆舟所著<<Struts2技术内幕 深入解析Strtus2架构设计与实现原理>>一书.笔记中所用的图片若无特殊说明,就都取自书中,特此声明. 什么是框架 ...

  6. 重读COM技术内幕(inside com)有感

    重读COM技术内幕(inside com)有感 面向对象设计哲学在复杂领域并不能很好地解决问题.参考(http://www.richardlord.net/blog/what-is-an-entity ...

  7. 快读《ASP.NET Core技术内幕与项目实战》EFCore2.5:集合查询原理揭秘(IQueryable和IEnumerable)

    本节内容,涉及4.6(P116-P130).主要NuGet包:如前述章节 一.LINQ和EFCore的集合查询扩展方法的区别 1.LINQ和EFCore中的集合查询扩展方法,虽然命名和使用完全一样,都 ...

  8. 《ASP.NET Core技术内幕与项目实战》精简集-目录

    本系列是杨中科2022年最新作品<ASP.NET Core技术内幕与项目实战>及B站配套视频(强插点赞)的精简集,是一个读书笔记.总结和提炼了主要知识点,遵守代码优先原则,以利于快速复习和 ...

  9. 《jQuery技术内幕:深入解析jQuery架构设计与实现原理》

    <jQuery技术内幕:深入解析jQuery架构设计与实现原理> 基本信息 作者: 高云 出版社:机械工业出版社 ISBN:9787111440826 上架时间:2014-1-10 出版日 ...

随机推荐

  1. AE插件:能量激光描边光效特效Saber Mac汉化版

    与大家分享一款非常好用的AE插件Saber插件汉化版.videocopilot saber是一款能量激光描边光效特效AE插件,可以帮助用户制作出能量激光.传送门.霓虹灯.电流.光束.光剑等效果.小编现 ...

  2. C++ 自定义时间

      今天精神状态不好,和公司的领导请了假.为了抵抗我的痛苦,我在床上打坐冥想,从早上九点到下午三点二十六.嗯,感觉好多了.这种温和的暴力果然有效.   之后吃了点东西,然后无聊的我就在想,明天的工作该 ...

  3. JavaScript中的ononline事件和onoffline事件

    关于这个时间的描述到处都有,但基本上都是说离线在线什么的我一下子还没反应过来.后再在这里看到了一句话:"断开网络再联网试试,就可以看到连线的提示."这才反应过来,原来指的是网络状态 ...

  4. HBASE 基础命令总结

    HBASE基础命令总结 一,概述 本文中介绍了hbase的基础命令,作者既有记录总结hbase基础命令的目的还有本着分享的精神,和广大读者一起进步.本文的hbase版本是:HBase 1.2.0-cd ...

  5. python selenium TouchAction模拟移动端触摸操作(十八)

    最近做移动端H5页面的自动化测试时候,需要模拟一些上拉,下滑的操作,最初考虑使用使用selenium ActionChains来模拟操作,但是ActionChains 只是针对PC端程序鼠标模拟的一系 ...

  6. java web中分层MVC的意义

    在web编程中,由于高内聚.低耦合的特点,需要将多个类实现多层,大致有以下几层:①entity,实体类,如user,role等,这些类里边包含了私有属性和公共的get.set方法这和数据库中的表相对应 ...

  7. 专访笨叔叔:2019年可能是Linux年?(转)

    链接:https://zhuanlan.zhihu.com/p/57815479 2017年9月<奔跑吧 Linux内核>一书出版后得到了广大Linux从业人员和爱好者(特别是从事Linu ...

  8. innobackupex 远程备份

    # 远程备份./innobackupex --defaults-file=/etc/my.cnf --no-timestamp -user xxx --host xx.xx.123 --passwor ...

  9. 第四节 Python基础之数据类型(集合)

    在学习本节之前,我们先对数据类型做一个补充,也就是数据类型的分类: 按照可变和不可变来分: 可变:列表,字典 不可变:数字,字符串,元组 按照访问顺序来分: 顺序访问:字符串,列表,元组 映射的方式访 ...

  10. 简简单单美化你Mac os x的终端配色

    Mac OS x虽然是以图形界面出名的,但是作为一个类Unix系统,还是离不开终端(shell)的,尤其是对于开发人员来说,Mac OS x默认状态的终端给人的感觉总是不那么舒服,所以很有必要对它进行 ...