我正在开发一个用于在JBoss上运行的文档协作的网站/在线服务。在使用2.5Ghz cpu和2GB RAM的Linux机器上进行测试期间,页面响应非常快,我们正在考虑使用这台机器启动。
文档处理过程中出现问题。在用户上载文档之后,启动新线程,其中除了其他内容之外还转换文档,从文档中提取文本和图像,并通过另一服务器上的https上载文档。用户可以一次上传许多文档,并且用于处理它们的线程同时工作。在此处理完成之前,网站几乎没有响应。
您能否就如何在处理文档的线程上分配一定比例的CPU /内存(例如最多40%)给我一些建议?如果这是不可能的,请告诉我一个方法/模式,它将以某种方式在JBoss响应页面请求和处理文档的线程之间共享机器上的负载。
此致
答案 0 :(得分:3)
没有办法为给定的线程分配一定比例的CPU /内存时间。您可以降低线程优先级,使其不会使所有资源饱和:
int oldPriority = Thread.currentThread().getPriority();
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
// process your documents here
Thread.currentThread().setPriority(oldPriority);
更好的方法可能会让您更接近指定百分比,将使用具有固定数量线程的ExecutorService
并通过它运行所有文档处理。如果你给服务器中处理器数量的一半,那么它将有效地将文档处理限制为服务器CPU时间的50%。您需要一个单例服务来设置这样的线程池:
int threads = Runtime.getRuntime().availableProcessors() / 2;
ExecutorService service = Executors.newFixedThreadPool(threads);
然后,在您的网络请求中,您可以将实现文档处理的Callable
传递给服务,并阻止它完成:
Callable<Result> callable = new DocumentProcessorCallable<Object>(doc);
Result result = service.submit(callable).get();
或者您可能不希望通过提供传递给Runnable
的{{1}}实现来立即阻止并返回。有关更多示例和文档,请参阅ExecutorService。
答案 1 :(得分:2)
用户提交文档后,您可以将它们全部提交到JMS队列中,其中只有一个MDB实例正在侦听。所以文档处理将是串行的,因此只使用一个线程(它仍然可以使用大量的CPU)。
如果此解决方案不够,您可以将远程MDB放在不同的服务器上来处理文档,并基本上卸载文档处理。这里的美妙之处在于,此更改基本上只是配置更改,不需要重新编译您的应用程序。