(node:31) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 exit listeners added to [Bus]. Use emitter.setMaxListeners() to increase limit 2023-12-20 20:05:28 (Use `node --trace-warnings ...` to show where the warning was created)
위같은 경고가 떴다.
원인
1. 메모리 관리를 못해서 필요하다는 경고
2. 외부 서비스 붙일 때, 이벤트 리스너를 추가하게 되는데 너무 많이 붙이면 경고 발생 가능함.
Node.js에서 Redis, MySQL, RabbitMQ와 같은 외부 서비스를 사용하는 경우 이벤트 리스너를 추가하게 됩니다.
이러한 외부 서비스는 각각 연결을 유지하고 이벤트를 처리하기 위해 이벤트 리스너를 사용합니다.
따라서 이러한 외부 서비스를 여러 개 사용하는 경우 이벤트 리스너의 수가 증가하고, 이로 인해 MaxListenersExceededWarning 경고가 발생할 수 있습니다.
라고 한다.
그래서 보통 아래처럼 바로 max listener 수를 지정하곤 한다.
process.setMaxListeners(0);
위처럼 max listener 제한을 제거하면 경고가 제거되지만 원인은 제거되지 않으며 리소스 누출 원인에 대한 경고가 표시되지 않는다.
참고로 기본값은 10이다. (그래서 11개가 넘었다는 경고가 뜬 것이다.)
합당한 이유로 MaxListeners에 도달했을때만 값을 증가시키는 것을 추천한다고 한다.
require('events').EventEmitter.defaultMaxListeners = 15;
만약 MaxListeners 를 설정해야하는 경우라면 defaultMaxListeners 속성의 값으로 설정하는 것을 추천한다.
해결
나의 경우에는 1번과 같이 메모리 관리에 문제가 있었다.
export const refreshVerifyToken = async (token: string, userId: number) => {
const { TOKEN_REFRESH_SECRET } = logTokenSecret();
const getAsync = promisify(redisCli.get).bind(redisCli); //문제지점
if (!token) return null;
try {
const data = await getAsync(userId);
if (token === data) {
try {
return jwt.verify(token, TOKEN_REFRESH_SECRET);
} catch (err) {
return false;
}
} else {
return false;
}
} catch (err) {
return false;
}
};
Redis와 같은 외부 서비스와의 연결에서는 연결을 끊어주는 것이 중요하다.
일반적으로 이벤트 리스너가 연결 이벤트를 감지하고 해당 연결에 대한 이벤트 리스너가 등록되어 연결이 종료될 때까지 리스너가 유지되기 때문이다.
그러나 bind 함수를 사용하여 이벤트 리스너를 연결할 때는, 해당 이벤트 리스너가 수동으로 제거되지 않는다.
따라서 여러 번 호출되면 이벤트 리스너가 중복 등록되어 메모리 누수와 같은 문제를 야기한다.
이를 방지하기 위해서는 Redis 연결이 끝날 때마다 이벤트 리스너를 명시적으로 제거하거나, bind 함수를 호출하는 것을 피하는 것이 좋다.
즉, 커넥션을 계속 연결만 하고 remove를 안해줘서 커넥션 수가 늘어나기만 했던것이다.
위 코드를 수정하면 된다.
const result = jwt.verify(token, TOKEN_REFRESH_SECRET);
redisCli.quit();
return result;
연결 후 종료를 시켜준다.
참고
https://stackoverflow.com/questions/8313628/how-to-emitter-setmaxlisteners
https://stackoverflow.com/questions/67684821/unable-to-manage-redis-connections-properly-in-express
'JaveScript > NodeJS' 카테고리의 다른 글
nvm 버전 변경 (0) | 2024.05.24 |
---|---|
jest 테스트프레임워크 공부중 (0) | 2024.05.23 |
npm 배포하기 (0) | 2024.05.19 |
NodeJS 로그 터미널에서 확인하기 (0) | 2023.07.19 |
JavaScrpit과 NVM, NPM (0) | 2023.07.13 |