《第一章》
NameServer的优点: | NameServer取代zookeeper作为信息管理的注册中心,NameServer实现元数据的管理(topic路由信息等),topic路由信息无须在集群之间保持强一致,只是最终一致性,并且能容忍分钟级的不一致。基于这种特点,RocketMQ的NameServer集群之间互不通信,这样极大的降低了NameServer实现的复杂度,对网络的要求也减低了很多,性能比zookeeper好很多。 |
高性能的原因: | 高效的IO存储机制,RocketMQ为了达到搞吞吐量,消息存储文件被设计成文件组的概念,组内单个文件的大小固定,方便引入内存映射机制,所有主题的消息存储被顺序编写,极大的提升了消息的写性能。同时为了兼顾消息消费与消息查找,引入了消息消费队列文件与索引文件。 |
如何保证消息一定能被消息消费者消费,且仅被消费一次:RocketMQ只保证消息被消费者消费,在设计上允许消息被重复消费。简化了消息中间件的内核,消息重复消费由消费者在消费消息时实现幂等。
RocketMQ含概:
架构模式 | 采用发布订阅模式,主要组件:消息发送者,消息服务器(消息存储),消息消费,路由发现 |
顺序消息 | 顺序消息即消费者按照消息达到消息存储服务器的顺序消费,RocketMQ可以严格保证消息有序 |
消息过滤 | 消息过滤是指在消费时,消费者可以对同一主题下的消息按照规则只消费自己感兴趣的消息。RocketMQ消息过滤是由消费端和服务端共同完成的。 |
消息存储 | 消息存储分两个维度考虑:消息堆积能力和消息存储性能。 RocketMQ最求消息存储的高性能,引入内存映射机制,所有主题的消息按顺序存储在同一个文件中。同时为了避免消息在消息存储服务器中无限累计,引入了消息文件过期机制于文件存储空间报警机制。 |
消息 高可用性 |
影响高可用的场景: 1.broker异常崩溃 2.操作系统崩溃 3.机器断电,但是能立即恢复供电 4.机器无法开机(可能是CPU,主板,内存等关键设备损坏) 5.磁盘设备损坏 注意: 对于前3种情况,RocketMQ在同步刷盘模式下可以确保不丢失消息,在异步刷盘模式下,会丢失少量消息。 对于后两种情况,属于单点故障,一旦发生,该节点上的消息全部丢失,如果开启了异步复制机制,RocketMQ能保证只丢失少量消息 |
消息到达(消费)低延迟 | RocketMQ在消息不发生堆积时,以长轮询模式实现准实时的消息推送模式 |
确保消息必须被消费一次 | RocketMQ通过消息消费确认机制ACK确保消息至少被消费一次,因为ACK消息有可能出现丢失等情况,RocketMQ无法做到消息只被消费一次,所以有重复消费的可能。 |
回溯消息 | 指的是消费端已经消费成功,根据业务要求,需要重新消费消息。RocketMQ支持按时间向前或向后回溯消息,时间维度可精确到毫秒。 |
消息堆积 | 消息中间件的主要功能是异步解耦,流量削峰,提高后端系统的可用性,要求消息中间件具备一定的消息堆积能力。RocketMQ使用磁盘文件存储消息(内存映射机制),并且在物理布局上为多个大小相等的文件组成逻辑文件组,可以无限循环使用。RocketMQ消息存储文件不是永久存储在消息服务器端的,而是提供了过期机制,默认保留3天。 |
定时消息 | 定时消息是指消息发送到broker后,不能被消费端立即消费,而是要等到特定的时间点后才能被消费。RocketMQ不支持任意进度的定时消息,支持持特定延时级别。 原因:如果要支持任意精度的定时消息消费,就必须在消息服务端对消息进行排序,这带来很大的性能损耗。 |
消息重试机制 | RocketMQ支持消息重试机制。消息重试是指在消费时如果发生异常,消费中间件支持消息重新投递。 |
《第二章》
nameServer机构设计是基于主题的订阅发布机制,生产者发送某一主题的消息到达消息服务器,消息服务器负责改消息的持久化存储,消费者订阅主题,消息服务器根据订阅信息(路由信息)将消息推送给消费者(推模式)或者消费者主动向消息服务器拉取消息(拉模式),从而实现消息生产者和消费者的解耦。为了避免因消息服务器的单点故障导致的整个系统瘫痪,通常会部署多态消息服务器共同承担消息的存储。nameServer为了解决上述而设计的。
broker消息服务器在启动时向所有nameServer注册,生产者在发送消息之前先从nameServer获取broker服务器的地址列表,然后根据负载均衡算法从列表中选择一台消息服务器发送消息。nameServer和每台broker服务器保持长连接,并间隔10s检测broker是否存活,如果检测到broker宕机,则从路由注册表中将其移除,但是路由变化不会马上通知生产者。这是为了降低nameServer实现的复杂度,所以需要在消息发送端提供容错机制来保证消息发送的高可用性。
nameServer本身的高可用性可通过部署多台nameServer服务器来实现,但彼此之间互不通信。淡然nameServer服务器之间在某一时刻的数据并不会完全相同,但对消息发送不会造成重大影响,不过就是短暂造成消息发送不均衡。
nameServer核心架构:
1.broker每隔30s向nameServer集群的每一台机器发送心跳包,包含自身创建的topic路由等信息。 |
2.消息客户端每隔30s向nameServer更新对应topic的路由信息。 |
3.nameServer收到broker发送的心跳包时会记录时间戳 |
4.nameServer每隔10s会扫描一次brokerLiveTable(存放心跳包的时间戳信息),如果在120s内没有收到心跳包,则认为broker失效,更新topic的路由信息,将失效的broker信息移除。 |
rocketmqHome | rocketMQ主目录,通过-Docketmq.home.dir=path或设置环境变量ROCKETMQ_HOME可以配置RocketMQ的主目录 |
kvConfigPath | nameServer存储KV配置属性的持久化路径 |
configStorePath | nameServer默认配置文件路径,nameServer启动时如果要通过配置文件配置nameServer启动属性,请使用-c选项 |
orderMessageEnable | 是否支持顺序消息,默认是不支持 |
listenPort | nameServer监听端口,默认9876 |
serverWorkerThreads | Netty业务线程池线程个数 |
serverCallBackExecutorThreads | Netty public任务线程池线程个数。Netty网络会根据业务类型创建不同的线程池,比如处理消息发送,消息消费,心跳检测等。如果该业务类型requestCode未注册线程池,则由public线程池执行 |
serverSelectorThreads | IO线程池线程个数,主要是nameServer,broker端解析请求,返回相应的线程个数。这类线程主要用于处理网络请求,先解析请求包,然后转发到各个业务线程池完成具体的业务操作,最后将结果返回给调用方。 |
serverOnewaySemaphoreValue | send oneway消息请求的并发度 |