我知道已经有一些现有的问题并且它们提供了非常好的总体观点。 我希望获得关于某些观点的 C#/VB.Net 方面的细节,而不是哲学层面上的实际实施。
我的特定情况
我有一个 WCF 服务,其中包括接收文件等功能。 在服务的大部分生命周期中,这个特定领域实际上只是闲置的 - 当工作真正来临时,会以极高的数量迅速到达。
对于每个接收到的文件(最多可以达到每秒数千个),服务需要为每个文件工作1-10秒钟(从其他服务,本地资源和网络 IO 等待时间等方面取决于多种因素)。
为了帮助服务处理这些突发负载,我实施了队列系统。 每秒收到的成千上万个文件被放置在队列上。 控制器根据队列大小计算要使用的线程数,直到达到“峰值最大线程”设置,这将防止创建额外的线程。 这些线程被放置在线程池中,并重新用于循环遍历队列。 控制器将定期重新计算所需的线程数。 如果队列的大小减少,则释放相应数量的线程。
老生常谈的问题
我应该将线程峰值设置为多少? 显然,每次接收到文件时添加一个新线程是愚蠢的 - 性能最好将恶化。 当 CPU 利用率仅为每个核心的 10% 时限制线程似乎也不是最佳资源使用方式。
那么,有没有适当的方法来确定要限制的线程数? 我希望服务可以通过抽样可用资源来自行确定这一点,但这样做是否会影响性能? 我知道通常的答案是监视工作负载,通过试错调整计数,直到找到我喜欢的数字,但由于这项服务的性质(长时间闲置后跟随高/突发工作量),这可能需要很长时间才能获得这种信息。
如果我们将服务器的镜像移动到一个不同于之前速度更快/更慢/不同的主机上,那该怎么办?我是否需要重新进行所有过程的重采样?
理想情况下,我希望协调员能够智能地增加线程池的大小,直到CPU利用率达到x%(80%是否合理?90%?99%?)。显然,我希望在不添加超过必要数量的线程以达到x%的情况下实现这一点,否则我将得到的只是线程不仅在等待IO资源,而且互相等待。
提前致谢!
相关问题(如果您想获得一些通用的想法):
一个让你复杂化的问题
如果问题不复杂,那会有多少乐趣呢?
目前为止,服务在这些突发情况下确实会达到100%的CPU使用率。问题在于CPU利用率会突然激增,从空闲状态(0-10%)达到100%,然后再次下降。我不确定我是否可以解决这个问题——理想情况下,我不想将其一直提高到100%。该问题的原因在于所提到的文件实际上是图片,而服务的一部分过程是将图像传递给System.Windows.Media黑盒子,它会为我执行一些复杂的图像处理。
由于I/O等待和其他处理,CPU利用率会不断地出现波峰后又有平静期。如果无法避免 CPU 利用率达到 100%(我很想知道如何预防这种情况,或者是否有必要),应该让 CPU 利用率图形呈现什么样的状态?始终保持在 100%?在 50-100% 之间反复跳动?如果我尝试取样来决定哪种方法效果最好,那么更改虚拟服务器的主机是否可以保证获得相同的图表效果?
对于愿意回答的人,我不需要考虑这个额外的复杂性。请随意忽略此部分内容。然而,任何带有这种复杂性的回答,或者提供处理建议的回答,我至少会点赞!
非常冗长的问题 - 对此表示抱歉 - 感谢您的耐心阅读!!