概述
其实不是阻塞,但不知道怎么用一句话描述,具体现象后面有详细讲。
用的是 request. 伪代码如下
let count = 100;
function batch() {
// 从数据库用 SELECT ... LIMIT 100 取出 100 条 url
for (let url in urlList) {
const req = request(...);
req.on('error', () => {
// 一些其它操作
count--;
if (count === 0) {
count = 100;
batch();
}
});
req.on('end', () => {
// 一些其它操作
count--;
if (count === 0) {
count = 100;
batch();
}
});
}
第一波发出去的请求是正常的,过了几波后,在创建完 request, 控制权交还给事件循环时, 要等好长时间才会开始发请求,这个等待的时间会越来越久。试过调整连接池,但只能缓解,不能解决。
大家有没有碰到过类似的问题?或者有没有排查问题的思路?
等待发请求时的具体现象
- 通过打印日志,确定:
- 计数器工作正常
- 创建 request 对象的那个循环已经执行完了
- 但是
- lsof 看到没有创建任何 tcp 连接(前面的数据库连接除外)。
- 没有任何 request 的调试日志输出
- 用 gdb backtrace node 进程,看到几个线程是阻塞在 poll 上,其余几个线程是阻塞在信号量上
- 等待一段时间后
- 出现 request 的调试日志输出, lsof 看到 tcp 连接
- 这个等待时间会越来越久