部署于IIS的.NET Core Web App运行重负载进程卡顿该如何解决
解决方案
1. 优先调整并行计算逻辑的资源占用
你当前使用的Parallel.ForEach默认会占用所有可用的CPU核心,是导致站点卡顿的核心原因,优先修改代码限制并行度:
private List<ModelX> CalculationProcess(IList<ModelY> data) { var modelXs = new ConcurrentBag<ModelX>(); // 配置并行参数,留至少2个核心处理Web请求 var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount - 2 }; Parallel.ForEach(data, parallelOptions, datum => { // 降低计算线程的调度优先级,让Web请求线程优先获取CPU资源 var originalPriority = Thread.CurrentThread.Priority; Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; try { modelXs.Add(datum.GenerateModelX()); } catch (Exception) { // ... } finally { // 恢复线程优先级,避免影响线程池后续调度 Thread.CurrentThread.Priority = originalPriority; } }); return modelXs.ToList(); }
注:16核的服务器预留2个核心足够支撑常规站点请求,如果你站点并发量高,可以适当调高预留核心数。
2. 改造长耗时任务的调用模式
单次计算耗时10分钟,放在同步API请求流程中会直接导致请求超时,同时长期占用请求线程资源,建议改成异步后台任务模式:
- 调用API时直接返回任务ID,不等待计算完成
- 用
IHostedService或者第三方后台任务框架处理计算逻辑 - 计算完成后通过查询接口、站内通知等方式告知用户结果
这种方式既避免了用户侧请求超时,也能避免计算逻辑占用Web请求的处理资源。
3. 调整IIS配置的补充方案
如果暂时不想改代码,可配合调整IIS应用池配置提升效果:
- 将
CPU Limit下调到60%~70%,预留更多CPU余量给普通请求 - 开启
Processor Affinity后,指定工作进程只绑定前14个逻辑核心,强制预留2个核心给系统和其他请求调度,比百分比限流更稳定 - 如果使用多进程(Web Garden)模式,可通过路由规则将计算类请求固定转发到其中一个工作进程,剩余进程专门处理普通站点请求,注意要提前处理好多进程下的会话、缓存共享问题。
4. 长期最优方案
将重计算模块和Web站点拆分为两个独立服务,部署在不同的应用池甚至不同服务器上:
- Web服务仅负责处理用户交互、请求转发,资源占用低
- 计算服务仅负责处理重负载计算任务,可单独配置资源策略
- 两个服务之间通过内存队列、消息队列通信,完全避免资源竞争,也方便后续单独扩容计算能力。
内容的提问来源于stack exchange,提问作者azizanbps
相关产品推荐
相关产品推荐

