NET 应用程序使用线程来执行其工作指令。此类示例包括 Web 应用程序中请求的处理或工作指令的并行化,其中多个线程可以并行运行,并在最后合并结果。线程池提供了预定义数量的此类线程,这些线程通常已经创建。使用线程池可以轻松使用池中的预定义线程,而无需一次又一次重新创建它们。
当从线程池请求线程但无法再提供线程时,就会出现线程池瓶颈(也称为“线程池耗尽”)。在耗时的操作或网络服务器负载较高时,用户可能需要等待很长时间才能得到响应。尽管.NET下线程池的大小在一定限制内是可变的,但一旦达到可用线程的最大数量,用户就必须等待。此外,更改线程池大小需要时间。
问题
该应用程序是.NET 8下的ASP.NET Core WebAPI,用作单 贷款人员电子邮件列表 页应用程序(SPA)的基础。到目前为止,我们已将其托管在 Windows 上的 IIS 上,运行速度非常快。在 Docker 容器中迁移到 Linux 后,响应时间几乎增加了一倍。这是不典型的,所以我们想找出问题的根源。
调查问题
.NET 提供了一些用于诊断此类问题的工具,但在我们的示例中,它们必须安装在 Docker 容器中。特别是,我们需要 dotnet-counters 工具,它是Dotnet Cli 诊断工具的一部分。可以使用一个技巧将它们安装在 Docker 镜像中。您首先在发布阶段安装它,它基于 .NET SDK 映像。然后将最后阶段的工具复制到最终图像中。这种绕道是必要的,因为最终映像中没有 .NET SDK,因此您无法安装这些工具。以下代码显示了相应的 Dockerfile。
然后,您可以在应用程序容器中启动 .NET 诊断工具。
禁用 Visual Studio 的“快速模式”也很重要,因为在快速模式下,Visual Studio 调用时会docker build带有一个参数,告诉 Docker 仅在 Dockerfile 中创建第一个阶段(通常是基础阶段),应用程序的 DLL 在本地创建然后将 PC 作为安装件集成到映像中(更多信息请参见此处)。要停用“快速模式”,项目文件 (.csproj) 中的参数ContainerDevelopmentMode必须设置为值“常规”。