最近正在研究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. Java_02变量、数据类型和运算符

    1.变量命名规则 变量必须以字母.下划线 " _ " 或 " $ " ( " ¥ " ) 符号开头. 变量可以包括数字,但不能以数字开头. ...

  2. vue 在全局设置cookie main.js文件

    //设置cookie Vue.prototype.setCookie=function(cname, cvalue, exdays) { var d = new Date(); d.setTime(d ...

  3. 通过type类型 新建对象

    Activator根System命名空间中的类非常强大. 将参数传递给构造函数等有很多重载.查看以下文档: http://msdn.microsoft.com/en-us/library/system ...

  4. activiti 任务监听参数的配置

    public class TaskListenersImp implements TaskListener { private Expression level; private Expression ...

  5. js正則匹配经纬度(经纬度逗号隔开)

    谷歌坐標:31.2807691689,112.5382624525 高德坐標:31.2807691689,112.5382624525 regexp: {//正则验证 regexp: /^([0-9] ...

  6. PHP中的traits快速入门

    traits 在学习PHP的过程中,我们经常会翻阅PHP的官方手册.一般理解能力强悍的人多阅读几遍便可轻松理解其中要领,但往往更多的初学者对官方文档中寥寥数语的描述难以理解.作为一个曾有同样困扰的人, ...

  7. java.lang.IllegalArgumentException: No enum constant org.apache.ws.commons.schema.XmlSchemaForm.

    一次系统断电维护之后,apache cxf 的 web service 接口调用一直报错: java.lang.IllegalArgumentException: No enum constant o ...

  8. 一个HTTP打趴80%面试者

    面试多年,每当我问起面试者对HTTP的了解时,个个回答令我瞠目结舌,这些开发者都有3-5年的经验.请不要让我叫你野生程序员,是时候了解HTTP了,让我们当个正规军. 起因 面试官:请问你了解HTTP协 ...

  9. PAT 甲级 1035 Password (20 分)

    1035 Password (20 分) To prepare for PAT, the judge sometimes has to generate random passwords for th ...

  10. OPC客户端开发问题总结

    环境准备 采用MatrikonOPC做模拟服务器,注册 OPCDAAuto.dll组件 引用 Interop.OPCAutomation.dll组件.开始开发. 1..new OPCServer()- ...