如何模拟ASP.NET Web API应用死锁挂起状态以测试K8s存活探针
实现方案
以下两种实现方式都可以让ASP.NET Core 3.1 Web API应用进入无响应状态,满足测试Kubernetes存活探针的需求:
方案1:通过API接口主动触发挂起
适合需要手动控制测试时机的场景,调用接口后应用立刻进入死锁无响应状态。
using Microsoft.AspNetCore.Mvc; using System.Threading; [ApiController] [Route("api/[controller]")] public class HangTestController : ControllerBase { private static readonly object _lockObj1 = new object(); private static readonly object _lockObj2 = new object(); [HttpPost("trigger")] public IActionResult TriggerHang() { // 构造死锁逻辑 new Thread(() => { lock (_lockObj1) { Thread.Sleep(100); lock (_lockObj2) { } } }).Start(); lock (_lockObj2) { Thread.Sleep(100); lock (_lockObj1) { } } // 代码永远不会运行到此处 return Ok(); } }
接口调用后会立刻产生死锁,占用应用线程池资源,后续包括健康检查在内的所有请求都会超时无响应,可直接验证Liveness probe是否会按预期触发Pod重启。
方案2:通过后台任务自动触发挂起
适合不需要人工干预、应用启动后指定时间自动进入挂起状态的测试场景。
- 首先在
Startup.cs的ConfigureServices方法中注册后台服务:
services.AddHostedService<HangBackgroundService>();
- 实现后台服务类:
using Microsoft.Extensions.Hosting; using System; using System.Threading; using System.Threading.Tasks; public class HangBackgroundService : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // 可自定义应用启动多久后触发挂起,示例为启动1分钟后触发 await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); var lockObj1 = new object(); var lockObj2 = new object(); new Thread(() => { lock (lockObj1) { Thread.Sleep(100); lock (lockObj2) { } } }).Start(); lock (lockObj2) { Thread.Sleep(100); lock (lockObj1) { } } } }
注意事项
- 上述代码仅可用于测试环境,严禁合入生产环境代码分支,避免引发线上故障
- 测试完成后及时删除相关代码,也可添加条件编译标记仅在测试构建时生效,示例:
#if DEBUG // 测试用挂起逻辑代码 #endif
内容的提问来源于stack exchange,提问作者user584018
相关产品推荐
相关产品推荐

