Kafka消费与心跳机制

1.概述

最近有同学咨询Kafka的消费和心跳机制,今天笔者将通过这篇博客来逐一介绍这些内容。

2.内容

2.1 Kafka消费

首先,我们来看看消费。Kafka提供了非常简单的消费API,使用者只需初始化Kafka的Broker Server地址,然后实例化KafkaConsumer类即可拿到Topic中的数据。一个简单的Kafka消费实例代码如下所示:

复制代码

public class JConsumerSubscribe extends Thread {
    public static void main(String[] args) {
        JConsumerSubscribe jconsumer = new JConsumerSubscribe();
        jconsumer.start();
    }

    /** 初始化Kafka集群信息. */
    private Properties configure() {
        Properties props = new Properties();
        props.put("bootstrap.servers", "dn1:9092,dn2:9092,dn3:9092");// 指定Kafka集群地址
        props.put("group.id", "ke");// 指定消费者组
        props.put("enable.auto.commit", "true");// 开启自动提交
        props.put("auto.commit.interval.ms", "1000");// 自动提交的时间间隔
        // 反序列化消息主键
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        // 反序列化消费记录
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        return props;
    }

    /** 实现一个单线程消费者. */
    @Override
    public void run() {
        // 创建一个消费者实例对象
        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(configure());
        // 订阅消费主题集合
        consumer.subscribe(Arrays.asList("test_kafka_topic"));
        // 实时消费标识
        boolean flag = true;
        while (flag) {
            // 获取主题消息数据
            ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
            for (ConsumerRecord<String, String> record : records)
                // 循环打印消息记录
                System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
        }
        // 出现异常关闭消费者对象
        consumer.close();
    }
}

复制代码

上述代码我们就可以非常便捷的拿到Topic中的数据。但是,当我们调用poll方法拉取数据的时候,Kafka Broker Server做了那些事情。接下来,我们可以去看看源代码的实现细节。核心代码如下:

org.apache.kafka.clients.consumer.Ka

### Kafka消费者配置实现重试机制的最佳实践 #### 配置参数设置 对于Kafka消费者而言,确保消息能够被可靠地消费至关重要。为此,合理的参数配置必不可少。`max.poll.interval.ms` 参数决定了消费者在两次调用 `poll()` 方法之间允许的最大间隔时间[^4]。当处理逻辑较为复杂耗时较长的情况下,应适当增加此值以防止不必要的再平衡操作。 另一个关键参数是 `session.timeout.ms` ,它用于定义消费心跳超时时长,在集群检测到某成员未按期发送心跳即视为离线并启动再均衡过程前等待的时间长度。通常建议将其设为小于 `max.poll.interval.ms` 的数值来保障及时响应的同时不影响正常工作流程。 针对可能出现的消息重复投递情况,可以通过调整 `enable.auto.commit=false` 并手动控制提交偏移量的方式增强应用层面的一致性处理能力;同时利用幂等生产者特性减少因网络抖动等原因造成的冗余记录写入问题[^1]。 ```yaml spring: kafka: consumer: enable-auto-commit: false max-poll-interval-ms: 300000 # 设置更长时间避免频繁rebalance session-timeout-ms: 20000 # 较短的心跳超时时间保持敏感度 ``` #### 实现重试机制 为了有效应对临时性的错误状况(如短暂的服务不可达),可以在业务逻辑层面上加入适当的异常捕获和有限次数内的自动重试策略: - **本地缓存待发消息**:一旦遇到可预见的瞬态故障,则立即将当前批次中的所有条目暂存在内存队列里而不立即丢弃; - **指数退避算法**:每次尝试失败后按照一定倍率延长下次执行间的延时期望值直至达到最大限定阈值为止; - **死信队列支持**:经过多次努力仍无法成功传递的信息最终会被转发至专门设立的主题保存起来供后续分析排查之用[^2]。 ```java import org.apache.kafka.clients.consumer.ConsumerRecord; import java.util.concurrent.TimeUnit; public class RetryableMessageProcessor { private static final int MAX_RETRIES = 5; // 最大重试次数 private static final long RETRY_DELAY_MS = 100L;// 初始延迟毫秒数 public void process(ConsumerRecord<String, String> record) throws Exception { boolean success = false; int attemptCount = 0; while (!success && ++attemptCount <= MAX_RETRIES){ try{ // 尝试处理接收到的数据... Thread.sleep(TimeUnit.MILLISECONDS.toMillis(RETRY_DELAY_MS * Math.pow(2 , (double)(attemptCount - 1)))); success=true; }catch(Exception e){ System.err.println("Processing failed on attempt " + attemptCount); if(attemptCount >= MAX_RETRIES){ throw new RuntimeException("Max retries exceeded",e); } } } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿小乙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值