1、RocketMQ简单介绍
RocketMQ主要由NameServer、Broker、Producer以及Consumer四部分构成,如下图所示
所有的集群都具有水平扩展能力,无单点障碍。
NameServer以轻量级的方式提供服务发现和路由功能,每个NameServer存有全量的路由信息,提供对等的读写服务,支持快速扩缩容。
Broker负责消息存储,以Topic为纬度支持轻量级的队列,单机可以支撑上万队列规模,支持消息推拉模型,具备多副本容错机制(2副本或3副本)、强大的削峰填谷以及上亿级消息堆积能力,同时可严格保证消息的有序性。除此之外,Broker还提供了同城异地容灾能力,丰富的Metrics统计以及告警机制。这些都是传统消息系统无法比拟的。
Producer由用户进行分布式部署,消息由Producer通过多种负载均衡模式发送到Broker集群,发送低延时,支持快速失败。
Consumer也由用户部署,支持PUSH和PULL两种消费模式,支持集群消费和广播消息,提供实时的消息订阅机制,满足大多数消费场景。
2、RocketMQ中的专业术语
Topic
topic表示消息的第一级类型,比如一个电商系统的消息可以分为:交易消息、物流消息...... 一条消息必须有一个Topic。
Tag
Tag表示消息的第二级类型,比如交易消息又可以分为:交易创建消息,交易完成消息..... 一条消息可以没有Tag。RocketMQ提供2级消息分类,方便大家灵活控制。
Queue
一个topic下,我们可以设置多个queue(消息队列)。当我们发送消息时,需要要指定该消息的topic。RocketMQ会轮询该topic下的所有队列,将消息发送出去。
Producer 与 Producer Group
Producer表示消息队列的生产者。消息队列的本质就是实现了publish-subscribe模式,生产者生产消息,消费者消费消息。所以这里的Producer就是用来生产和发送消息的,一般指业务系统。
Producer Group是一类Producer的集合名称,这类Producer通常发送一类消息,且发送逻辑一致。
Consumer 与 Consumer Group
消息消费者,一般由后台系统异步消费消息。
Push Consumer
Consumer 的一种,应用通常向 Consumer 对象注册一个 Listener 接口,一旦收到消息,Consumer 对象立刻回调 Listener 接口方法。
Pull Consumer
Consumer 的一种,应用通常主动调用 Consumer 的拉消息方法从 Broker 拉消息,主动权由应用控制。
Consumer Group是一类Consumer的集合名称,这类Consumer通常消费一类消息,且消费逻辑一致。
Broker
消息的中转者,负责存储和转发消息。可以理解为消息队列服务器,提供了消息的接收、存储、拉取和转发服务。broker是RocketMQ的核心,它不不能挂的,所以需要保证broker的高可用。
广播消费
一条消息被多个Consumer消费,即使这些Consumer属于同一个Consumer Group,消息也会被Consumer Group中的每个Consumer都消费一次。在广播消费中的Consumer Group概念可以认为在消息划分方面无意义。
集群消费
一个Consumer Group中的Consumer实例平均分摊消费消息。例如某个Topic有 9 条消息,其中一个Consumer Group有 3 个实例(可能是 3 个进程,或者 3 台机器),那么每个实例只消费其中的 3 条消息。
NameServer
NameServer即名称服务,两个功能:
- 接收broker的请求,注册broker的路由信息
- 接口client的请求,根据某个topic获取其到broker的路由信息
NameServer没有状态,可以横向扩展。每个broker在启动的时候会到NameServer注册;Producer在发送消息前会根据topic到NameServer获取路由(到broker)信息;Consumer也会定时获取topic路由信息。
3、Producer最佳实践
1、一个应用尽可能用一个 Topic,消息子类型用 tags 来标识,tags 可以由应用自由设置。只有发送消息设置了tags,消费方在订阅消息时,才可以利用 tags 在 broker 做消息过滤。
2、每个消息在业务层面的唯一标识码,要设置到 keys 字段,方便将来定位消息丢失问题。由于是哈希索引,请务必保证 key 尽可能唯一,这样可以避免潜在的哈希冲突。
3、消息发送成功或者失败,要打印消息日志,务必要打印 sendresult 和 key 字段。
4、对于消息不可丢失应用,务必要有消息重发机制。例如:消息发送失败,存储到数据库,能有定时程序尝试重发或者人工触发重发。
5、某些应用如果不关注消息是否发送成功,请直接使用sendOneWay
方法发送消息。
4、Consumer最佳实践
1、消费过程要做到幂等(即消费端去重)
2、尽量使用批量方式消费方式,可以很大程度上提高消费吞吐量。
3、优化每条消息消费过程
5、其他配置
线上应该关闭autoCreateTopicEnable
,即在配置文件中将其设置为false
。
RocketMQ在发送消息时,会首先获取路由信息。如果是新的消息,由于MQServer上面还没有创建对应的Topic
,这个时候,如果上面的配置打开的话,会返回默认TOPIC的(RocketMQ会在每台broker
上面创建名为TBW102
的TOPIC)路由信息,然后Producer
会选择一台Broker
发送消息,选中的broker
在存储消息时,发现消息的topic
还没有创建,就会自动创建topic
。后果就是:以后所有该TOPIC的消息,都将发送到这台broker
上,达不到负载均衡的目的。
所以基于目前RocketMQ的设计,建议关闭自动创建TOPIC的功能,然后根据消息量的大小,手动创建TOPIC。
本文部分内容摘自:http://www.jianshu.com/p/453c6e7ff81c