0

我正在寻找构建一个 Java11 Spring 引导应用程序。该应用程序将处理非常大的吞吐量(将有高峰和低流量)

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

幸福的道路

从概念上讲,它相当直截了当。步骤大致是这样的

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

我们对这个应用程序的潜在问题是它会为每个请求进行数据库保存,它会保存很多单独的保存。数据库连接池可以快速用完更多的连接。

我的替代方法看起来像这样

内部队列

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

所以一些问题/想法

  • 这看起来像一个好方法吗,有什么我应该注意的陷阱吗?
  • 也许您以更好/不同的方式解决了类似的问题?
  • 无论如何,反应式流会有所帮助吗?
  • 我应该为此使用哪些内部 Java 库?我的想法是使用 Java 的 LinkedListQueue<SomeDto> myQ = new LinkedList<SomeDto>(); )进行内部排队?
4

3 回答 3

3

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

如果您想构建更健壮的东西,您可以考虑使用消费者填充数据库的事件日志解决方案(例如基于 Kafka)(Kafka 将取代您的内部队列)。

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

我建议您阅读《设计数据密集型应用程序》之类的书:这绝对是一种宝贵的资源,它将帮助您根据自己的需求和上下文设计可靠的解决方案。

于 2019-06-25T14:20:58.840 回答
1

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

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

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

于 2019-07-03T19:11:58.757 回答
0

如果您正在打一个休息电话,我认为您不能将所有请求保存在同一个链接列表中。您可以使用 RabbitMQ 进行排队。验证成功后,您可以将对象推送到队列并返回 200

于 2019-06-25T13:55:56.853 回答