标准答案
- 事件循环中的同步文件、网络、加密或大计算会阻塞同一循环上的所有连接。
- 线程池中的阻塞任务会占满工作线程,后续请求只能排队,最终触发超时和重试。
- 应识别阻塞库和慢下游,把可隔离的工作放入有界专用执行器,并设置截止时间和拒绝策略。
- 验证时要结合事件循环延迟、线程池活跃数、队列长度、下游耗时和请求 P99。
题目解析
事件循环或工作线程被阻塞时,其他请求不是“变慢一点”,而是失去执行机会,只能在连接、线程池或网关队列里等待。因此 P99 往往比平均延迟更早暴露问题。
把阻塞调用移到专用池可以保护主路径,但只是把等待转移到另一个资源边界。专用池仍需要有界并发、获取超时、任务取消和过载时的明确失败行为。
排查时要把代码调用栈和运行时指标对齐:事件循环延迟、线程池活跃数、队列年龄、连接池等待和下游耗时一起升高时,通常比单看 CPU 更能说明阻塞问题。
常见误区
- 误区:在事件循环线程里继续加入同步文件、网络或大计算。改正:识别阻塞边界,改用非阻塞 API 或放入有界专用执行器。
- 误区:创建无界线程池吸收所有阻塞任务。改正:无界池只会把线程和内存耗尽延后,应设置上限、队列和拒绝策略。
- 误区:CPU 不高就排除阻塞。改正:线程可能在锁、网络或文件 I/O 上等待,必须结合线程状态和等待事件定位。