Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何以稳健的方式处理卡夫卡出版失败_Java_Cassandra_Redis_Apache Kafka_Kafka Consumer Api - Fatal编程技术网

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宕机、Kafka broker宕机等)无法向Kafka发布消息,我们如何能够可靠地处理这些消息,并在事情再次备份后重播它们。正如我所说,我们甚至不能承受一条消息的失败。 另一个用例是,我们还需要知道在任何给定的时间点,有多少消息由于任何原因(如计数器功能)而未能发布到Kafka,现在需要重新发布这些消息

解决方案之一是将这些消息推送到某个数据库(比如Cassandra,其中写入速度非常快,但我们还需要计数器功能,我想Cassandra计数器功能不是很好,我们不想使用它。)它可以处理这种负载,也为我们提供了非常精确的计数器设备

这个问题更多的是从架构的角度,然后是使用哪种技术来实现这一点

附言:我们处理一些像3000吨的地方。所以,当系统开始出现故障时,这些故障消息可以在很短的时间内快速增长。我们使用的是基于java的框架


谢谢你的帮助

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