服务跑上一段时间,控制台就出现 MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 request listeners added 这样的警告,同一时间内存曲线也开始缓慢往上走,重启后又能安静一阵。日志里能对上时间点,这种反而好排。
每次请求都给同一个事件中心加监听却没有移除,监听器数组越堆越长,回调闭包里引用的对象跟着一起留在内存里,压力一上来就明显了。这一点先确认清楚,后面就不用反复试。
emitter.setMaxListeners(20);
emitter.once('data', handler);
emitter.off('data', handler);
这次卡住的地方就在「MaxListenersExceededWarning」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。
日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
处理上按这个顺序:先定位到底是谁在哪个事件名上反复添加监听;改成只监听一次,或者在回调的末尾把它移除;确实需要多个监听时再调高上限并评估一下内存。
结果对不对很好判断,警告消失,不同请求之间的监听数量保持稳定,内存曲线也平了。
