Java 如何以稳健的方式处理卡夫卡出版失败
我正在使用Kafka,我们有一个用例来构建一个容错系统,在这个系统中,甚至一条消息都不应该被遗漏。问题是: 如果由于任何原因(ZooKeeper宕机、Kafka broker宕机等)无法向Kafka发布消息,我们如何能够可靠地处理这些消息,并在事情再次备份后重播它们。正如我所说,我们甚至不能承受一条消息的失败。 另一个用例是,我们还需要知道在任何给定的时间点,有多少消息由于任何原因(如计数器功能)而未能发布到Kafka,现在需要重新发布这些消息 解决方案之一是将这些消息推送到某个数据库(比如Cassandra,其中写入速度非常快,但我们还需要计数器功能,我想Cassandra计数器功能不是很好,我们不想使用它。)它可以处理这种负载,也为我们提供了非常精确的计数器设备 这个问题更多的是从架构的角度,然后是使用哪种技术来实现这一点 附言:我们处理一些像3000吨的地方。所以,当系统开始出现故障时,这些故障消息可以在很短的时间内快速增长。我们使用的是基于java的框架Java 如何以稳健的方式处理卡夫卡出版失败,java,cassandra,redis,apache-kafka,kafka-consumer-api,Java,Cassandra,Redis,Apache Kafka,Kafka Consumer Api,我正在使用Kafka,我们有一个用例来构建一个容错系统,在这个系统中,甚至一条消息都不应该被遗漏。问题是: 如果由于任何原因(ZooKeeper宕机、Kafka broker宕机等)无法向Kafka发布消息,我们如何能够可靠地处理这些消息,并在事情再次备份后重播它们。正如我所说,我们甚至不能承受一条消息的失败。 另一个用例是,我们还需要知道在任何给定的时间点,有多少消息由于任何原因(如计数器功能)而未能发布到Kafka,现在需要重新发布这些消息 解决方案之一是将这些消息推送到某个数据库(比如Ca
谢谢你的帮助 Kafka之所以以分布式容错方式构建,是为了处理与您完全相同的问题,核心组件的多个故障应该避免服务中断。为了避免Zookeeper宕机,请至少部署3个Zookeeper实例(如果在AWS中,请跨可用性区域部署它们)。要避免代理失败,请部署多个代理,并确保在producer
bootstrap.servers
属性中指定多个代理。要确保Kafka群集已将您的消息写入持久庄园,请确保在生产者中设置了acks=all
属性。这将在所有同步副本确认收到消息时确认客户端写入(以牺牲吞吐量为代价)。您还可以设置队列限制,以确保如果对代理的写入开始备份,您可以捕获异常并进行处理,还可以重试
使用Cassandra(另一个经过深思熟虑的分布式容错系统)来“暂存”您的写操作似乎并没有为您的体系结构增加任何可靠性,但确实增加了复杂性,而且Cassandra并不是为消息队列编写的消息队列,我会避免这种情况
如果配置正确,Kafka应该可以处理所有的消息写入并提供适当的保证。Chris已经告诉过如何保持系统容错 默认情况下,Kafka至少支持一次
消息传递语义,这意味着当它试图发送消息时,发生了什么事情,它将尝试重新发送消息
创建Kafka制作人
属性时,可以通过将retries
选项设置为大于0来配置该属性
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:4242");
props.put("acks", "all");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
Producer<String, String> producer = new KafkaProducer<>(props);
Properties=newproperties();
props.put(“bootstrap.servers”,“localhost:4242”);
道具放置(“阿克斯”、“全部”);
道具放置(“重试”,0);
道具放置(“批量大小”,16384);
道具放置(“玲儿小姐”,1);
props.put(“buffer.memory”,33554432);
put(“key.serializer”、“org.apache.kafka.common.serialization.StringSerializer”);
put(“value.serializer”、“org.apache.kafka.common.serialization.StringSerializer”);
制作人=新卡夫卡制作人(道具);
欲了解更多信息,请查收。我参加聚会迟到了。但我发现上面的答案中缺少了一些东西:)
选择像Cassandra这样的分布式系统的策略是一个不错的主意。一旦卡夫卡启动并正常运行,您可以重试写入其中的所有消息
我想回答“知道在给定时间有多少消息未能发布”
从标记中,我看到您正在使用apache-kafka
和kafka消费者api
。您可以为制作人编写自定义回调,此回调可以告诉您消息发布是否失败或成功。失败时,记录消息的元数据
现在,您可以使用日志分析工具来分析故障。Splunk就是这样一个体面的工具
下面是一个小代码片段,它可以更好地解释我所说的回拨:
public class ProduceToKafka {
private ProducerRecord<String, String> message = null;
// TracerBulletProducer class has producer properties
private KafkaProducer<String, String> myProducer = TracerBulletProducer
.createProducer();
public void publishMessage(String string) {
ProducerRecord<String, String> message = new ProducerRecord<>(
"topicName", string);
myProducer.send(message, new MyCallback(message.key(), message.value()));
}
class MyCallback implements Callback {
private final String key;
private final String value;
public MyCallback(String key, String value) {
this.key = key;
this.value = value;
}
@Override
public void onCompletion(RecordMetadata metadata, Exception exception) {
if (exception == null) {
log.info("--------> All good !!");
} else {
log.info("--------> not so good !!");
log.info(metadata.toString());
log.info("" + metadata.serializedValueSize());
log.info(exception.getMessage());
}
}
}
}
ProduceToKafka公共类产品{
私有产品记录消息=null;
//生产者类具有生产者属性
私人卡夫卡制作人myProducer=制作人
.createProducer();
public void publishMessage(字符串){
ProducerRecord消息=新的ProducerRecord(
“主题名称”,字符串);
myProducer.send(message,newmycallback(message.key(),message.value());
}
类MyCallback实现回调{
私有最终字符串密钥;
私有最终字符串值;
公共MyCallback(字符串键、字符串值){
this.key=key;
这个值=值;
}
@凌驾
公共void onCompletion(记录元数据、异常){
if(异常==null){
log.info(“----------->一切正常!!”;
}否则{
log.info(“---------->不太好!!”;
log.info(metadata.toString());
log.info(“+metadata.serializedValueSize());
log.info(exception.getMessage());
}
}
}
}
如果您分析每个时间单位的“---------->不太好!!”
日志数,您可以获得所需的细节
天哪,速度 谢谢你,克里斯!我理解卡夫卡的设计是为了处理这种情况,但把它作为一个论据,说事情总是会按照它应该是一个大胆的声明,对我来说,它注定要失败迟早。只是给你一个例子,即使你有足够的代理和足够的zookeeper实例,事情仍然会失控。例如:如果一个主题有3个re