我正在开发一个带有 play 框架的应用程序,该框架执行密集的 CPU 计算。这些计算由 40 个必须并行运行的部分组成。现在我已经为每个计算片段创建了一个 Akka actor,当请求计算时,将启动 40 个新的 actor。我的问题是,在应用程序前端,我正在运行一个轮询服务来检查计算是否已结束,并且由于执行了如此多的线程,CPU 获得 100% 和轮询服务,当然还有整个导航,持续时间大约为 20 秒,正常情况下持续时间不到 1 秒,这是一个微不足道的请求。
我在一个只有一个核心的 AWS 小型实例中运行它。这是问题的一部分,但我需要确保当应用程序投入生产且流量大得多时,“后端”计算不会影响前端体验。
使用 akka 的正常方法是限制调度程序“大小”以减少线程数,然后有空闲的 cpu 来处理前端请求,但我至少需要 40 个并行处理元素。我尝试通过以下方式降低这些计算线程的优先级:
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
但我认为对性能没有影响。我的主要问题是,有什么方法可以在逻辑上并行化这些执行,但不创建这么多线程?
最佳答案
我的看法:
似乎没有简单的方法来解决并行问题,所以整个想法是将前端服务与后端计算分开。
首先是WebSocket。在后端服务器上运行 WebSocket 服务,并从前端连接到该 WebSocket。所以前端不会轮询服务器,而是后端服务器计算完成后将结果推送到前端。
其次,通过使用现代 JavaScript 框架(例如 AngularJS)在另一个实例上运行前端服务,甚至主要是在客户端浏览器上。
这样后端计算速度慢就不会再影响前端的性能,前端什么时候完成就可以得到结果(通过WebSocket与后端通信)。
关于java - 如何在没有线程的情况下并行化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26585044/