一:消息发送
过程:
- producer根据不同场景发送不同的消息,如顺序消息,事务消息等,默认使用DefaultMQProducer,发送需要经过五个步骤:
- 设置groupName,相同的groupName会分在一个组
- 设置instanceName, 如果一个jvm上需要启动多个实例,需要instanceName来区分。默认为"DEFAULT"
- 设置nameServer地址,从nameServer获取topic所在的broker地址
- 组装消息并发送
消息返回状态:
- FLUSH_DISK_TIMEOUT: 同步刷盘超时(broker的刷盘策略为SYNC_FLUSH时才会报这个错)
- FLUSH_SLAVE_TIMEOUT: 主备模式下,主从复制超时(需要master实例设置为同步复制:SYNC_MASTER)
- SLAVE_NOT_AVAILABLE: 主备模式下,主从复制没有可用的slave(需要master实例设置为同步复制:SYNC_MASTER)
- SEND_OK:发送成功
如何提升消息发送的性能:
- 如果对可靠性不要求,可以使用Oneway的方式。 只管发送到服务器,不需要应答。
- 增加producer实例,增大并发数量(不用担心多个同时写入会降低写磁盘的效率,rocket引入了一个并发窗口,消息是并发写入DirectMem中,而后使用异步方式刷盘)。
- 采用顺序写commitLog可以保持高性能。
broker配置:
二:消息消费
消息消费的几个要点:
- 消费方式: pull和push
- 消费模式: 广播和集群
- 流量控制: 可结合sentinel
- 消息过滤: Tag
- 并发线程设置
- 消息积压:
- 优化系统逻辑,提升消费速度
- 增加单个consumer的并行处理的线程数(修改consumeThreadMin和consumeThreadMax)
- 增加group内的consumer实例数量,但是不要超过topic下的Read Queue数量,因为超过的实例不能接收到消息
- 批量方式消费消息(修改consumeMessageBatchMaxSize,默认1)。 这个要看场景,如果场景不需要立即消费消息,可以批量来处理
- 丢弃不重要的消息
三:消息存储
消息存储结构
文件系统:rocket刷盘采用的是机器的文件系统来做持久化。 目前的高性能磁盘,顺序写速度可达600MB/s,超过一般网卡传输速度,随机写只有100kb/s,相差6000倍。 而rocket正是采用顺序写。
系统结构:前面我们知道,消息发送到某一个topic,是存在messageQueue中。 而存储实际是使用ConsumeQueue和CommitLog配合完成,每个messageQueue会对应一个从consumerQueue。 当消息路由到messageQueue时,先把消息顺序写到CommitLog中,然后将索引信息写到consumerQueue中,以便消费时从commitLog中快速找到。 具体来看看
- CommitLog:文件名长度为20位,左边补零,剩余为起始偏移量,比如00000000000000000000代表了第一个文件,起始偏移量为0,文件大小为 1G=1073741824;当第一个文件写满了,第二个文件为00000000001073741824,起始偏移量为1073741824,以此类推。
- ConsumeQueue:
- 逻辑队列,目的是提高消费性能,消费时不用去遍历commitLog。
- 存储了消息在commitLog中的偏移量offset,消息大小和Tag的hashCode值 。
- 我们知道,consumerGroup中的每个consumer对应消费一个messageQueue,其实就是对应一个consumerQueue,先读取到索引信息,再去commitLog中找。
四:负载均衡
rocketmq的负载均衡分为producer和consumer端,都是由client端自己实现的策略。 当然,也可由使用者在代码中指定。
producer端:
producer体现在发送消息时,对messageQueue的选择。 它会先根据topic获取TopicPublishInfo信息,里面记录了topic下可选择的messageQueue列表,轮询选择。
consumer端:
- pull consumer可以看到所有的Message Queue,而且从哪个Message Queue读取消息,读消息时的Offset都由使用者控制,使用者可以实现任何特殊方式的负载均衡。
- push consumer: 默认负载均衡策略是AllocateMessageQueueAveragely,每个consumer在启动时,或者group中成员数量发生变化,都会触发doRebalance动作。 此动作分为几步:
- broker实例接收consumer发送的心跳包,返回topic的queue信息(数量,id等),group中的consumer信息等。
- consumer在RebalanceImpl类中,对mq排序和consumer排序,排序后确定那些mq分给那些consumer。
- 根据当前的consumer的id,返回其消费的queue
五:消息重试
producer端的重试:
//同步发送消息,如果5秒内没有发送成功,则重试5次 DefaultMQProducer p