Kafka01-Kafka生产者发送消息方式(发送即忘、同步、异步)

目录

生产者的三种发送消息方式

发后即忘(Fire-and-Forget)可能丢数据的情况

重要参数讲解

同步发送和异步发送的可靠性

异常处理

性能与可靠性的平衡

最佳实践


生产者的三种发送消息方式

Kafka 生产者是 Kafka 系统中用来发布消息到 Kafka 集群的组件。Kafka 生产者提供了三种主要的消息发送方式,分别是:

  1. 发送即忘(Fire-and-Forget): 这种方式是最简单的发送模式,生产者发送消息后不会等待任何确认,直接继续发送下一条消息。这种方式的优点是性能最高,因为它不需要等待服务器的响应。但缺点是如果消息发送失败,生产者不会得到通知,因此无法进行重试或错误处理。

  2. 同步发送(Synchronous Send): 在同步发送模式下,生产者在发送消息后会等待服务器的确认。如果消息被成功接收,服务器会返回一个确认响应,生产者收到响应后才会继续发送下一条消息。这种方式确保了消息的可靠性,但可能会因为等待确认而牺牲一些性能。

  3. 异步发送(Asynchronous Send): 异步发送结合了发送即忘和同步发送的特点。生产者在发送消息后不会立即等待服务器的确认,而是继续发送下一条消息。生产者可以注册一个回调函数,当消息被成功发送或发送失败时,回调函数会被调用。这种方式可以在不牺牲性能的情况下提供一定的消息可靠性。

下面是使用 Java 编写的 Kafka 生产者示例代码,演示了这三种发送方式:

这段代码首先配置了 Kafka 生产者的属性,然后创建了一个生产者实例。接着,它演示了三种发送方式:发送即忘、同步发送和异步发送。在异步发送的例子中,我们注册了一个回调函数来处理消息发送成功或失败的情况。最后,代码关闭了 Kafka 生产者以释放资源。


public class KafkaProducerExample {
    public static void main(String[] args) {
        // 配置 Kafka 生产者
        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");

        // 创建 Kafka 生产者实例
        Producer<String, String> producer = new KafkaProducer<>(props);

        // 定义要发送的消息
        String topic = "test-topic";
        String message = "Hello, Kafka!";

        // 发送即忘模式
        System.out.println("Sending message in fire-and-forget mode...");
        producer.send(new ProducerRecord<>(topic, message));

        // 同步发送模式
        System.out.println("Sending message in synchronous mode...");
        try {
            producer.send(new ProducerRecord<>(topic, message)).get();
            System.out.println("Message sent successfully in synchronous mode.");
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 异步发送模式
        System.out.println("Sending message in asynchronous mode...");
        producer.send(new ProducerRecord<>(topic, message), new Callback() {
            @Override
            public void onCompletion(RecordMetadata metadata, Exception e) {
                if(e != null) {
                    System.out.println("Error while sending message in asynchronous mode.");
                    e.printStackTrace();
                } else {
                    System.out.println("Message sent successfully in asynchronous mode. " +
                           "Topic: " + metadata.topic() + ", Partition: " + metadata.partition() +
                           ", Offset: " + metadata.offset());
                }
            }
        });

        // 关闭 Kafka 生产者
        producer.close();
    }
}

在 Kafka 生产者中,确实存在一些关键参数和概念,它们对消息的发送方式和性能有着重要的影响。以下是对您提供内容的进一步解释和补充:

发后即忘(Fire-and-Forget)可能丢数据的情况

  • 可重试异常:如 NetworkExceptionLeaderNotAvailableException 或 NotCoordinatorException。Kafka 生产者内置了自动重试机制,并且可以通过 ProducerConfig.RETRIES_CONFIG 配置重试次数。如果异常在重试次数耗尽前得到解决,消息不会丢失。否则,如果异常持续存在,消息可能会丢失。
  • 不可重试异常:如 RecordTooLargeException。当消息大小超过 max.request.size 时,即使重试也不会成功,且在发后即忘模式下,生产者不会抛出异常,导致无法知道消息是否发送成功。

重要参数讲解

  • batch.size:控制 ProducerBatch 的大小,默认为 16KB。增加此值可以在一次网络请求中发送更多消息,提高吞吐量。
  • linger.ms:设置生产者在发送消息前等待的额外时间,默认为 0。增加此值可以等待更多消息累积到 ProducerBatch 中,减少网络请求次数,但会增加消息延迟。
  • retries:设置生产者在消息发送失败时的重试次数,增加重试次数可以提高消息发送的成功率。

同步发送和异步发送的可靠性

  • 同步发送:通过 send().get() 等待服务器响应,如果发送失败,可以捕获异常并进行处理,提高了消息的可靠性,但可能会降低性能。
  • 异步发送:通过回调函数处理消息发送成功或失败的情况,可以在不阻塞主线程的情况下提高性能。回调函数在生产者的主线程中执行,因此必须确保执行速度足够快,避免阻塞。

异常处理

  • 可重试异常:如果重试次数耗尽且异常未解决,需要在外层逻辑中捕获异常,并进行适当的错误处理,如记录异常信息。
  • 不可重试异常:如消息大小超过 max.request.size,需要捕获 RecordTooLargeException 并进行处理,例如记录错误或尝试将数据发送到其他 Topic。

性能与可靠性的平衡

  • 在选择发送方式时,需要根据业务需求平衡性能和可靠性。如果消息的可靠性至关重要,可以选择同步发送或异步发送并妥善处理异常。如果性能是主要考虑因素,且可以容忍一定程度的消息丢失,可以选择发后即忘的方式。

最佳实践

  • 合理配置 batch.size 和 linger.ms,以优化吞吐量和延迟。
  • 在异步发送中,确保回调函数执行迅速,避免阻塞生产者主线程。
  • 对于重要的业务场景,考虑实现重试机制和异常日志记录,以提高消息的可靠性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值