主题配置和 消息发送(一)KafkaTemplate 的使用

本文详细介绍了如何配置Kafka主题,包括通过KafkaAdmin Bean自动化主题添加,以及在运行时检查和创建主题的方法。此外,重点讲解了KafkaTemplate的使用,包括其简介、配置及异步、同步消息发送的示例,帮助读者掌握Spring Boot应用中发送Kafka消息的技巧。
摘要由CSDN通过智能技术生成

一、主题

1.1、配置主题

  • 在应用程序上下文定义一个 KafkaAdmin Bean, 它可以自动将主题添加到代理。通过这个Bean可以将
    每一个新建的主题 Topic 添加到应用程序上下文中。下面是一个简单的示例:

也可以创建 TopicBuilder 类,使用它创建 Bean 更加简单。

@Bean
public KafkaAdmin admin() {
        Map<String, Object> configs = new HashMap<>();
        configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
        return new KafkaAdmin(configs);
        }

@Bean
public KafkaAdmin.NewTopics topics456() {
        return new NewTopics(
        TopicBuilder.name("defaultBoth")
        .build(),
        TopicBuilder.name("defaultPart")
        .replicas(1)
        .build(),
        TopicBuilder.name("defaultRepl")
        .partitions(3)
        .build());
        }

使用 Spring Boot 时,KafkaAdminbean 会自动注册
默认情况下,代理不可用时会记录一条消息,然后上下文会继续加载。可以以编程方式调用Admin的initialize()方法以稍后重试。
也可将 admin 的fatalIfBrokerNotAvailable属性设置为true。然后上下文无法初始化。

1.2、在运行时检查和创建主题

目前有两种方法来进行操作:

  • createOrModifyTopics
  • describeTopics
    或者使用 AdminClient 来直接使用:
@Autowired
private KafkaAdmin admin;

...

    AdminClient client = AdminClient.create(admin.getConfigurationProperties());
    ...
    client.close();

二、消息发送

2.1、使用 KafkaTemplate

2.1.1、KafkaTemplate 介绍

KafkaTemplate 包装了生产者并提供了将数据发送到 Kafka 主题的便捷方法。

2.1.2、配置 KafkaTemplate

要使用模板,需要配置生产者工厂并在模板的构造函数中提供。

  • 单个生产者配置
@Bean
public ProducerFactory<Integer, String> producerFactory() {
    return new DefaultKafkaProducerFactory<>(producerConfigs());
}

@Bean
public Map<String, Object> producerConfigs() {
    Map<String, Object> props = new HashMap<>();
    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
    props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    return props;
}

@Bean
public KafkaTemplate<Integer, String> kafkaTemplate() {
    return new KafkaTemplate<Integer, String>(producerFactory());
}
  • 多个生产者配置

    使用来自同一工厂的不同生产者配置创建模板,需要覆盖工厂的ProducerConfig属性。

@Bean
public KafkaTemplate<String, String> stringTemplate(ProducerFactory<String, String> pf) {
return new KafkaTemplate<>(pf);
}

@Bean
public KafkaTemplate<String, byte[]> bytesTemplate(ProducerFactory<String, byte[]> pf) {
return new KafkaTemplate<>(pf,
Collections.singletonMap(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class));
}

然后调用 KafkaTemplate 的方法来使用它。

  • 异步消息发布示例
public void sendToKafka(final MyOutputData data) {
    final ProducerRecord<String, String> record = createRecord(data);

    ListenableFuture<SendResult<Integer, String>> future = template.send(record);
    future.addCallback(new KafkaSendCallback<SendResult<Integer, String>>() {

        @Override
        public void onSuccess(SendResult<Integer, String> result) {
            handleSuccess(data);
        }

        @Override
        public void onFailure(KafkaProducerException ex) {
            handleFailure(data, record, ex);
        }

    });
}
  • 阻塞发布示例
public void sendToKafka(final MyOutputData data) {
    final ProducerRecord<String, String> record = createRecord(data);

    try {
        template.send(record).get(10, TimeUnit.SECONDS);
        handleSuccess(data);
    }
    catch (ExecutionException e) {
        handleFailure(data, record, e.getCause());
    }
    catch (TimeoutException | InterruptedException e) {
        handleFailure(data, record, e);
    }
}

ExecutionException 在于 KafkaProducerException 属性 failedProducerRecord 中

2.1.3、发布结果查看

  • 异步

发布成功还是失败可以向侦听器注册回调以异步接收发送结果:

ListenableFuture<SendResult<Integer, String>> future = template.send("topic", 1, "thing");
        future.addCallback(new KafkaSendCallback<Integer, String>() {

@Override
public void onSuccess(SendResult<Integer, String> result) {
        ...
        }

@Override
public void onFailure(KafkaProducerException ex) {
        ProducerRecord<Integer, String> failed = ex.getFailedProducerRecord();
        ...
        }

        });

或者使用 lambda:

ListenableFuture<SendResult<Integer, String>> future = template.send("topic", 1, "thing");
future.addCallback(result -> {
        ...
    }, (KafkaFailureCallback<Integer, String>) ex -> {
            ProducerRecord<Integer, String> failed = ex.getFailedProducerRecord();
            ...
    });
  • 同步

阻塞发送线程等待结果需要调用 future 的 get()方法,可以使用带超时的 get() 方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

timi先生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值