核心概念
- Topic:消息主题,一级消息类型,生产者向其发送消息。
- Message:生产者向Topic发送并最终传送给消费者的数据消息的载体。
- 消息属性:生产者可以为消息定义的属性,包含Message Key和Tag。
- Message Key:消息的业务标识,由消息生产者(Producer)设置,唯一标识某个业务逻辑。
- Message ID:消息的全局唯一标识,由消息队列RocketMQ系统自动生成,唯一标识某条消息。
- Tag:消息标签,二级消息类型,用来进一步区分某个Topic下的消息分类
- Producer:也称为消息发布者,负责生产并发送消息至Topic。
- Consumer:也称为消息订阅者,负责从Topic接收并消费消息。
- 分区:即Topic Partition,物理上的概念。每个Topic包含一个或多个分区。
- 消费位点:每个Topic会有多个分区,每个分区会统计当前消息的总条数,这个称为最大位点 MaxOffset;分区的起始位置对应的位置叫做起始位点MinOffset。
- Group:一类生产者或消费者,这类生产者或消费者通常生产或消费同一类消息,且消息发布或订
阅的逻辑一致。 - Group ID:Group的标识。
- 队列:每个Topic下会有一到多个队列来存储消息。
- 定时消息:Producer将消息发送到消息队列RocketMQ服务端,但并不期望这条消息立马投递,而是推迟到在当前时间点之后的某一个时间投递到Consumer进行消费,该消息即定时消息。
- 延时消息:Producer将消息发送到消息队列RocketMQ服务端,但并不期望这条消息立马投递,而是延迟一定时间后才投递到Consumer进行消费,该消息即延时消息。
- 事务消息:RocketMQ提供类似X/Open XA的分布事务功能,通过消息队列RocketMQ的事务消息能达到分布式事务的最终一致。
- 顺序消息:RocketMQ提供的一种按照顺序进行发布和消费的消息类型,分为全局顺序消息和分区顺序消息。
- 全局顺序消息:对于指定的一个Topic,所有消息按照严格的先入先出(FIFO)的顺序进行发布和消费。
- 分区顺序消息:对于指定的一个Topic,所有消息根据Sharding Key进行区块分区。同一个分区内的消息按照严格的FIFO顺序进行发布和消费。Sharding Key是顺序消息中用来区分不同分区的关键字段,和普通消息的Message Key是完全不同的概念。
- 消息堆积:Producer已经将消息发送到消息队列RocketMQ的服务端,但由于Consumer消费能力有限,未能在短时间内将所有消息正确消费掉,此时在消息队列RocketMQ的服务端保存着未被消费的消息,该状态即消息堆积。
- 消息过滤:Consumer可以根据消息标签(Tag)对消息进行过滤,确保Consumer最终只接收被过滤后的消息类型。消息过滤在消息队列RocketMQ的服务端完成。
- 消息轨迹:在一条消息从Producer发出到Consumer消费处理过程中,由各个相关节点的时间、地点等数据汇聚而成的完整链路信息。通过消息轨迹,您能清晰定位消息从Producer发出,经由消息队列RocketMQ服务端,投递给Consumer的完整链路,方便定位排查问题。
- 死信队列:死信队列用于处理无法被正常消费的消息。当一条消息初次消费失败,消息队列RocketMQ会自动进行消息重试;达到最大重试次数后,若消费依然失败,则表明Consumer在正常情况下无法正确地消费该消息。此时,消息队列RocketMQ不会立刻将消息丢弃,而是将这条消息发送到该Consumer对应的特殊队列中。为死信队列(Dead-Letter Queue)。
同步消息
发送同步消息是指producer向 broker 发送消息,执行 API 时同步等待,
直到broker 服务器返回发送结果;
RocketMQTemplate 给我们提供了syncSend方法(有多个重载),来实现发送同步消息;
异步消息
发送异步消息是指producer向 broker 发送消息时指定消息发送成功及发送异常的
回调方法,调用 API后立即返回,producer发送消息线程不阻塞 ,消息发送成功
或失败的回调任务在一个新的线程中执行
RocketMQTemplate 给我们提供了asyncSend方法(有多个重载),来实现发送异步消息;
public void sendAsyncMessage() {
for (int i = 0; i < 10; i++) {
rocketMQTemplate.asyncSend("java1234-rocketmq", "rocketmg异步消息!" + i, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("发送成功之后回调执行!");
}
@Override
public void onException(Throwable throwable) {
System.out.println("发送失败之后回调执行!");
}
});
}
}
单向消息
发送单向消息是指producer向 broker 发送消息,执行 API 时直接返回,不等待broker
服务器的结果。这种方式主要用在不特别关心发送结果的场景,举例:日志发送;
RocketMQTemplate 给我们提供了sendOneWay方法(有多个重载),来实现发送单向消息
模式区分
每个消费者,都会消费消息
MessageModel.BROADCASTING 是广播模式
每一个消息只会被某一个消费者消费一次;
MessageModel.CLUSTERING 是默认集群负载均衡模式
顺序消息
- syncSendOrderly,发送同步顺序消息
- asyncSendOrderly,发送异步顺序消息;
- sendOneWayOrderly,发送单向顺序消息;
消费端修改线程接收方式:
默认并发多线程去接收消息(是ConsumeMode.CONCURRENTLY)
修改为单线程顺序接收消息(ConsumeMode.ORDERLY)
延迟消息
对于消息中间件来说,producer 将消息发送到mq的服务器上,但并不希望这条消息
马上被消费,而是推迟到当前时间节点之后的某个时间点,再将消息投递到 queue
中让 consumer 进行消费。
延迟等级
messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m
20m 30m 1h 2h
事务消息
- Half(Prepare) Message——半消息(预处理消息)
半消息是一种特殊的消息类型,该状态的消息暂时不能被Consumer消费。
当一条事务消息被成功投递到Broker上,但是Broker并没有接收到Producer
发出的二次确认时,该事务消息就处于"暂时不可被消费"状态,
该状态的事务消息被称为半消息。
- Message Status Check——消息状态回查
由于网络抖动、Producer重启等原因,可能导致Producer向Broker发送的二次确认消息
没有成功送达。如果Broker检测到某条事务消息长时间处于半消息状态,
则会主动向Producer端发起回查操作,查询该事务消息在Producer端的事务状态
(Commit 或 Rollback)。可以看出,Message Status Check主要
用来解决分布式事务中的超时问题。
public void sendTransactionMessage() {
Message msg = MessageBuilder.withPayload("rocketmq事务消息-01").build();
rocketMQTemplate.sendMessageInTransaction("java1234-transaction- rocketmq", msg, null);
}
@RocketMQTransactionListener
class TransactionListenerImpl implements RocketMQLocalTransactionListener {
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
System.out.println("executeLocalTransaction");
return RocketMQLocalTransactionState.UNKNOWN;
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
System.out.println("checkLocalTransaction");
return RocketMQLocalTransactionState.COMMIT;
}
}
生产者端发送half消息到MQ-SERVER,然后异步执行executeLocalTransaction方法
xecuteLocalTransaction 的返回有三种状态,bollback , commit or unknown 三种,
分别是回滚事务,提交事务和未知;根据事务消息执行流程,
如果返回bollback,则直接丢弃消息;
如果是返回commit,则消费消息;
如果是unknow,则继续等待,然后调用checkLocalTransaction方法,
最多重试15次,超过了默认丢弃此消息
checkLocalTransaction 方法返回值和xecuteLocalTransaction 一样,如果此方法有
响应,再根据此方法的返回值进行后续操作。
MQ-SERVER得到commit后,消费端才可以消费消息;
消息过滤
消息发送端只能设置一个tag,消息接收端可以设置多个tag
public void sendMessageWithTag() {
Message msg1 = MessageBuilder.withPayload("rocketmq过滤消息测试- TAG01").build();
Message msg2 = MessageBuilder.withPayload("rocketmq过滤消息测试- TAG02").build();
Message msg3 = MessageBuilder.withPayload("rocketmq过滤消息测试- TAG03").build();
rocketMQTemplate.convertAndSend("java1234-filter-rocketmq" + ":" + "TAG1", msg1);
rocketMQTemplate.convertAndSend("java1234-filter-rocketmq" + ":" + "TAG2", msg2);
rocketMQTemplate.convertAndSend("java1234-filter-rocketmq" + ":" + "TAG3", msg3);
}