Broker: Unknown topic or partition 问题解决

./kafka-console-producer.sh --broker-list XXX:9092 --topic kafka_test < ttt.txt
报错:Broker: Unknown topic or partition
生产者端失败重试
配置重试参数:在Kafka生产者的配置中,可以设置retries和retry.backoff.ms参数来启用重试机制。
异步发送与回调:使用异步发送消息,并在回调中处理发送失败的情况。
异常处理:在回调中对异常进行分类处理,对于可恢复的错误进行重试,对于不可恢复的错误进行日志记录或报警。
幂等性:确保生产者发送消息的逻辑是幂等的,即使消息被重复发送也不会影响系统状态。
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”);
props.put(“retries”, 3); // 设置重试次数
props.put(“retry.backoff.ms”, 1000); // 设置重试间隔
props.put(“acks”, “all”); // 确保消息被所有副本确认

Producer<String, String> producer = new KafkaProducer<>(props);
producer.send(new ProducerRecord<>(“topic”, “key”, “value”), new Callback() {
@Override
public void onCompletion(RecordMetadata metadata, Exception exception) {
if (exception != null) {
// 处理发送失败的逻辑
// 可以选择重试或记录日志
}
}
});

消费者端失败重试
手动提交偏移量:设置enable.auto.commit为false,手动提交偏移量,以便在消息处理成功后才提交。
重试策略:使用SpringKafka的SeekToCurrentErrorHandler或自定义错误处理逻辑来实现重试。
死信队列:对于重试次数达到上限仍然失败的消息,发送到死信队列(DLQ)进行后续处理。
幂等性:确保消费者处理消息的逻辑是幂等的,即使消息被重复处理也不会影响系统状态。
错误处理:在处理消息时,对可能抛出的异常进行捕获和处理,根据异常类型决定是否重试。
@Bean
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
factory.setErrorHandler(new SeekToCurrentErrorHandler(
new DeadLetterPublishingRecoverer(kafkaTemplate()),
new FixedBackOff(3000, 3)
));
factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL);
return factory;
}

@KafkaListener(topics = “topic”, containerFactory = “kafkaListenerContainerFactory”)
public void listen(ConsumerRecord<String, String> record) {
try {
// 处理消息
} catch (Exception e) {
// 处理失败逻辑,消息将被重新消费
}
}

Kafka C++ 库版本 0.11.0.0 及以上都支持 subscribe() 方法。在该方法中,您可以指定一个或多个主题以及回调函数,以便在消费者接收到新消息时进行处理。例如,以下是使用 Kafka C++ 库进行订阅的示例代码: ```cpp #include <librdkafka/rdkafkacpp.h> #include <iostream> #include <csignal> static bool run = true; void sigterm(int sig) { run = false; } class ExampleEventCb : public RdKafka::EventCb { public: void event_cb(RdKafka::Event &event) { switch (event.type()) { case RdKafka::Event::EVENT_ERROR: std::cerr << "ERROR (" << RdKafka::err2str(event.err()) << "): " << event.str() << std::endl; if (event.err() == RdKafka::ERR__ALL_BROKERS_DOWN) run = false; break; case RdKafka::Event::EVENT_STATS: std::cerr << "\"STATS\": " << event.str() << std::endl; break; case RdKafka::Event::EVENT_LOG: std::cerr << "LOG-" << event.severity() << "-" << event.fac() << ": " << event.str() << std::endl; break; default: std::cerr << "EVENT " << event.type() << " (" << RdKafka::err2str(event.err()) << "): " << event.str() << std::endl; break; } } }; class ExampleConsumeCb : public RdKafka::ConsumeCb { public: void consume_cb(RdKafka::Message &msg, void *opaque) { switch (msg.err()) { case RdKafka::ERR__TIMED_OUT: break; case RdKafka::ERR_NO_ERROR: std::cout << "Read msg at offset " << msg.offset() << std::endl; if (msg.key()) { std::cout << "Key: " << *msg.key() << std::endl; } std::cout << "Payload: " << static_cast<const char *>(msg.payload()) << std::endl; break; case RdKafka::ERR__PARTITION_EOF: std::cerr << "Reached end of partition " << RdKafka::TopicPartition::format(msg.topic(), msg.partition(), msg.offset()) << std::endl; break; case RdKafka::ERR__UNKNOWN_TOPIC: case RdKafka::ERR__UNKNOWN_PARTITION: std::cerr << "Consume failed: " << msg.errstr() << std::endl; run = false; break; default: std::cerr << "Consume failed: " << msg.errstr() << std::endl; run = false; } } }; int main(int argc, char **argv) { std::string brokers = "localhost:9092"; std::string errstr; std::string topic_str = "my_topic"; std::vector<std::string> topics = {topic_str}; int32_t partition = RdKafka::Topic::PARTITION_UA; int64_t start_offset = RdKafka::Topic::OFFSET_BEGINNING; RdKafka::Conf *conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); conf->set("metadata.broker.list", brokers, errstr); ExampleEventCb ex_event_cb; conf->set("event_cb", &ex_event_cb, errstr); RdKafka::Consumer *consumer = RdKafka::Consumer::create(conf, errstr); if (!consumer) { std::cerr << "Failed to create consumer: " << errstr << std::endl; exit(1); } RdKafka::Topic *topic = RdKafka::Topic::create(consumer, topic_str, nullptr, errstr); if (!topic) { std::cerr << "Failed to create topic: " << errstr << std::endl; exit(1); } ExampleConsumeCb ex_consume_cb; RdKafka::ErrorCode resp = consumer->start(topic, partition, start_offset, &ex_consume_cb); if (resp != RdKafka::ERR_NO_ERROR) { std::cerr << "Failed to start consumer: " << RdKafka::err2str(resp) << std::endl; exit(1); } std::cout << "Started consumer for topic " << topic_str << std::endl; signal(SIGINT, sigterm); signal(SIGTERM, sigterm); while (run) { consumer->poll(1000); } consumer->stop(topic, partition); consumer->close(); delete topic; delete consumer; RdKafka::wait_destroyed(5000); return 0; } ``` 在上面的示例代码中,我们使用了 `consumer->start()` 方法来开始从指定主题中消费消息。在回调函数 `ExampleConsumeCb::consume_cb()` 中,我们对接收到的消息进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值