Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.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 历史记录队列POC返回了意外的延迟_Java_Low Latency_Chronicle Queue - Fatal编程技术网

Java 历史记录队列POC返回了意外的延迟

Java 历史记录队列POC返回了意外的延迟,java,low-latency,chronicle-queue,Java,Low Latency,Chronicle Queue,我们的一个系统有一个使用ApacheKafka作为服务总线的微服务体系结构。 低延迟是一个非常重要的因素,但可靠性和一致性(仅一次)更为重要 当我们执行一些负载测试时,我们注意到性能显著下降,所有调查都指出Kafka主题的生产者和消费者延迟大幅增加。无论我们改变了多少配置或添加了更多资源,我们都无法摆脱这些症状 目前,我们的需求是每秒处理10个事务(TPS),负载测试运行20个TPS,但随着系统的发展和添加更多功能,我们知道我们将达到一个需要500TPS的阶段,因此我们开始担心能否通过Kafka

我们的一个系统有一个使用ApacheKafka作为服务总线的微服务体系结构。 低延迟是一个非常重要的因素,但可靠性和一致性(仅一次)更为重要

当我们执行一些负载测试时,我们注意到性能显著下降,所有调查都指出Kafka主题的生产者和消费者延迟大幅增加。无论我们改变了多少配置或添加了更多资源,我们都无法摆脱这些症状

目前,我们的需求是每秒处理10个事务(TPS),负载测试运行20个TPS,但随着系统的发展和添加更多功能,我们知道我们将达到一个需要500TPS的阶段,因此我们开始担心能否通过Kafka实现这一点

作为概念证明,我尝试切换到我们的一个微服务,使用编年史队列而不是卡夫卡主题。按照avro示例从

在配置了appender之后,我们运行了一个循环,以向一个历史记录队列生成100000条消息。每个消息的大小都相同,文件的最终大小为621MB。处理写所有消息需要22分20秒和613毫秒(约1341秒),因此平均每秒75条消息

这绝对不是我们想要的,也远远不是编年史文档中宣传的延迟,它让我相信我的方法是不正确的。我承认我们的消息并不小,大约6.36KB/消息,但我毫不怀疑将它们存储在数据库中会更快,所以我仍然认为我做得不对

重要的是,我们的信息要一个接一个地处理


提前感谢您的输入和/或建议。

每次手动构建Avro对象对我来说都有点代码味道

您是否可以创建一个预定义的消息->avro序列化程序,并使用它为队列提供信息

或者,仅仅为了测试,在循环外创建一个avro对象,并多次将该对象送入队列。这样你就可以知道是大楼还是排队是瓶颈


更一般的建议:


可能附加一个探查器,看看是否进行了过多的对象分配。如果他们被提升到更高的一代,这尤其糟糕

查看它们是您的对象还是编年史队列对象


您的代码是否超出了您的ram或cpu(或网络)?

如果您需要分布式微服务,我建议您进行挑战。它将为您解决什么问题?它真的解决了那个问题吗?!记住一个方法调用需要纳秒,但是一个网络调用需要毫秒(x1000慢)。通过拥有许多dll项目和依赖项注入,您可以获得微服务的大部分优势。如果需要,每个项目都应该有自己的独立数据存储。可能会添加一个pub-sub-backbone,例如番石榴,或者使用akka(如果硬件增长过快,akka可以让您无缝地扩展到分布式系统)。我的客户希望它能帮上忙在我的POC中,我只使用了我的Mac笔记本,所以它没有联网功能。是的,我们的微服务架构是以这样一种方式完成的,即每个mico服务实例都有自己的数据存储。当在不同机器上运行的miro服务之间传递消息时,当然会有联网,但在这个POC中,情况并非如此。也许可以连接一个探查器,看看您是否进行了过多的对象分配,尤其是当它们被升级到更高的代时。查看它们是您的对象还是编年史队列对象。你在制作ram或cpu(或网络)吗?每次手工构建Avro对象对我来说都有点代码味道。您是否可以创建一个预定义的消息->avro序列化程序,并使用它为队列提供信息?或者只是为了测试,在循环外创建一个avro对象,并多次将该对象输入队列。这样你就可以知道是大楼还是排队是瓶颈。请把你最后的建议贴出来作为答案。我放了一些日志条目,发现在创建要播放的消息时,它是一个数字签名和一个编组操作,大约需要12个工厂才能完成,当然,乘以100000就是总数。重复使用同一个签名将时间减少到仅三秒,这是一个完全不同的结果。对结果非常满意。尽管如此,我还是不知道在AWS中的某个位置使用EBS存储时会发生什么,但到目前为止,它看起来很有希望。
public class MessageAppender {
    private static final String MESSAGES = "/tmp/messages";

    private final AvroHelper avroHelper;
    private final ExcerptAppender messageAppender;

    public MessageAppender() {
        avroHelper = new AvroHelper();
        messageAppender = SingleChronicleQueueBuilder.binary(MESSAGES).build().acquireAppender();
    }

    @SneakyThrows
    public long append(Message message) {
        try (var documentContext = messageAppender.writingDocument()) {
            var paymentRecord = avroHelper.getGenericRecord();
            paymentRecord.put("id", message.getId());
            paymentRecord.put("workflow", message.getWorkflow());
            paymentRecord.put("workflowStep", message.getWorkflowStep());
            paymentRecord.put("securityClaims", message.getSecurityClaims());
            paymentRecord.put("payload", message.getPayload());
            paymentRecord.put("headers", message.getHeaders());
            paymentRecord.put("status", message.getStatus());
            avroHelper.writeToOutputStream(paymentRecord, documentContext.wire().bytes().outputStream());
            return messageAppender.lastIndexAppended();
        }
    }
}