首页 > 其他分享 >【博学谷学习记录】超强总结,用心分享|狂野架构Kafka消费安全问题

【博学谷学习记录】超强总结,用心分享|狂野架构Kafka消费安全问题

时间:2022-11-13 23:15:43浏览次数:45  
标签:队列 狂野 Kafka 重试 单线程 死信 线程 消息 超强

Kafka消费安全问题

消费者线程安全问题

首先,kafka 的 Java consumer是单线程的设计,准确来说是双线程,从kafka 0.10.1.0版本开始kafkaConsumer变成了用户主线程和心跳线程的双线程设计

​ 所谓用户主线程,就是你启动Consumer应用程序的main方法的那个线程,而心跳线程(Heartbeat Thread)只负责定期发送心跳给对应的Boroker,以标识消费者应用的存活性,引入心跳线程的目的还有一个:解耦真实的消息处理逻辑与消费者组成员存活性管理。

​ 尽管多了一个心跳线程,但是实际的消息处理还是由主线程完成。所以我们还是可以认为KafkaConsumer是单线程设计的。

为什么采用单线程设计

采用单线程设计的原因:

  1. 新版本Consumer设计了单线程+轮询的机制,这种设计能够较好的实现非阻塞式的消息获取。
  2. 单线程的设计能够简化Consumer端的设计,将处理消息的逻辑是否使用多线程的选择,交由你来决定。
  3. 不论使用那种编程语言,单线程的设计都比较容易实现,并且,单线程设计的Consumer更容易移植到其它语言上。
单线程验证

我们可以使用以下方式进行验证,当一条消息卡住后,检查其他的消息是否能够被消费到

if (record.offset() % 3 == 0) {
    try {
        Thread.sleep(Integer.MAX_VALUE);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
}

我们执行消费者后发现一条消息卡住后就无法就行继续消费了

死信队列&重试队列
死信队列

​ 当一条消息初次消费失败,消息队列 MQ 会自动进行消息重试;达到最大重试次数后,若消费依然失败,则表明消费者在正常情况下无法正确地消费该消息,此时,消息队列 MQ 不会立刻将消息丢弃,而是将其发送到该消费者对应的特殊队列中,这种正常情况下无法被消费的消息称为死信消息(Dead-Letter Message),存储死信消息的特殊队列称为死信队列(Dead-Letter Queue)。

重试队列

​ 与此对应的还有一个“回退队列”的概念,试想如果消费者在消费时发生了异常,那么就不会对这一次消费进行确认(Ack),进而发生回滚消息的操作之后消息始终会放在队列的顶部,然后不断被处理和回滚,导致队列陷入死循环。为了解决这个问题,可以为每个队列设置一个回退队列,它和死信队列都是为异常的处理提供的一种机制保障,实际情况下,回退队列的角色可以由死信队列和重试队列来扮演。

​ 重试队列其实可以看成是一种回退队列,具体指消费端消费消息失败时,为防止消息无故丢失而重新将消息回滚到Broker中。与回退队列不同的是重试队列一般分成多个重试等级,每个重试等级一般也会设置重新投递延时,重试次数越多投递延时就越大。

注意事项

​ Kafka不支持重试机制也就不支持消息重试,也不支持死信队列,因此使用kafka做消息队列时,如果遇到了消息在业务处理时出现异常的场景时,需要额外实现消息重试的功能。

标签:队列,狂野,Kafka,重试,单线程,死信,线程,消息,超强
From: https://www.cnblogs.com/xieshier/p/16887605.html

相关文章