继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Kafka消息丢失学习:新手入门指南

哔哔one
关注TA
已关注
手记 485
粉丝 93
获赞 543
概述

本文详细介绍了Kafka消息丢失的各种场景和原因,包括生产者端、消息在Broker间传递和消费者端的丢失情况。文章还提供了多种解决方法,如确保消息的持久性和配置参数以增强可靠性,并推荐使用工具监控消息状态。此外,文章还分享了实践案例和问题排查步骤,帮助读者更好地理解和解决Kafka消息丢失学习中的问题。

Kafka简介
Kafka的定义

Apache Kafka 是一个分布式的流处理平台,最初由 LinkedIn 创建,后捐赠给了 Apache 软件基金会。Kafka 提供了高吞吐量、持久化消息队列的能力,适用于构建实时数据管道和流处理应用。Kafka 的设计目标是处理大规模的数据流,适用于日志聚合、网站活动跟踪、数据处理管道等方面。

Kafka的核心概念

生产者(Producer)

生产者负责将消息推送到 Kafka 集群中的指定主题(topic)。生产者可以将消息保留在内存缓冲区中,通过批量发送来提高效率。

消费者(Consumer)

消费者从 Kafka 主题中读取消息。消费者需要订阅指定的主题,并从对应的分区中拉取消息。消费者可以组成消费者组,共同消费主题中的消息,实现负载均衡。

主题(Topic)

主题是 Kafka 中消息分类的逻辑命名空间。每个主题可以由多个分区组成,每个分区是一个有序的、不可变的消息序列。

分区(Partition)

分区是主题的物理分片,每个分区都是一个有序的日志文件。分区保证了消息的顺序,允许 Kafka 支持大规模的并行处理。

代理(Broker)

代理是 Kafka 的网络服务器,负责存储和转发消息。每个代理可以管理多个主题的分区,通过网络连接与生产者和消费者通信。

日志(Log)

日志是指 Kafka 存储消息的物理结构。每个分区是一个不可变的日志,消息被追加到日志的末尾。每个消息都有一个唯一的偏移量,用于标识在分区中的位置。

偏移量(Offset)

偏移量是消息在分区中的唯一标识符,用于跟踪消息的消费进度。偏移量是一个单调递增的整数,由代理在写入消息时生成。

Kafka的主要特性
  1. 高吞吐量:Kafka 设计用于处理每秒数千条消息的高吞吐量。
  2. 持久化:消息被持久地存储在磁盘上,保证了消息的可靠传递。
  3. 可靠性:通过消息的有序性和可重复读取,确保消息不丢失或重复。
  4. 水平扩展:Kafka 可以通过增加代理节点来扩展集群容量。
  5. 高可用性:通过复制分区和容错机制实现高可用性。
  6. 多语言支持:支持多种编程语言的客户端,如 Java、Python、C++ 等。
  7. 低延迟:通过批量发送和压缩技术降低延迟。
  8. 容错机制:支持分区复制和故障转移,保证数据的安全性。
Kafka消息流转过程
生产者发送消息

生产者将消息发送到 Kafka 集群中的指定主题(topic)。生产者可以配置消息的序列化方式和发送策略。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        String topic = "test-topic";

        for (int i = 0; i < 100; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "value-" + i);
            producer.send(record);
        }

        producer.close();
    }
}
消息的存储与传递

消息被发送到 Kafka 主题的分区中。每个分区是一个有序的日志文件,消息按照它们被写入的顺序存储。代理负责将消息存储在磁盘上,并在必要时将其传递给消费者。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        String topic = "test-topic";

        for (int i = 0; i < 100; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "value-" + i);
            producer.send(record);
        }

        producer.close();
    }
}
消费者接收消息

消费者从 Kafka 主题的分区中读取消息。消费者需要订阅主题,并指定要消费的分区。消费者可以从代理获取特定偏移量的消息,从而控制消费进度。

示例代码(Java):

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Arrays;
import java.util.Properties;

public class KafkaConsumerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("group.id", "test-group");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Arrays.asList("test-topic"));

        while (true) {
            ConsumerRecord<String, String> record = consumer.poll(100);
            if (record != null) {
                System.out.println("Received message: " + record.value());
            }
        }

        consumer.close();
    }
}
常见的Kafka消息丢失场景
生产者端消息丢失

生产者端消息丢失主要包括以下几种情况:

  • 网络异常:生产者连接到 Kafka 代理时出现网络问题,导致消息未发送成功。
  • Broker 满:代理磁盘空间不足,导致新消息无法写入。
  • Producer 配置问题:生产者未正确配置消息的持久性设置。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("acks", "0"); // 不需要确认

        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        String topic = "test-topic";

        for (int i = 0; i < 100; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "value-" + i);
            producer.send(record);
        }

        producer.close();
    }
}
消息在Broker间传递丢失

消息在 Broker 间传递丢失可能由以下原因引起:

  • Broker 重启或崩溃:代理在消息传递过程中发生故障导致消息丢失。
  • 网络延迟或丢包:代理之间网络通信不稳定导致消息丢失。
  • 数据复制失败:消息复制到备份节点失败。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        String topic = "test-topic";

        for (int i = 0; i < 100; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "value-" + i);
            producer.send(record);
        }

        producer.close();
    }
}
消费者端消息丢失

消费者端消息丢失主要包括以下几种情况:

  • 消费者异常:消费者在读取消息过程中出现异常,导致消息未被消费。
  • 偏移量提交失败:消费者提交偏移量时失败,导致消息重复消费。
  • 消费者组变化:消费者组发生变化,导致消息未被消费或重复消费。

示例代码(Java):

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Arrays;
import java.util.Properties;

public class KafkaConsumerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("group.id", "test-group");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("enable.auto.commit", "false"); // 禁用自动提交

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Arrays.asList("test-topic"));

        while (true) {
            ConsumerRecord<String, String> record = consumer.poll(100);
            if (record != null) {
                System.out.println("Received message: " + record.value());
            }
        }

        consumer.close();
    }
}
解决Kafka消息丢失的方法
确保消息的持久性

为了确保消息的持久性,可以采取以下措施:

  • 设置消息的持久性级别:配置生产者的 acks 参数,以确保消息被写入到至少一个副本。
  • 增加副本数量:通过增加分区的副本数量,提高数据的冗余度和可靠性。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("acks", "all"); // 设置为至少一个副本确认

        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        String topic = "test-topic";

        for (int i = 0; i < 100; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "value-" + i);
            producer.send(record);
        }

        producer.close();
    }
}
配置参数以增强消息的可靠性

可以通过配置 Kafka 的相关参数来增强消息的可靠性:

  • 配置生产者参数:设置 delivery.timeout.ms,以防消息超时丢失。
  • 配置消费者参数:设置 enable.auto.commitauto.commit.interval.ms,以控制偏移量的提交。
  • 配置代理参数:设置 log.flush.interval.mslog.flush.interval.messages,以控制消息的持久化。

示例代码(Java):

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Arrays;
import java.util.Properties;

public class KafkaConsumerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("group.id", "test-group");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("enable.auto.commit", "false"); // 禁用自动提交

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Arrays.asList("test-topic"));

        while (true) {
            ConsumerRecord<String, String> record = consumer.poll(100);
            if (record != null) {
                System.out.println("Received message: " + record.value());
            }
        }

        consumer.close();
    }
}
使用工具监控消息状态

可以通过以下工具来监控 Kafka 的消息状态:

  • Kafka自带的命令行工具:使用 kafka-topics.shkafka-consumer-groups.sh 查看主题和消费者组的状态。
  • 第三方监控工具:使用如 Prometheus + Grafana 或 Kafka Manager 等工具,监控 Kafka 的运行状态和性能指标。
  • 监控代码示例:使用 Java API 监控 Kafka 状态。

示例代码(Java):

import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.admin.NewTopic;
import java.util.Properties;
import java.util.concurrent.ExecutionException;

public class KafkaAdminExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");

        AdminClient adminClient = AdminClient.create(props);

        NewTopic topic = new NewTopic("test-topic")
                .partitions(1)
                .replicas(3)
                .configs(
                        Map.of(
                                "min.insync.replicas", "2",
                                "unclean.leader.election.enable", "false",
                                "retention.bytes", "1048576",
                                "retention.ms", "86400000"
                        )
                );

        adminClient.createTopics(Collections.singletonList(topic));
        adminClient.close();
    }
}
Kafka配置最佳实践
核心参数设定

以下是 Kafka 的一些核心参数设置:

  • acks:指定生产者在发送消息后需要收到的确认数量。acks=0 表示不需要确认,acks=1 表示至少写入到一个副本,acks=all 表示所有副本都写入成功。
  • retries:指定生产者在发送消息失败后重试的次数。
  • batch.size:指定生产者缓存消息的大小,达到该大小时一次性发送。
  • linger.ms:指定生产者缓存消息的时间,超过该时间后发送。
  • compression.type:指定消息的压缩类型,如 gzipsnappy 等。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("acks", "all");
        props.put("retries", 2);
        props.put("batch.size", 16384);
        props.put("linger.ms", 1);
        props.put("compression.type", "gzip");

        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        String topic = "test-topic";

        for (int i = 0; i < 100; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "value-" + i);
            producer.send(record);
        }

        producer.close();
    }
}
消息可靠性设置

为了提高消息的可靠性,可以设置以下参数:

  • request.timeout.ms:指定生产者在等待响应时的超时时间。
  • max.in.flight.requests.per.connection:指定生产者在等待响应时的最大请求数。
  • retry.backoff.ms:指定重试请求之间的间隔时间。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("acks", "all");
        props.put("retries", 2);
        props.put("request.timeout.ms", 30000);
        props.put("max.in.flight.requests.per.connection", 5);
        props.put("retry.backoff.ms", 100);

        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        String topic = "test-topic";

        for (int i = 0; i < 100; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "value-" + i);
            producer.send(record);
        }

        producer.close();
    }
}
容错机制配置

为了提高 Kafka 集群的容错能力,可以配置以下参数:

  • min.insync.replicas:指定最少需要多少个副本在线,才能认为消息写入成功。
  • unclean.leader.election.enable:指定在领导者故障时,是否允许从不干净的副本选举新的领导者。
  • retention.bytes:指定每个分区的最大保留数据量。
  • retention.ms:指定每个分区的数据保留时间。

示例代码(Java):

import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.admin.NewTopic;
import java.util.Properties;
import java.util.concurrent.ExecutionException;

public class KafkaAdminExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");

        AdminClient adminClient = AdminClient.create(props);

        NewTopic topic = new NewTopic("test-topic")
                .partitions(1)
                .replicas(3)
                .configs(
                        Map.of(
                                "min.insync.replicas", "2",
                                "unclean.leader.election.enable", "false",
                                "retention.bytes", "1048576",
                                "retention.ms", "86400000"
                        )
                );

        adminClient.createTopics(Collections.singletonList(topic));
        adminClient.close();
    }
}
实践案例与问题排查
模拟消息丢失场景

为了模拟消息丢失场景,可以设置生产者和消费者的配置,使其故意失败。例如,设置生产者的 acks0,模拟消息未被写入的情况;或者设置消费者的 enable.auto.commitfalse,模拟消息未被提交的情况。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("acks", "0"); // 不需要确认

        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        String topic = "test-topic";

        for (int i = 0; i < 100; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "value-" + i);
            producer.send(record);
        }

        producer.close();
    }
}
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Arrays;
import java.util.Properties;

public class KafkaConsumerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("group.id", "test-group");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("enable.auto.commit", "false"); // 禁用自动提交

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Arrays.asList("test-topic"));

        while (true) {
            ConsumerRecord<String, String> record = consumer.poll(100);
            if (record != null) {
                System.out.println("Received message: " + record.value());
            }
        }

        consumer.close();
    }
}
实际问题排查步骤

在排查 Kafka 消息丢失问题时,可以按照以下步骤进行:

  1. 检查生产者和消费者的配置:确保生产者和消费者的配置正确,特别是消息的持久性和可靠性设置。
  2. 查看 Kafka 日志:通过查看 Kafka 代理的日志,了解是否有异常信息或错误提示。
  3. 检查 Kafka 状态:使用 Kafka 提供的命令行工具或第三方监控工具,检查 Kafka 的运行状态和性能指标。
  4. 测试模拟场景:模拟消息丢失场景,通过测试来验证问题是否复现。
  5. 分析日志和指标:通过日志和监控指标,分析问题的原因。

示例代码(Java):

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Arrays;
import java.util.Properties;

public class KafkaConsumerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("group.id", "test-group");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("enable.auto.commit", "false"); // 禁用自动提交

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Arrays.asList("test-topic"));

        while (true) {
            ConsumerRecord<String, String> record = consumer.poll(100);
            if (record != null) {
                System.out.println("Received message: " + record.value());
            }
        }

        consumer.close();
    }
}
常见问题及解决方案

问题1:生产者发送的消息未被接收

原因:生产者未正确配置确认参数(acks),或者消费者未订阅对应的主题。

解决方案:确保生产者设置 acks=all,并且消费者订阅了对应的主题。

示例代码(Java):

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("acks", "all"); // 设置为至少一个副本确认

        KafkaProducer<String, String> producer = new KafkaProducer<>(props);
        String topic = "test-topic";

        for (int i = 0; i < 100; i++) {
            ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "value-" + i);
            producer.send(record);
        }

        producer.close();
    }
}

问题2:消费者未消费到所有消息

原因:消费者未正确提交偏移量,导致消息被重复消费。

解决方案:确保消费者启用自动提交(enable.auto.commit=true),或者手动提交偏移量。

示例代码(Java):

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Arrays;
import java.util.Properties;

public class KafkaConsumerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("group.id", "test-group");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("enable.auto.commit", "true"); // 启用自动提交

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Arrays.asList("test-topic"));

        while (true) {
            ConsumerRecord<String, String> record = consumer.poll(100);
            if (record != null) {
                System.out.println("Received message: " + record.value());
            }
        }

        consumer.close();
    }
}

问题3:消息在 Broker 间传递丢失

原因:Broker 之间网络通信出现问题,或者数据复制失败。

解决方案:检查 Broker 之间的网络连接,并确保数据复制成功。

示例代码(Java):

import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.admin.NewTopic;
import java.util.Properties;
import java.util.concurrent.ExecutionException;

public class KafkaAdminExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");

        AdminClient adminClient = AdminClient.create(props);

        NewTopic topic = new NewTopic("test-topic")
                .partitions(1)
                .replicas(3)
                .configs(
                        Map.of(
                                "min.insync.replicas", "2",
                                "unclean.leader.election.enable", "false",
                                "retention.bytes", "1048576",
                                "retention.ms", "86400000"
                        )
                );

        adminClient.createTopics(Collections.singletonList(topic));
        adminClient.close();
    }
}

问题4:消费者异常导致消息丢失

原因:消费者在读取消息过程中发生异常,导致未成功提交偏移量。

解决方案:确保消费者能够正确处理异常,并进行适当的错误恢复。

示例代码(Java):

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Arrays;
import java.util.Properties;

public class KafkaConsumerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("group.id", "test-group");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("enable.auto.commit", "true"); // 启用自动提交

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Arrays.asList("test-topic"));

        while (true) {
            ConsumerRecord<String, String> record = consumer.poll(100);
            if (record != null) {
                System.out.println("Received message: " + record.value());
            }
        }

        consumer.close();
    }
}

通过以上介绍和示例代码,希望能够帮助大家更好地理解和解决 Kafka 消息丢失问题。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP