solon 整合 kafka-clients

带刺的坐椅發表於2024-12-06

使用 kafka-clients 原本是比較簡單的事情。但有些同學習慣了 spring-kafka 後,對原始 java 介面會陌生些。會希望有個整合的示例。

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>${kafka.version}</version>
</dependency>

現在我們使用原始 sdk 的依賴包,做一個 solon 專案的整合分享(其它的框架,也可以參考此例)。

1、新增整合配置

使用 Solon 初始器 生成一個 Solon Web 模板專案,然後新增上面的 kafka-clients 依賴。之後:

  • 新增 yml 配置(具體的配置屬性,參考:ProducerConfig,ConsumerConfig)
solon.app:
  name: "demo-app"
  group: "demo"

solon.logging:
  logger:
    root:
      level: INFO

# 配置可以自由定義,與 @Bean 程式碼對應起來即可(以下為參考)
solon.kafka:
  properties:  #公共配置(配置項,參考:ProducerConfig,ConsumerConfig 的公用部分)
    bootstrap:
      servers: "127.0.0.1:9092"
    key:
      serializer: "org.apache.kafka.common.serialization.StringSerializer"
      deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
    value:
      serializer: "org.apache.kafka.common.serialization.StringSerializer"
      deserializer: "org.apache.kafka.common.serialization.StringDeserializer"
  producer: #生產者專屬配置(配置項,參考:ProducerConfig)
    acks: "all"
  consumer: #消費者專屬配置(配置項,參考:ConsumerConfig)
    enable:
      auto:
        commit: "false"
    isolation:
      level: "read_committed"
    group:
      id: "${solon.app.group}:${solon.app.name}"
  • 新增 java 配置器
@Configuration
public class KafkaConfig {
    @Bean
    public KafkaProducer<String, String> producer(@Inject("${solon.kafka.properties}") Properties common,
                                             @Inject("${solon.kafka.producer}") Properties producer) {

        Properties props = new Properties();
        props.putAll(common);
        props.putAll(producer);

        return new KafkaProducer<>(props);
    }

    @Bean
    public KafkaConsumer<String, String> consumer(@Inject("${solon.kafka.properties}") Properties common,
                                                  @Inject("${solon.kafka.consumer}") Properties consumer) {
        Properties props = new Properties();
        props.putAll(common);
        props.putAll(consumer);

        return new KafkaConsumer<>(props);
    }
}

完成上面兩步,就算是整合了(後面,是應用的事兒)。配置也可以沒有,直接寫程式碼設定屬性。

2、應用

  • 傳送(或生產),這裡代控制器由使用者請求再傳送訊息(僅供參考):
@Controller
public class DemoController {
    @Inject
    private KafkaProducer<String, String> producer;

    @Mapping("/send")
    public void send(String msg) {
        //傳送
        producer.send(new ProducerRecord<>("topic.test", msg));
    }
}
  • 拉取(或消費),這裡採用定時攔取方式:(僅供參考)

這裡需要引入一個 solon 的簡單排程外掛(或,別的排程外掛),用於定時拉取訊息:

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-scheduling-simple</artifactId>
</dependency>

編寫定時拉取任務:

@Component
public class DemoJob {
    @Inject
    private KafkaConsumer<String, String> consumer;

    @Init
    public void init() {
        //訂閱
        consumer.subscribe(Arrays.asList("topic.test"));
    }

    @Scheduled(fixedDelay = 10_000L, initialDelay = 10_000L)
    public void job() throws Exception {
        //拉取
        ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(10));
        for (ConsumerRecord<String, String> record : records) {
            System.out.println(record.value());
            //確認
            consumer.commitSync();
        }
    }
}

相關文章