服务热线
135-6963-3175
RocketMq相关概念
NameServer
比起zk更轻量化。nameServer互相独立彼此没有通信关系,单台挂掉不影响其它nameServer。
broker与nameServer:
1.维护了broker的地址列表,broker在启动时候会去nameServer注册,通过netty和broker保持长连接通信,会维护broker的存活状态(通过心跳机制30s向nameServer发送一次,心跳包含自身的topic配置信息)。nameserver每10秒扫描还存活的broker连接
2.维护了一份Topic和Topic缩对应队列的地址列表,broker每次发送心跳过来的时候会把topic信息带上。
producer与nameServer:
producer主要从nameServer获取topic的最新队列情况。producer向提供topic服务的master建立长连接,定时发送心跳。producer向所有master连接,但不能向slave写入。
consumer与nameServer:
consumer主要从nameServer中根据topic查询broker地址并缓存到客户端向提供Topic的master\slave建立长连接,定时发送心跳
综上:
nameServer保存活跃的broker列表,包括master和slave.
nameServer保存所有topic和该topic所有队列的列表。
nameServer用来保存所有broker的Filter列表(consumer->filterserver->broker)
nameServer为客户端,包括生产者、消费组和命令行客户端提供最新的路由信息
Broker
包括master和slave。作为消息的中间媒介,用于消息的接收和被消费端拉取消费。
master一般用于生产者producer的连接写入,slave用于consumer的连接读取消费。
在搭建主从集群时候通过brokerName一致做关联,通过brokerId为0为主,brokerId非0为slave。
Topic
一个Topic是一个主题,一个系统中,可将消息划成Topic,这样将不同的消息发送到不同的queue
Queue
一个Topic下可以设置多个queue(队列是topic的逻辑分区)。queue完全从属于某个特定的topic的。所以发送消息前要知道该消息所属的topic是什么。然后就能知道topic下有几个queue。(具体发送哪个queue是在producer做的而不是消息服务器做,可让用户自己决定该如何路由消息)
broker、topic和Queue的关系:
Message
消息
key
发送了某个消息,但是希望在后台很方便的搜索到,就要通过key了。可以根据key搜索到所有相关的Message。
多个用空格隔开,RocketMQ可以根据这些key快速检索到消息对消息关键字的提取方便查询,
比如一条消息某个关键字是 运单号,之后我们可以使用这个运单号作为关键字进行查询
tags
用于消息分组的过滤,默认为*
Producer
用于消息的生产发送
Consumer
用于消息的消费,把queue里面的消息拿出来用。定位:Topic+Tag
Consumer Group
一组具有相同消费行为的客户端。 消费者分组:为实现集群消费。一个消费者分组中包含了一些消费者,如果这些消费者要集群消费,那这些消费者会平均消费该分组中的消息
模式
负载均衡(集群消费)和广播模式
集群消费
指一个consumer group下的consumer,平均消费topic下的queue。
建议:
我们应该尽量让consumer group下的consumer的数目和topic的queue的数目一致或成倍数关系。这样每个consumer消费的queue的数量总是一样的,这样每个consumer服务器的压力才会差不多。当前前提是这个topic下的每个queue里的消息的数量总是差不多多的。这点我们可以对消息根据某个用户自己定义的key来进行hash路由来保证。
广播消费
指一个consumer只要订阅了某个topic的消息,就会收到该topic下所有queue里的消息,不管这个consumer的group是什么
注意:对于广播消费来说,consumer group没什么实际意义。consumer可以在实例化时,我们可以指定是集群消费还是广播消费。
消费进度
当一个消费组里的consumer消费某个queue里的消息时,equeue通过记录消费位置(offset)来知道当前消费到哪里了。以便该consumer重启后继续从该位置开始消费
比如一个topic有4个queue,一个consumer group有4个consumer,则每个consumer分配到一个queue,然后每个consumer分别消费自己的queue里的消息。equeue会分别记录每个consumer对其queue的消费进度,从而保证每个consumer重启后知道下次从哪里开始继续消费。实际上,也许下次重启后不是由该consumer消费该queue了,而是由group里的其他consumer消费了,这样也没关系,因为我们已经记录了这个queue的消费位置了。所以可以看出,消费位置和consumer其实无关,消费位置完全是queue的一个属性,用来记录当前被消费到哪里了。
注意:
一个topic可以被多个consumer group里的consumer订阅。不同consumer group里的consumer即便是消费同一个topic下的同一个queue,那消费进度也是分开存储的。也就是说,不同的consumer group内的consumer的消费完全隔离,彼此不受影响。
对于集群消费和广播消费,消费进度持久化的地方是不同的,集群消费的消费进度是放在broker,也就是消息队列服务器上的,而广播消费的消费进度是存储在consumer本地磁盘上的。
同一个订阅组内不同Consumer实例订阅不同topic消费混乱问题分析说明
两个应用的消费者使用相同的consumer group,但消费不同的topic,造成两个应用各有一半消息丢失。
原因:offset是共用的,offset只与groupname有关。
顺序消息
可以按照消息的发送顺序来消费(FIFO),rocketmq可严格保证消息有序,分为分区有序或者全局有序。
原理:默认情况消息会轮询方式发送到不同的Queue分区队列,而消费消息的时候从多个queue拉取消息,这种情况发送和消费不能保证顺序。但是如果控制发送的顺序消息只发送到同一queue,消费的时候只从这个queue拉取,则就保证来顺序。(当发送消费参与的queue只有一个则全局有序,若多个queue参与则分区有序,即相对每个queue,消息都是有序的)
消费过程 消息队列负载->消息拉取->消息消费->消息消费进度存储。
支持局部顺序消息消费,也就是保证同一个消息队列上的消息顺序消费
如果要实现某一主题的全局顺序消息消费,可以将该topic主题的队列数设置为1,牺牲高性能和可用性
顺序消息在创建消息队列拉取任务时需要在Broker服务器锁定该消息队列。
MAX_TIME_CONSUME_CONTINUOUSLY:每次消费任务最大持续时间,默认为60s,切换线程
顺序消息消费的并发度为消息队列。也就是一个消息消费队列同一时刻只会被一个消费线程池中一个线程消费。
达到重试次数上限,转移到死信队列,继续后续消息的消费
并发消费
推送消息模式:RocketMQ消息推模式的实现基于拉模式
RocketMQ并没有真正实现推模式,而是消费者主动向消息服务器拉取消息,RocketMQ推模式是循环向消息服务端发送消息拉取请求
单独线程池拉取消息,然后调用监听api接口
单独线程池拉取->内存队列->消息处理线程池处理->移除客户端内存队列消息并更新进度
定时消息
消息发送之后并不立即被消费者消费,而是要等到特定的时间之后才能被消费
不支持任意时间精度定时发送,只支持配置级别的时间默认为"1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h",delayLevel=1表示延迟1s,delayLevel=2表示延迟5s,依次类推。
SCHEDULE_TOPIC_XXXX定时消息主题