我有一个 Clojure 网络应用程序,基本结构是这样的:
- 服务器有一个 LinkedBlockingQueue 或 ArrayBlockingQueue(我都试过了)
- 多个线程接受网络连接,并
offer
工作到队列 - 队列中的一个线程
take
在无限循环中处理所取的每个项目
我注意到take
调用的严重性能问题:
- 线程
offer
以非常快的速度进入队列,队列很快将它们全部带走 - 队列中的一个工作线程
take
以非常慢的速度(比速度慢 200 多倍offer
) - CPU 使用率非常低 - 所以工作人员根本不忙
在不使用队列的情况下,在基准测试情况下,相同的工作负载能够最大化 CPU 使用率并以令人满意的速度完成。
那么在这种情况下使用的最佳排队技术是什么?
这是我的代码(少于 100 行);
https://github.com/HouzuoGuo/Aurinko/blob/master/src/Aurinko/core.clj
编辑,我的观察细节:
- 我对请求处理速度进行了基准测试,它在不使用队列的情况下每秒处理大约 8,000 个请求。
- 我让服务器程序在排队请求时打印一条调试消息,并在完成处理请求时打印另一条消息。
- 我制作了一个简单的客户端程序,每秒向服务器发送大约 1,000 个请求。
- 服务器及时将所有请求排队,队列变成数千个元素。
- 根据调试消息,Worker(请求处理器)似乎每秒仅处理大约 150 个请求。
编辑:
感谢大家的帮助。我已经确认阻塞队列不是导致性能问题的原因。虽然我没有发现我的应用程序中的性能瓶颈,但一定有一个地方。
最终编辑:
谢谢大家。性能瓶颈是由网络 IO 而不是阻塞队列引起的。