[英]spring-kafka - how to read one topic from the beginning, while reading another one from the end?
我正在編寫一個 spring-kafka 應用程序,其中我需要閱讀 2 個主題:test1 和 test2:
public class Receiver {
private static final Logger LOGGER = LoggerFactory
.getLogger(Receiver.class);
@KafkaListener(id = "bar", topicPartitions =
{ @TopicPartition(topic = "test1", partitions = { "0" }),
@TopicPartition(topic = "test2", partitions = { "0" })})
public void receiveMessage(String message) {
LOGGER.info("received message='{}'", message);
}
}
我的配置如下所示:
@Configuration
@EnableKafka
public class ReceiverConfig {
@Value("${kafka.bootstrap.servers}")
private String bootstrapServers;
@Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> props = new HashMap<>();
// list of host:port pairs used for establishing the initial connections
// to the Kakfa cluster
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
bootstrapServers);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
IntegerDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
StringDeserializer.class);
// consumer groups allow a pool of processes to divide the work of
// consuming and processing records
props.put(ConsumerConfig.GROUP_ID_CONFIG, "test1");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "test2");
return props;
}
@Bean
public ConsumerFactory<Integer, String> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(consumerConfigs());
}
@Bean
public ConcurrentKafkaListenerContainerFactory<Integer, String> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
return factory;
}
@Bean
public Receiver receiver() {
return new Receiver();
}
}
我需要能夠僅讀取“test1”中的最新消息,同時能夠讀取“test2”開頭的所有消息。 我只對應用程序啟動時的“test2”消息感興趣,但只要應用程序正在運行,就需要不斷地閱讀“test1”消息。
有沒有辦法配置這樣的功能?
我也一直在努力解決這個問題,並想提出一個更通用的解決方案。
當您的解決方案有效時,您需要對分區進行硬編碼。 您還可以讓使用@KafkaListener
的 class 實現ConsumerSeekAware
接口。
這為您提供了三種可用於尋找特定偏移量的方法。 一旦分配了分區,就會調用一種方法。 所以它可能看起來像這樣。
@Override
public void onPartitionsAssigned(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
assignments.keySet().stream()
.filter(partition -> "MYTOPIC".equals(partition.topic()))
.forEach(partition -> callback.seekToBeginning("MYTOPIC", partition.partition()));
}
這樣,當您決定向主題添加更多分區時,您無需接觸任何代碼:)
希望這可以幫助某人。
這是一種對我有用的方法:
@KafkaListener(id = "receiver-api",
topicPartitions =
{ @TopicPartition(topic = "schema.topic",
partitionOffsets = @PartitionOffset(partition = "0", initialOffset = "0")),
@TopicPartition(topic = "data.topic", partitions = { "0" })})
public void receiveMessage(String message) {
try {
JSONObject incomingJsonObject = new JSONObject(message);
if(!incomingJsonObject.isNull("data")){
handleSchemaMessage(incomingJsonObject);
}
else {
handleDataMessage(incomingJsonObject);
}
} catch (Exception e) {
e.printStackTrace();
}
使用“partitionOffsets”注解(import org.springframework.kafka.annotation.PartitionOffset;)
是能夠始終從頭開始閱讀特定主題的關鍵,同時像往常一樣“跟蹤”其他主題。
您可以瀏覽文檔 #4.1.7 。 幾種方法之一是在“最早”或“最新”上更改您的消費者屬性 auto.offset.reset:
...
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
...
然后,您可以創建任意數量的 @KafkaListener ,它將從開始讀取。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.