1、为什么要用MQ?
- 解耦
多个项目之间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败。目的是跟调用接口是一样的,只不过 MQ 可以异步、失败尝试、消息堆积等。
- 异步
生产者发送消息后可以立即返回,不需要等消费者处理业务,不需要阻塞当前线程。
- 削峰/限流
允许消息堆积,避免流量过大导致应用系统挂掉的情况
2、使用消息队列需要注意什么?
- 系统复杂性增加
- 如何保证消息队列是高可用,即做到集群高可用
- 如何保证消费的可靠性传输,即不丢消息
- 如何保证消息不被重复消费,即保证消费的幂等性
- 如何保证消息的顺序性,即保证数据的逻辑正确性
3、架构图
4、NameServer
维持心跳和提供Topic-Broker的关系数据,多个Namesrv之间相互没有通信,单台Namesrv宕机不影响其他Namesrv与集群;
即使整个Namesrv集群宕机,已经正常工作的Producer,Consumer,Broker仍然能正常工作,但新起的Producer, Consumer,Broker就无法工作,Namesrv不会有频繁的读写,所以性能开销非常小,稳定性很高。
5、Broker
Broker与Namesrv的心跳机制:单个Broker跟所有Namesrv保持心跳请求,心跳间隔为30秒,心跳请求中包括当前Broker所有的Topic信息
高可靠并发读写服务:所有发往broker的消息,有同步刷盘和异步刷盘机制,同步刷盘时,消息写入物理文件才会返回成功,因此非常可靠;异步刷盘时,只有机器宕机,才会产生消息丢失,broker挂掉可能会发生,但是机器宕机崩溃是很少发生的,除非突然断电。
负载均衡: Broker上存Topic信息,Topic由多个队列组成,队列会平均分散在多个Broker上,而Producer的发送机制保证消息尽量平均分布到所有队列中,最终效果就是所有消息都平均落在每个Broker上
高可用:集群部署时一般都为主备,Broker名相同的一组Master/Slave Broker,其中包含一个Master Broker(Broker Id为0)和0~N个Slave Broker(Broker Id不为0),备机实时从主机同步消息,如果其中一个主机宕机,备机提供消费服务,但不提供写服务。
6、Producer
Producer启动时,也需要指定Namesrv的地址,从Namesrv集群中选一台Master建立长连接,生产者每30秒从Namesrv获取Topic跟Broker的映射关系,更新到本地内存中。再跟Topic涉及的所有Broker建立长连接
生产者发送时,会自动轮询当前所有可发送的broker,一条消息发送成功,下次换另外一个broker发送,以达到消息平均落到所有的broker上。假如某个Broker宕机,意味生产者最长需要30秒才能感知到。在这期间会向宕机的Broker发送消息。当一条消息发送到某个Broker失败后,会往该broker自动再重发2次,假如还是发送失败,则抛出发送失败异常。业务捕获异常,重新发送即可。客户端里会自动轮询另外一个Broker重新发送,这个对于用户是透明的
消息发送方式分为:同步发送,异步发送,单向发送
7、Consumer
消费者启动时需要指定Namesrv地址,与其中一个Namesrv建立长连接。消费者每隔30秒从nameserver获取所有topic的最新队列情况
Consumer跟Broker是长连接,会每隔30秒发心跳信息到Broker。Broker端每10秒检查一次当前存活的Consumer,若发现某个Consumer 2分钟内没有心跳,就断开与该Consumer的连接,并且向该消费 组的其他实例发送通知,触发该消费者集群的负载均衡。
消费者得到master宕机通知后,转向slave消费(重定向,对于2次开发者透明),但是slave不能保证master的消息100%都同步过来了,因此会有少量的消息丢失。但是消息最终不会丢的,一旦master恢复,未同步过去的消息会被消费掉。
消费分为:集群消费和广播消费
8、Topic+Queue
topic的逻辑存储模型:
如果各Master Broker有Slave Broker,Slave Broker中的结构和其对应的Master Broker完全相同。
Topic是逻辑概念,对于RocketMQ,一个Topic可以分布在各个Broker上,把一个Topic分布在一个Broker上的子集定义为一个Topic分片,其实就是在某一broke上一个topic的部分数据
Queue 存在的意义:每个Topic分片等分的Queue的数量可以不同,由用户在创建Topic时指定, 是消费负载均衡过程中资源分配的基本单元.
9、RocketMQ存储的特点
1、Broker单个实例下所有的队列共用一个日志数据文件(即为CommitLog)来存储
2、consumerQueue 是个消费的逻辑队列,保存了数据在CommitLog中的offset
3.、消费读取数据,需要先读取consumerQueue,再读取CommitLog,消息主体都是通过CommitLog来进行读写.
由于Consume Queue存储数据量极少, 而且是顺序读, 在PAGECACHE预读作用下, Consume Queue的读性能几乎与内存一致, 即使堆积情况下. 所以可认为Consume Queue完全不会阻碍读性能
RocketMQ可以严格的保证消息有序。但这个顺序,不是全局顺序,只是分区(queue)顺序。要全局顺序只能一个分区
RocketMQ不保证消息不重复,如果你的业务需要保证严格的不重复消息,需要你自己在业务端去重
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏