基本概念
topic:消息主题,通过 Topic 对不同的业务消息进行分类。
tag:消息标签,用来进一步区分某个 Topic 下的消息分类,消息从生产者发出即带上的属性。
keys:代表这条消息的业务关键词
body:表示消息的存储内容
顺序消息
对于一个指定的Topic,消息严格按照先进先出(FIFO)的原则进行消息发布和消费,即先发布的消息先消费,后发布的消息后消费。
RocketMQ 消息的顺序性分为两部分,生产顺序性和消费顺序性。只有同时满足了生产顺序性和消费顺序性才能达到上述的FIFO效果。
生产顺序性: RocketMQ 通过生产者和服务端的协议保障单个生产者串行地发送消息,并按序存储和持久化。如需保证消息生产的顺序性,则必须满足以下条件:
单一生产者: 消息生产的顺序性仅支持单一生产者,不同生产者分布在不同的系统,即使设置相同的分区键,不同生产者之间产生的消息也无法判定其先后顺序。
串行发送:生产者客户端支持多线程安全访问,但如果生产者使用多线程并行发送,则不同线程间产生的消息将无法判定其先后顺序。
例如创建订单的场景,需要保证同一个订单的生成、付款和发货,这三个操作被顺序执行。如果是普通消息,订单A的消息可能会被轮询发送到不同的队列中,不同队列的消息将无法保持顺序,而顺序消息发送时将ShardingKey相同(同一订单号)的消息序路由到一个逻辑队列中。
延迟消息
当消息写入到Broker后,不能立刻被消费者消费,需要等待指定的时长后才可被消费处理的消息
Rocket MQ延时消息的延迟时长不支持随意时长的延迟,是通过特定的延迟等级来指定的。默认支持18个等级的延迟消息
例如指定的延时等级为2,则表示延迟时长为5s,延时等级为3,则表示延迟时长为10s,即延迟等级是从1开始计数的。
延迟消息使用场景
- 在电商交易系统中,像淘宝、京东,我们提交了一个订单之后,在支付时都会
提示,需要在指定时间内(例如30分钟)完成支付,否则订单将被取消的消息,
实际上这个超时未支付功能就可以使用延时消息来实现。在下单成功之后,就
发送一个延时消息,然后指定消息的延时时间为30分钟,这条消息将会在30
分钟后投递给后台业务系统(Consumer),此时才能被消费者进行消费,消
费消息的时候会再去检查这个订单的状态,确认下是否支付成功,如果支付成
功,则忽略不处理;如果订单还是未支付,则进行取消订单、释放库存等操
作;
- 比如B站视频投稿经常会发起一些活动,Up主在活动期间可以按照活动规则投
稿视频,在活动时间截止后,后台根据Up主完成任务的情况以及结合投稿视频
的播放量等进行判定,然后派发对应的奖励。这种场景我们也可以采用延时消
息来实现,即在发起活动后,同时发送一条延时消息,延时时间设置为本次活
动周期的时间。当活动结束后,这条延时消息刚好可以被消费者进行消费,这
样就可以消费消息然后执行一系列的逻辑处理。
RocketMq中提供两种消费模式:集群模式和广播模式
集群模式表示同一个消息会被同一个消费组中的消费者消费一次,消息被负载均衡分配到同一个消费者上的多个实例上。
广播模式表示同一个消息会推送到集群里面所有的消费者,保证消息至少被每个消费者消费一次。
并发消费和顺序消费
在并发消费中,可能会有多个线程同时消费一个队列的消息,因此即使发送端通过发送顺序消息保证消息在同一个队列中按照FIFO的顺序,也无法保证消息实际被顺序消费。实现了MessageListenerConcurrently接口
顺序消费是指消息按照一定的顺序进行处理,同一个消息队列上的消息按照发送顺序和消费顺序进行处理。
顺序消费通常需要保证同一消息队列上只有一个消费者实例处理消息,以确保消息的顺序性。实现了MessageListenerOrderly接口
其他
- NameServer:NameServer 是一个非常简单的 Topic 路由注册中心,是一个无状态的服务器,角色类似于 Kafka 使用的 Zookeeper,但比 Zookeeper 更轻量。支持 Broker 的动态注册与发现。
- Broker:初始化加载本地配置,配置信息是以json格式存储在本地, rocketmq强依赖fastjson作转换, 通过ConfigMananger来管理配置加载以及持久化,主要负责消息的存储、投递和查询以及服务高可用保证。