kafka多线程消费的两种方式

本文介绍了Kafka多线程消费的两种方式:一是使用多个消费者实例,每个线程直接处理业务;二是建立一个消费者实例和工作线程池,以实现消费逻辑与业务逻辑分离。方式一实现简单但扩展性差,方式二复杂但易于扩展。同时,文章提到了具体代码实现以及在使用线程池时的注意事项,如线程队列满后的阻塞策略,以及频繁提交offset可能导致的问题。
摘要由CSDN通过智能技术生成

一、两种方式

1、构建多个KafkaConsumer进行消费,消费线程直接处理业务逻辑。
优势:代码实现简单,可采用自动提交
劣势:消费线程数和分区数挂钩,超过分区数的线程不做处理,扩展性差,线程自己处理消费到的消息可能会导致超时,从而造成rebalance
2、构建一个或多个KafkaConsumer实例,每个实例采用worker线程池处理业务逻辑。
优势:消费逻辑和业务逻辑分离,易于横向扩展
劣势:实现较麻烦,难于维护分区内的消息顺序,处理链路变长,导致难以保证提交位移的语义正确性

二、具体代码实现

1、方式一

import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

@Slf4j
public class KafkaConsumerClient {

    private Boolean isRunning;

    private ExecutorService executor;

    private String servers;

    private int sessionTimeout;

    private int maxPollSize;

    private String groupId;

    private String topic;

    private int parallelism;

    public KafkaConsumerClient(String servers, int sessionTimeout, int maxPollSize,
                               String groupId, String topic,
                               boolean isRunning) {
        this.servers = servers;
        this.sessionTimeout = sessionTimeout;
        this.maxPollSize = maxPollSize;
        this.groupId = groupId;
        this.topic = topic;
        this.isRunning = isRunning;
    }

    public KafkaConsumerClient(String servers, String groupId, String topic,
                               boolean isRunning) {
        this(servers, 30000, 100, groupId, topic, isRunning);
    }

    public KafkaConsumerClient() {
    }

    public void init(){
        if(isRunning){
            start(parallelism);
            log.info("the kafka consume client has start!");
        }
    }
    
    public void start(int parallelism) {
        if(parallelism > 0){
            isRunning = true;
            this.parallelism = parallelism;
            executor = Executors.newFixedThreadPool(parallelism);
            IntStream.range(0, parallelism).forEach(i -> {
                executor.submit(new ConsumerRunner("kafka-client-consumer-" + i));
            });
        }else{
            this.parallelism = 0;
        }
    }

    public void stop(){
        isRunning = false;
        this.parallelism = 0;
        if(executor != null){
            executor.shutdown();
            try {
                if(!executor.awaitTermination(10, TimeUnit.SECONDS)) {
                    executor.shutdownNow();
                    log.info("kafka client has stopped!");
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
                log.error("kafka client has stopped! ", e);
            }
        }
    }

    class C
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值