后端面试中,Linux、网络和线上排查经常会连在一起问。一个典型追问是:你知道 epoll,那线上接口突然变慢时,它和线程池、连接池有什么关系?这个问题不要求你背内核源码,而是看你能不能把底层知识转成排查能力。
很多线上慢请求并不是 CPU 打满,而是大量线程或协程在等待:等数据库连接、等下游响应、等锁、等网络返回。看起来服务还活着,但有效吞吐已经下降。
epoll 解决的是等待方式,不解决业务慢
epoll 的价值,是让一个线程高效监听大量文件描述符事件,避免为每个连接分配一个阻塞线程。它适合高并发网络 IO,但它不等于系统一定快。事件到了之后,业务处理仍然可能慢;下游慢,连接池满,应用层队列堆积,都会让请求变慢。
面试里可以这样说:IO 多路复用提升的是等待连接事件的效率,但请求全链路还包括应用处理、数据库、缓存、外部服务和序列化。不能因为用了 epoll 或异步框架,就忽略下游瓶颈。
连接池耗尽是高频事故形态
连接池耗尽常见于数据库、Redis、HTTP 客户端。原因可能是下游变慢,连接长期不释放;也可能是超时时间过长,失败请求堆住;还可能是代码没有正确关闭连接。
接口大量超时:可能原因是下游响应慢,排查证据是分段耗时和下游错误率。线程数升高但 CPU 不高:可能原因是线程都在等待,排查证据是线程栈和连接池等待数。
- 数据库连接池满:可能原因是慢 SQL 或事务太长,排查证据是慢查询、活跃连接、锁等待。
- 重试后更慢:可能原因是流量被放大,排查证据是重试次数和失败比例。
排查顺序要先收敛影响
真实事故里,不要一上来就钻进某个命令。先看影响范围:是单接口还是全站,是单实例还是全量,是刚发布后出现还是流量上来后出现。然后再看资源:CPU、内存、线程、连接池、下游耗时、错误率。
如果确认是下游慢,继续无限重试只会加剧问题。更稳的动作是限流、降级、缩短超时、关闭非核心功能,或者把重试改成退避策略。恢复服务和保留证据要一起做。
面试里的完整表达
可以这样回答:我理解 epoll 解决的是高并发连接等待问题,但线上慢请求还要看应用层资源。接口变慢时,我会先确认影响范围,再看线程栈、连接池、下游耗时和错误率。如果发现连接池耗尽,会继续判断是下游慢、慢 SQL、事务过长还是连接泄露。修复时不会盲目加连接数,因为那可能把压力转移给数据库。这样的回答能把底层知识和稳定性经验连起来。
这类题还可以主动补充“不要只加机器”。如果瓶颈是数据库慢查询或下游超时,扩容应用实例只会制造更多请求,把下游压得更慢。先定位瓶颈,再决定扩容、限流、降级、修 SQL 还是调整连接池,顺序比动作本身更重要。