我在 tomcat 服务器上运行了一个 RESTful 风格的 RPC(远程过程调用)API,该 API 在 K 线程上处理具有 M 个任务的 N 个用户的数据。大多数情况下,一个用户有大约 20 到 500 个任务(但 M 可能在 1 到 5000 之间)。一项任务需要大约 10 到 20 秒才能完成,但可能在 1 秒到 20 分钟之间。目前,系统大多只有一个用户,有时最多三个,但在不久的将来会同时增加到大约 10 个用户。我们的服务器有 10 个内核,因此我想使用 10 个线程。目前,每个用户都有 5 个线程进行处理,效果很好。但是 a) 大多数时候机器的利用率只有 50%(这导致针在“30 分钟”范围内等待),有时服务器负载高达 150%。
解决方案要求:
- 始终使用 100% 的服务器(如果有任务)
- 所有用户在线程执行方面都被同等对待(与其他用户完成的线程数量相同)
- 新用户不必等到之前用户的所有任务都完成后(尤其是在 user1 有 5000 个任务而 user2 有 1 个任务的情况下,这一点很重要)
想到的解决方案:
只需使用具有 10 个线程的 FixedThreadPoolExecutor,违反条件 3
在我的任务中使用 PriorityBlockingQueue 并实现 compareTo 方法 -> 不能使用 threadpoolExecutors 提交方法(因此我不知道提交的任务何时结束)
实现类似阻塞队列的“循环”,其中 K 个线程(在我们的例子中为 10 个)以循环方式从 N 个内部队列中获取新任务 -> 为了能够将任务放入正确的队列中,我需要一个“提交”- 接受多个参数的方法(我也需要实现一个 ThreadPoolExecutor)
我试图说明我所说的循环法的含义,比如阻塞队列(如果没有帮助,请随时编辑它):
-- -- -- -- -- -- queue task load, -- -- -- -- -- -- -- one task denoted by -- -- -- -- -- -- -- -- -- | Q1 | Q2 | Q3 | Q4 | Q5 | Q6 | Q7 | QN | | * ^ | | last| |next | | ------------- \ / \ | | | | | | T1 | T2 | T3 | T4 | TK |
是否有一个优雅的解决方案来主要使用 Java 标准 API(或任何其他广泛使用的 Java API)来实现这种处理行为(可能是我提出的解决方案之一或任何其他解决方案)?或者您对如何解决此问题有任何其他提示?