我每天需要使用 EJB 3.1 异步方法处理大约 250.000 个文档,才能应对整体的长时间任务。
我这样做是为了使用更多线程并同时处理更多文档。这是伪代码的示例:
// this returns about 250.000 documents per day
List<Document> documentList = Persistence.listDocumentsToProcess();
for(Document currentDocument: documentList){
//this is the asynchronous call
ejbInstance.processAsynchronously(currentDocument);
}
假设我有一个大小为 10 的线程池和 4 核处理器,我的问题是:
- 应用程序服务器将同时处理多少个文档?
- 当池中的所有线程都在处理文档并且又出现一个异步调用时会发生什么?这会像某种 JMS 队列一样工作吗?
- 采用 JMS 队列解决方案有什么改进吗
我使用 Java EE 6 和 WebSphere 8.5.5.2
异步EJB方法调用的默认配置如下(来自信息中心):
EJB容器工作管理器具有以下线程池设置:
Minimum number of threads = 1
Maximum number of threads = 5
Work request queue size = 0 work objects
Work request queue full action = Block
Remote Future object duration = 86400 seconds
所以尝试回答你的问题:
应用程序服务器将同时处理多少个文档? (假设10个大小的线程池)
该线程池适用于所有 EJB 异步调用,因此首先您需要假设您的应用程序是唯一使用 EJB 异步调用的应用程序。那么你可能会有 10runnable实例,将并行处理。是否会被处理同时取决于系统中可用的核心/线程的数量,因此您无法获得准确的数字(例如,某些核心/线程可能正在执行 Web 工作,或使用 cpu 的其他进程)。
当池中的所有线程都在处理文档并且又出现一个异步调用时会发生什么?
这取决于Work request queue size
and Work request queue full action
, 设置。如果池中没有可用线程,则请求将排队,直到达到队列大小。然后这取决于行动,这可能是Block
or Fail
.
采用 JMS 队列解决方案有什么改进吗
取决于您的需求。以下是 JMS 解决方案的一些优缺点。
Pros:
- 持久性 - 如果使用 JMS,您的异步任务可以是持久的,因此在服务器发生故障的情况下您不会丢失它们,并且将在重新启动后或由其他集群成员处理。 EJB 异步队列仅保存在内存中,因此队列中的任务在发生故障时会丢失。
- 可扩展性 - 如果将任务放入队列,它们可能会由集群中的许多服务器同时处理,而不仅限于单个 JVM
- 过期和优先级 - 您可以为消息定义不同的过期时间或优先级。
Cons:
- 更复杂的应用程序 - 您将需要实现 MDB 来处理您的任务。
- 更复杂的基础设施 - 您将需要数据库来存储队列(文件系统可用于单个服务器,共享文件系统可用于集群),或外部消息传递解决方案,例如WebSphere MQ
- 处理单个项目的性能稍低,服务器上的负载较高,因为它必须序列化/反序列化到持久存储
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)