KAFKA 编程

本文介绍了在Kafka集群从2.8升级到2.10版本后,如何使用新版API进行同步消息发送的方法。通过配置KafkaProducer并利用send方法结合Future的get方法,确保了消息发送的成功性和可靠性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kafka版本:2.10-0.10.0.1
API jar包:kafka-clients-0.10.0.1.jar

背景:kafka集群从2.10-0.8.2.1升级到2.10-0.10.0.1后,发现原先使用的写日志到Kafka的API全部被标记成了deprecated的状态

kafka_2.10-0.10.0.1.jar
kafka.javaapi.producer.Producer;
kafka.producer.KeyedMessage;
kafka.producer.ProducerConfig;

查过官方文档,发现从0.8的版本之后,出了一组新的API,用异步方式发送消息,号称性能好过旧的API

kafka-clients-0.10.0.1.jar
org.apache.kafka.clients.producer.KafkaProducer;
org.apache.kafka.clients.producer.Producer;
org.apache.kafka.clients.producer.ProducerConfig;
org.apache.kafka.clients.producer.ProducerRecord;

因为业务需求,我们并不能容忍回写到kafka的日志丢失,因此必须使用同步的方式发送消息。而新的API默认是使用异步方式的,简单研究之后发现,想实现同步方式发送,实现如下:

首先需要定义一个KafkaProducer:

public Producer<Integer, String> initKafkaProducer(String brokerList){
    Properties props = new Properties();

    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, brokerList.substring(1));//格式:host1:port1,host2:port2,....
    props.put(ProducerConfig.BATCH_SIZE_CONFIG, 0);//a batch size of zero will disable batching entirely
    props.put(ProducerConfig.LINGER_MS_CONFIG, 0);//send message without delay
    props.put(ProducerConfig.ACKS_CONFIG, "1");//对应partition的leader写到本地后即返回成功。极端情况下,可能导致失败
    props.put("key.serializer", "org.apache.kafka.common.serialization.IntegerSerializer");
    props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
    Producer<Integer, String> kafkaProducer = new KafkaProducer<Integer, String>(props);
    return kafkaProducer;
}

设置了以上之后,虽然每条消息是被单独发送的,但是,对于send方法的作用,文档中的说明是这样的:

The send is asynchronous and this method will return immediately once the record has been stored in the buffer of records waiting to be sent. This allows sending many records in parallel without blocking to wait for the response after each one. Since the send call is asynchronous it returns a Future for the RecordMetadata that will be assigned to this record. Invoking get() on this future will block until the associated request completes and then return the metadata for the record or throw any exception that occurred while sending the record.

因此,实际上调用send方法并不能保证消息被成功写入到kafka。为了实现同步的发送消息,并监控每条消息是否发送成功,需要对每次调用send方法后返回的Future对象调用get方法。(get方法的调用会导致当前线程block,直到发送结果返回,不管是成功还是失败)

public void send2Kafka(Producer<Integer, String> kafkaProducer, String topic, List<String> lines) throws InterruptedException, ExecutionException{
    for(String line : lines) {
        ProducerRecord<Integer, String> message = new ProducerRecord<Integer, String>(topic, line);
        this.kafkaProducer.send(message).get();
    }
}

当get方法抛出一个错误时,说明数据没有被正确写入,此时需要处理这个错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值