多少线程太多?

我正在编写一个服务器,当收到请求时,我将的每个操作发送到一个单独的线程中。我这样做是因为几乎每个请求都会进行数据库查询。我正在使用线程池库来减少线程的构造/破坏

我的问题是:对于这样的I/O线程,什么是好的截止点?我知道这只是一个粗略的估计,但我们说的是成百上千吗?几千

我该如何着手弄清楚这个截止点是什么


编辑:

谢谢大家的回复,看来我只是要测试一下,看看我的线程数上限。但问题是:我怎么知道我已经达到了极限?我到底应该测量什么

有些人会说,两条线太多了——我不太在那个阵营里:——)

以下是我的建议:测量,不要猜测。一个建议是将其设置为可配置,并最初将其设置为100,然后将您的软件发布到野外并监控发生的情况

如果线程使用率峰值为3,那么100就太多了。如果一天中大部分时间它都保持在100,那么把它增加到200,看看会发生什么

实际上,您可以让代码本身监控使用情况,并在下一次启动时调整配置,但这可能有些过头了


澄清和详细说明:

我不主张滚动您自己的线程池子系统,请务必使用您现有的线程池子系统。但是,由于您询问了线程的一个好的截止点,我假设您的线程池实现能够限制创建的最大线程数(这是一件好事)

我已经编写了线程和数据库连接池代码,它们具有以下特性(我认为这对性能至关重要):

  • 活动线程的最小数目
  • 最大线程数
  • 正在关闭一段时间未使用的线程

第一个设置线程池客户端的最低性能基线(此数量的线程始终可供使用)。第二个设置了活动线程对资源使用的限制。第三种方法是在安静时间将您返回到基线,以最小化资源使用

您需要平衡拥有未使用线程的资源使用情况(A)和没有足够线程来完成工作的资源使用情况(B)

(A) 通常是内存使用量(堆栈等),因为不工作的线程不会占用很多CPU。(B) 当请求到达时,通常会延迟处理,因为您需要等待线程可用

这就是你测量的原因。正如您所说,您的绝大多数线程将等待来自数据库的响应,因此它们不会运行。有两个因素会影响您应该允许的线程数

第一个是可用的DB连接数。这可能是一个硬限制,除非您可以在DBMS上增加它-我将假设您的DBMS在这种情况下可以接受无限数量的连接(尽管您最好也测量)

然后,您应该拥有的线程数量取决于您的历史使用情况。您应该运行的最小值是您曾经运行过的最小值+A%,绝对最小值为(例如,使其像A一样可配置)5

最大线程数应为历史最大值+B%

您还应该监控行为变化。如果由于某种原因,您的使用率在相当长的一段时间内达到了100%的可用率(因此会影响客户端的性能),您应该提高允许的最大值,直到再次提高B%


在回答“我到底应该测量什么?”问题时:

您应该具体测量负载下并发使用的最大线程数(例如,等待DB调用返回)。然后为示例添加10%的安全系数(强调,因为其他海报似乎将我的示例作为固定建议)

此外,这应该在生产环境中进行调整。事先得到一个估计值是可以的,但您永远不知道生产会给您带来什么(这就是为什么所有这些东西都应该在运行时进行配置)。这是为了捕捉一种情况,例如客户端呼叫的意外加倍

发表评论