使用外部数据库处理非常大的吞吐量

时间:2019-06-25 13:46:07

标签: java spring-boot queue high-volume

我正在寻找一个Java11 Spring启动应用程序。该应用程序将处理非常大的吞吐量(将出现峰值和低流量)

应用程序的快乐路径如下所示。

happy path

从概念上讲,它相当简单。步骤大致如下:

  • 接受传入的POST请求。保存端点处的DTO对象。
  • 然后,
  • 应用程序将验证DTO并返回无效的错误消息。
  • 转换为数据库实体对象
  • 将实体保存到Postgres数据库中。

此应用程序存在的潜在问题是,它将针对每个请求执行许多单独的保存操作以进行数据库保存。数据库连接池可以快速用完更多的连接。

我的替代方法如下

internal queue

我希望在传入的DTO通过验证并在内存队列中排队后返回200状态。
这里没有外部阻塞,数据库应该关闭-这意味着内部队列将提供一些冗余。

一些问题/想法

  • 这看起来像是个好方法吗,我有什么陷阱吗? 密切注意,提防,小心?
  • 也许您已经更好地解决了类似的问题/ 不同的方法?
  • 反应性流有帮助吗?
  • 我应该为此使用哪些内部Java库?我的 是否想到要使用Java的LinkedList Queue<SomeDto> myQ = new LinkedList<SomeDto>(); )在内部排队?

3 个答案:

答案 0 :(得分:3)

如果应用程序内部队列中的数据失败,会发生什么?还是如果内存中的保存操作溢出?

如果您想构建更强大的功能,可以考虑使用事件记录解决方案(例如,基于Kafka),并由使用者填充数据库(Kafka将替换您的内部队列)。

但是,由于必须考虑许多其他因素,因此很难在这里真正回答您的问题。

我建议您阅读Designing Data-Intensive Applications之类的书:它绝对是一种宝贵的资源,它将帮助您根据自己的需求和背景设计可靠的解决方案。

答案 1 :(得分:1)

更好的解决方案是拥有一个冗余数据库,这样,如果其中一个系统出现故障或不可用,您可以继续使用第二个数据库。

将数据保留在内存中是我建议的解决方案。您说您正在期待一个相对较高的高峰。如果您的数据库在高峰期间不可用,我无法相信您将能够在内存中将所有请求排队所需的时间长度。如果它们在内存中,则任何类型的应用程序服务器(或影响应用程序服务器的硬件问题)都将导致所有排队的请求完全丢失。这意味着您的REST接口对其调用方说谎。您返回的信息是您成功保存了数据,但没有这样做,因为您的数据库和应用程序都崩溃了。

您要么需要一个冗余数据库,要么需要一个持久性和外部排队系统。如果您选择一个外部排队系统(也可以是冗余的以防止中断),则可以将所有持久性请求简单地推送到外部队列中。这样,您只有一种需要支持的机制/工作流程。

答案 2 :(得分:0)

如果您要打个电话,我不认为您可以将所有请求保留在同一链接列表中。您可以使用RabbitMQ进行排队。验证成功后,您可以将对象放入队列并返回200