Kafka学习(一):消费者实现对分区的并发消费

本文介绍了如何使用Spring-Kafka实现Kafka消费者的并发消费,特别是针对单个分区的并发处理。通过线程封闭策略,创建多个消费者线程并根据分区数动态调整并发度。此外,文章探讨了多线程消息处理以提高消费能力,以及在手动提交消费位移时可能遇到的消息丢失问题,并推荐了《深入理解Kafka:核心设计与实践原理》一书作为进一步学习的资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明

在上篇博文《springboot学习(十七):了解spring - kafka配置工作原理》中,我们简单了解了spring-kafka的配置工作原理。通过源码可以看到spring在实现并发消费时,采用的是线程封闭的策略,也就是一个groupid中,根据配置的concurrency来创建多个消费者线程,每个消费者消费一个或多个分区,来实现整个topic消息的消费处理。本篇博文将对上篇博文中最后提出的问题 ----- 如何对单个分区实现并发消费? 通过代码演示,解答该问题。

正文

spring的线程封闭策略

在spring中实现消息的并发消费采用的是线程封闭的策略,具体实现是在创建监听器容器时,会根据配置的concurrency来创建多个KafkaMessageListenerContainer,在该类中又有内部类ListenerConsumer,在该内部类中封闭创建了consumer对象。以此来实现主题消息的并发消费。
在这里插入图片描述
注意,以这种方式进行并发消费时,实际的并发度受到了主题分区数的限制,当消费线程数大于分区数时,会使多出来的消费者线程一直处于空闲状态。对此,spring在创建KafkaMessageListenerContainer前,对用户配置的concurrency值进行了校验,当该值超出主题分区数时,将值设置为实际的分区数。

TopicPartitionInitialOffset[] topicPartitions = containerProperties.getTopicPartitions();
if (topicPartitions != null && this.concurrency > topicPartitions.length) {
    this.logger.warn("When specific partitions are provided, the concurrency must be less than or equal to the number of partitions; reduced from " + this.concurrency + " to " + topicPartitions.length);
    this.concurrency = topicPartitions.length;
}

同时,以线程封闭的方式实现并发消费,每个消费者线程都需要保持一个TCP连接,如果分区数很大,则会带来很大的系统开销。但是,以该方式实现并发消费,可以保证每个分区消息的顺序消费。

通过KafkaConsumer的消费模式我们可以看到,消费者需要不断的从服务器拉取(poll)消息进行处理,如果消息处理的速度越快,则拉取的频次越高,整体的消费能力越强。所以整体的消费速度在于消息处理模块的速度。我们可以将这个模块改为多线程的处理方式,来提高整体的消费能力。


多线程处理

通过将消息拉取动作和处理动作分开,将处理模块改为多线程的处理方式来提升消息的处理速度,进而提升整体的消费能力。
在这里插入图片描述
以上图示,将主题对应的消费者组进行池化,每个group对应一个consumer线程池,池中线程数为主题的分区数。每个消费者是个线程,提交到consumer线程池后,不断从服务器拉取消息,同时在消费者线程中,又有一个用来实际处理消息的MessageHandler线程池,在获取的消息后,根据每批次的消息创建MessagedoHandle线程,提交到handler线程池进行消息的实际处理。

KafaManager

依据以上原理创建KafaManager类,通过该类可以进行消息的发送和消费者的订阅。KafkaProducer是线程安全的,所以在该类中依据配置创建一个单例的KafkaProducer对象。对于消费者的订阅,通过该类提供的subscribe方法,用户可以自定义消息的处理方式,要订阅的主题,groupid,clientid,消息处理线程池的线程数等参数。

KafkaP
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值