개요
14시 2분을 기점으로 responseTime이 폭발적으로 증가하며 전체 서비스가 마비됨
API 성능 문제 발생
원인분석
동일 시간대 CRM 마케팅으로 인한 접속자수 증가 이슈가 있었던 것으로 원인 파악이 진행됨
CloudWatch 로그
특정 시간에 서버 내의 웹 프로세스가 재시작되는 이슈가 무한 반복되고 있음.
ECS 로그
2025년 4월 23일 14:02 (UTC+9:00)
service tirepick-service-prod has stopped 1 running tasks: task 3ec6dcf9e23242b98eeb69eec5e7ec20.
57cf2328-1908-4ed7-b81c-dddbf450cd75
2025년 4월 23일 14:02 (UTC+9:00)
service tirepick-service-prod port 80 is unhealthy in target-group tirepick-target-prod due to (reason Request timed out).
35e07f47-06f4-496d-b070-fbcff91b65f0
2025년 4월 23일 14:02 (UTC+9:00)
service tirepick-service-prod registered 1 targets in target-group tirepick-target-prod
fc1bc1f6-58ca-4a77-be52-fe4004491390
JavaScript
복사
문제 발생 시간 대에 task에 대한 헬스체크가 정상적으로 이뤄지지 않고 있음을 확인
일주일간 Memory 사용률
서버의 메모리 사용률이 평소대비 크게 올랐으며 4월 17일에도 동일한 Spike 트래픽으로 인한 Memory 리소스 사용률이 증가했음을 확인
전반적인 로그를 분석해본 결과, 서버 메모리 문제로 추정되지만 실제 리소스 사용률은 약 30% 수준에 불과함. 이는 웹 서버 자체나 이를 관리하는 PM2의 설정에 의해 발생했을 가능성이 있어, 배포 워크플로우에 사용되는 ecosystem.config.js를 확인해본 결과 max_memory_restart 옵션이 설정되어 있어 메모리 상승 시 자동 재시작이 발생한 것으로 보여 개발 테스트 시에도 동일한 문제가 발생 할 수 있는지 테스트 진행
ecosystem.config.js
// eslint-disable-next-line @typescript-eslint/no-var-requires
const config = require('./package.json');
module.exports = {
apps: [
{
script: 'dist/src/main.js',
kill_timeout: 12000,
instances: 1,
exec_mode: 'cluster',
max_memory_restart: '3000M',
error_file: '/dev/null',
out_file: '/dev/null',
env_staging: {
name: config.name + '-staging',
NODE_ENV: 'staging',
},
env_qa: {
name: config.name + '-qa',
NODE_ENV: 'qa',
},
env_prod: {
name: config.name + '-prod',
NODE_ENV: 'prod',
},
},
],
};
JavaScript
복사
개발 테스트 시
•
메모리를 극단적으로 줄인 뒤 개발에서 테스트 진행 시 아래와 같은 메시지와 함께 pm2 내의 프로세스가 무한 재시작되는 현상이 확인됨
[PM2][WORKER] Process 0 restarted because it exceeds --max-memory-restart value (current_memory=416059392 max_memory_limit=104857600 [octets])
JavaScript
복사
운영 로그 확인
•
17일 로그 확인 시 동일한 현상을 운영에서도 확인, 다만 23일 증상이 발생한 시점엔 해당 로그 확인이 되지 않아 로그 유실로 추정
[PM2][WORKER] Process 0 restarted because it exceeds --max-memory-restart value (current_memory=3546050560 max_memory_limit=3145728000 [octets])
JavaScript
복사
조치 및 결론
결과적으로 Spike 트래픽으로 인해 API 서버의 전반적인 리소스가 상승하였고, 서버 및 RDS 리소스 상에는 정상이었으나, 실제로 웹서버의 메모리가 35%(3000M) 이상 사용되는 경우 재시작이 되면서 서비스가 종료되는 현상으로 확인됨
현재 문제로 추정되는 PM2 프로세스의 max_memory_limit 값을 상향 조정 및 메모리에 따른 수평확장을 위한 오토스케일링 정책 수립
다만 Node.js V8 엔진 특성상 Heap 메모리는 1.5~2GB로 제한되어 있으며 하나의 서버 인스턴스가 3GB 이상의 메모리를 점유한다는 점에 의문점이 있으며, 이는 메모리 누수가 되는 부분이 의심되고 있어 단순히 임계치를 올려 설정하는 것 외에도 근본적인 원인을 찾아야 할 것으로 보임