kafka多线程实现消费者实战

前言:KafkaProducer是线程安全的,但是KafkaConsumer不是线程安全的,同一个KafkaConsumer用在了多个线程中,将会报Kafka Consumer is not safe for multi-threaded assess异常。可以加一个同步锁进行保护。

所以KafkaConsumer在多线程的环境下,我们使用KafkaConsumer的实例要小心,应该每个消费数据的线程拥有自己的KafkaConsumer实例。

1:每个Consumer有自己的线程,consumer去拉取数据,并对数据处理,这种方式比较简单,易于实现,容易保持对消息的顺序处理
2:消费者/处理者方式,创建一个线程池,在consumer拉取数据后,由线程池中的线程来处理数据,把拉取数据与处理数据解耦,但数据处理有可能破坏partition的消息顺序

两种方式的区别:第一种注重消息消费顺序但消费速度不如第二种,第二种注重消费速度但不注重消费顺序。在实际项目种可跟据实际情况选择。

实战背景:项目需要通过kafka的方式接收PaaS平台的告警数据,每分钟的接受量在1000+,目前kafka消费者实例数和分区数都是3,但是由于接收到消息后处理逻辑较为复杂,在优化后有时仍存在消息积压,所以需要在kafka消费处加入多线程进行处理。

多线程处理代码如下,这里使用的上述方式2,因为本处逻辑对消息顺序并不关注:

Thread thread = new Thread(){
			   public void run(){


					KafkaConsumer<String, String> consumer = null;
					while (true) {
						try {
							consumer = new KafkaConsumer<>(props);
							consumer.subscribe(Collections.singletonList(PaasConstant.topic));

							// 创建线程池
							ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 105, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue(1000));
							Integer index = 1;

							// 监听某个topic
							while (true) {
								logger.debug("--------start------监听kafka--topic----" + PaasConstant.topic);
								ConsumerRecords<String, String> records = consumer.poll(1000);
								logger.debug("开始消费 " + PaasConstant.topic + "中的数据 ");
								for (ConsumerRecord<String, String> record : records) {
									// 处理数据,发请求
									try {
										// 加入线程池操作
										pool.execute(new ThreadTaskCustomerKafka(record,index.toString()));
										index++;
										logger.debug("======线程"+index+"加入线程池======");

									
									} catch (Exception ex) {
										logger.debug(PaasConstant.topic + "   处理数据异常======" + record.value(), ex);
									}
								}
								Thread.sleep(300);
								logger.debug("--------准备下次监听kafka--topic----" + PaasConstant.topic);
							}

//							pool.shutdown();
						} catch (Exception e) {

							try {
								Thread.sleep(1000);
							} catch (InterruptedException e1) {
								logger.error(PaasConstant.topic + "===Thread.sleep(1000);===" , e1);
							}
							logger.error(PaasConstant.topic + "   处理数据异常======" , e);
						}
					}
				   
				   
				   
				   
			   }
			};
thread.start();

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值