gpt4 book ai didi

java - (Array|Linked)BlockingQueue 具有良好的 `offer` 性能,但为什么 `take` 太慢了?

转载 作者:行者123 更新时间:2023-11-30 07:22:39 26 4
gpt4 key购买 nike

我有一个 Clojure 网络应用程序,基本结构是这样的:

  • 服务器有一个 LinkedBlockingQueue 或 ArrayBlockingQueue(我都试过了)
  • 多线程接受网络连接,并提供工作给队列
  • 一个线程在无限循环中从队列中获取,并处理每个获取的项目

而且我注意到 take 调用存在严重的性能问题:

  • 线程以非常快的速度提供给队列,队列很快就把它们全部拿走
  • 一个工作线程以非常非常慢的速度从队列中(比offer的速度慢200多倍)
  • CPU 使用率非常非常低 - 所以工作人员根本不忙

在不使用队列的情况下,在基准情况下,相同的工作负载能够最大限度地提高 CPU 使用率并以令人满意的速度完成。

那么在这种情况下使用的最佳排队技术是什么?

这是我的代码(不到 100 行);

https://github.com/HouzuoGuo/Aurinko/blob/master/src/Aurinko/core.clj

编辑,我观察的细节:

  • 我对请求处理速度进行了基准测试,它在不使用队列的情况下每秒处理大约 8,000 个请求。
  • 我让服务器程序在排队请求时打印一条调试消息,在处理完请求时打印另一条消息。
  • 我制作了一个简单的客户端程序,每秒向服务器发送大约 1,000 个请求。
  • 服务器及时对所有请求进行排队,队列变成了数千个元素。
  • 根据调试消息,Worker(请求处理器)似乎每秒只能处理大约 150 个请求。

编辑:

感谢大家的帮助。我已经确认阻塞队列不是导致性能问题的原因。虽然我还没有在我的应用程序中发现性能瓶颈,但一定有一个地方。

最终编辑:

谢谢大家。性能瓶颈是由网络 IO 而不是阻塞队列引起的。

最佳答案

您声明:“CPU 使用率非常非常低 - 所以工作人员根本不忙”。你还说:“我已经确认阻塞队列不是导致性能问题的原因。虽然我没有在我的应用程序中发现性能瓶颈,但一定有一个地方。”

如果这两个陈述都是正确的,则可能是您的工作线程花费大量时间等待 I/O。如果是这样,有一个简单的解决方案:运行多个工作线程!

或者可能是存在一些其他并发瓶颈(不是工作队列)。

您为什么不执行以下操作:制作一个小测试程序,将大约 1,000 个项目推送到工作队列,然后开始运行在工作线程上运行的相同代码。当队列为空时,它应该退出。分析那个程序。 (您的开发机器上是否设置了分析器?我喜欢使用 JIP。)

关于java - (Array|Linked)BlockingQueue 具有良好的 `offer` 性能,但为什么 `take` 太慢了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12525937/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com