设计 Web 服务的最佳方式,它必须将来自请求的数据存储在列表或类似结构中

Best way to design web service, which have to store data from requests in list or similar structure

我的目标是创建 Java EE Web 服务,它将同时处理数千个(或将来更多)请求,并且必须将来自请求的数据存储在列表或类似结构中。我想将请求中的对象存储在内存中,但这不是强制性的。一些对象将从每个请求中提取并添加到选定的数据结构中。 Web 服务将有两个操作:添加到结构和从结构中删除。删除请求将包含对象实例变量的值。可能它将是唯一 ID 或其他一个或多个实例变量。总会有一个对象要删除(如果请求无效,则为 0)。实例变量值相等的对象将被删除。

我的想法是使用两个EJB。首先是@Stateless 并公开为 Web 服务。它将从请求中提取对象并调用第二个 EJB 以从数据结构中添加或删除请求的对象。第二个 EJB 将是 @Singleton 并且具有从请求中提取的对象的实例变量 ArrayList<>。正如我所说,它根本不必是 ArrayList 或 List。

我也考虑过使用一个 EJB,它必须是 @WebService @Singleton,但是文档说这种组合是 "possible, but ... not defined by this specification."

您不能在 WS 上使用 @Singleton,因为容器可能会初始化多个实例来处理大量请求。

您的@Singleton bean 不能使用 ArrayList<>,因为会有并发访问。您应该改用 ConcurrentLinkedQueue。 如何识别删除操作的请求?也许 ConcurrentHashMap 会更好。

如果你想要 "thousands (or more in future)",你迟早会 运行 内存不足,除非你将请求转储到数据库或文件中。带有 JPA 的数据库将是最简单的,您可以通过在 WS 和 Request 对象上添加一些注释来实现它。

A​​rjan,你的要求不是很清楚。 假设您正在构建一个高负载应用程序 > 每秒 1000 个请求,我会这样做:

Servlet 处理

  • 将 "object" 数据容器分离到每个用户的 http 会话中(如果 http 会话可用)
  • 将同步列表添加到您的 http 会话中,并在每个请求上对同步私有列表执行操作并将 Web 客户端详细信息添加到此 http 会话存储列表中
  • 将 httpsession 列表的引用添加到下一个提到的 SingletonEJB

单例 EJB

  • 创建单例 EJB
  • 为您的 extracted/filtered/processed YourObjectType 类型的对象添加一个列表字段
  • 为基于 HTTP 会话且未过滤但同步的列表的引用添加第二个集合

TimerEJB

  • 创建一个计时器 EJB 以 运行 定期,例如每秒
  • 此函数将遍历 refCol 中的所有引用列表,并将提取和过滤所需的对象,并确保清理基于 http 会话的列表。

解决方案的好处:

  • 将用户的内存负载推送到他们的会话
  • 不要在非常高的负载下陷入 synchronizing/mutex 问题,因为您在 Singleton bean 中的中央过滤列表上使用 timerEJB 的操作时间非常短。
  • 只要您的会话保持较小规模,您就可以长期扩展
  • 也许 CPU 过滤密集型解决方案和持久化过滤对象的 IO 密集型解决方案在客户端请求之外,客户端不会面临性能问题。
  • 计时器时间表可根据您的需要进行更改

缺点:

  • 复杂度稍高
  • 您必须清除 refColl 中对已关闭 http 会话列表的引用。通过在复合 class 或任何其他自定义解决方案中提供会话和对会话列表的引用。如果您不清理,您的堆将通过保存对已经 "killed" 个 http 会话的列表的引用而变得臃肿。