RocketMQ相关知识知多少(一):https://developer.aliyun.com/article/1534543
1.PushConsumer:高度封装的消费类型,消费消息仅仅通过通过消费监听器监听并返回结果。 消息的获取、消费状态提交以及消费重试都通过 RocketMQ 的客户端 SDK 完成。
- 返回消费成功:以 Java SDK 为例,返回,表示该消息处理成功,服务端按照消费结果更新消费进度。CosumeResult.SUCCESS
- 返回消费失败:以 Java SDK 为例,返回,表示该消息处理失败,需要根据消费重试逻辑判断是否进行重试消费。ConsumeResult.FAILURE
- 出现非预期失败:例如抛异常等行为,该结果按照消费失败处理,需要根据消费重试逻辑判断是否进行重试消费。
使用 PushConsumer 消费者消费时,不允许使用以下方式处理消息,否则 RocketMQ 无法保证消息的可靠性。
- 错误方式一:消息还未处理完成,就提前返回消费成功结果。 此时如果消息消费失败,RocketMQ 服务端是无法感知的,因此不会进行消费重试。
- 错误方式二:在消费监听器内将消息再次分发到自定义的其他线程,消费监听器提前返回消费结果。 此时如果消息消费失败,RocketMQ 服务端同样无法感知,因此也不会进行消费重试。
PushConsumer 严格限制了消息同步处理及每条消息的处理超时时间,适用于以下场景:
- 消息处理时间可预估:如果不确定消息处理耗时,经常有预期之外的长时间耗时的消息,PushConsumer 的可靠性保证会频繁触发消息重试机制造成大量重复消息。
- 无异步化、高级定制场景:PushConsumer 限制了消费逻辑的线程模型,由客户端 SDK 内部按最大吞吐量触发消息处理。 该模型开发逻辑简单,但是不允许使用异步化和自定义处理流程。
2.简单消费者:SimpleConsumer 是一种接口原子型的消费者类型,消息的获取、消费状态提交以及消费重试都是通过消费者业务逻辑主动发起调用完成。
- SimpleConsumer 适用于以下场景:
- 消息处理时长不可控:如果消息处理时长无法预估,经常有长时间耗时的消息处理情况。 建议使用 SimpleConsumer 消费类型,可以在消费时自定义消息的预估处理时长,若实际业务中预估的消息处理时长不符合预期,也可以通过接口提前修改。
- 需要异步化、批量消费等高级定制场景:SimpleConsumer 在 SDK 内部没有复杂的线程封装,完全由业务逻辑自由定制,可以实现异步分发、批量消费等高级定制场景。
- 需要自定义消费速率:SimpleConsumer 是由业务逻辑主动调用接口获取消息,因此可以自由调整获取消息的频率,自定义控制消费速率。
五、消费者过滤
消费者订阅了某个主题后,Apache RocketMQ 会将该主题中的所有消息投递给消费者。若消费者只需要关注部分消息,可通过设置过滤条件在 Apache RocketMQ 服务端进行过滤,只获取到需要关注的消息子集,避免接收到大量无效的消息。【使用 Apache RocketMQ 的消息过滤功能,可以帮助消费者更高效地过滤自己需要的消息集合,避免大量无效消息投递给消费者,降低下游系统处理压力。】
过滤的含义指的是将符合条件的消息投递给消费者,而不是将匹配到的消息过滤掉。
Apache RocketMQ 的消息过滤功能通过生产者和消费者对消息的属性、标签进行定义,并在 Apache RocketMQ 服务端根据过滤条件进行筛选匹配,将符合条件的消息投递给消费者进行消费。
消息过滤主要通过以下几个关键流程实现:
- 生产者:生产者在初始化消息时预先为消息设置一些属性和标签,用于后续消费时指定过滤目标。
- 消费者:消费者在初始化及后续消费流程中通过调用订阅关系注册接口,向服务端上报需要订阅指定主题的哪些消息,即过滤条件。
- 服务端:消费者获取消息时会触发服务端的动态过滤计算,Apache RocketMQ 服务端根据消费者上报的过滤条件的表达式进行匹配,并将符合条件的消息投递给消费者。
RocketMQ 支持Tag标签过滤和SQL属性过滤,这两种过滤方式对比如下:
六、消费重试
消费重试指的是,消费者在消费某条消息失败后,Apache RocketMQ 服务端会根据重试策略重新消费该消息,超过一定次数后若还未消费成功,则该消息将不再继续重试,直接被发送到死信队列中。
消息重试的触发条件
- 消费失败,包括消费者返回消息失败状态标识或抛出非预期异常。
消息处理超时,包括在PushConsumer中排队超时。
消息重试策略主要行为
- 重试过程状态机:控制消息在重试流程中的状态和变化逻辑。
- 重试间隔:上一次消费失败或超时后,下次重新尝试消费的间隔时间。
- 最大重试次数:消息可被重试消费的最大次数。
消息重试策略差异
根据消费者类型不同,消息重试策略的具体内部机制和设置方法有所不同,具体差异如下:
PushConsumer消费消息时,消息的几个主要状态如下:
- Ready:已就绪状态。消息在Apache RocketMQ服务端已就绪,可以被消费者消费。
- Inflight:处理中状态。消息被消费者客户端获取,处于消费中还未返回消费结果的状态。
- WaitingRetry:待重试状态,PushConsumer独有的状态。当消费者消息处理失败或消费超时,会触发消费重试逻辑判断。如果当前重试次数未达到最大次数,则该消息变为待重试状态,经过重试间隔后,消息将重新变为已就绪状态可被重新消费。多次重试之间,可通过重试间隔进行延长,防止无效高频的失败。
- Commit:提交状态。消费成功的状态,消费者返回成功响应即可结束消息的状态机。
- DLQ:死信状态。消费逻辑的最终兜底机制,若消息一直处理失败并不断进行重试,直到超过最大重试次数还未成功,此时消息不会再重试,会被投递至死信队列。您可以通过消费死信队列的消息进行业务恢复。
SimpleConsumer消费消息时,消息的几个主要状态如下:
- Ready:已就绪状态。消息在Apache RocketMQ服务端已就绪,可以被消费者消费。
- Inflight:处理中状态。消息被消费者客户端获取,处于消费中还未返回消费结果的状态。
- Commit:提交状态。消费成功的状态,消费者返回成功响应即可结束消息的状态机。
- DLQ:死信状态。消费逻辑的最终兜底机制,若消息一直处理失败并不断进行重试,直到超过最大重试次数还未成功,此时消息不会再重试,会被投递至死信队列。您可以通过消费死信队列的消息进行业务恢复。