← 전체 글로 돌아가기

웹 개발

작은 VPS의 메모리 부족을 swap 추가보다 먼저 확인한 순서

Node 프로세스가 죽을 때 swap부터 늘리지 않고, 메모리 압박의 원인을 좁힌 점검 노트.

새벽에 프로세스만 사라졌다

1GB VPS에서 Next.js 앱이 가끔 내려갔다. 로그에는 애플리케이션 예외가 없고 systemd가 재시작만 반복했다. 처음에는 swap을 크게 만들려고 했지만, 그 전에 커널이 정말 OOM으로 종료했는지 확인했다.

OOM 기록부터 찾기

free의 남은 메모리만 보고 판단하면 캐시까지 여유로 오해하기 쉽다. 커널 로그와 cgroup 제한을 같이 봤다.

free -h
journalctl -k --since '24 hours ago' | grep -i -E 'out of memory|killed process'
systemctl show myapp.service -p MemoryMax

여기서 Killed process가 Node PID를 가리켰고, 이미지 변환 작업과 앱이 같은 작은 서버에 올라가 있음을 확인했다.

프로세스별 사용량을 시간대와 연결했다

한 번의 top 화면보다 피크 시간의 기록이 필요했다. 배치 작업이 시작되는 시각과 RSS 요청이 몰리는 시각이 겹쳤다.

ps -eo pid,comm,rss,%mem --sort=-rss | head -n 10
systemd-cgtop

이미지 변환의 동시 실행 수를 1로 제한하고, Node에는 무작정 큰 힙 대신 상한을 두었다.

Environment="NODE_OPTIONS=--max-old-space-size=384"

swap은 안전망으로만 작게 뒀다

원인을 줄인 뒤 1GB swap을 추가했다. swap이 계속 사용되면 해결이 아니라 디스크 지연을 메모리 문제처럼 보이게 만드는 신호라고 적어 뒀다.

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

다음 배포에서 보는 기준은 단순하다. OOM 로그가 0인지, swap 사용량이 계속 상승하지 않는지, 무거운 배치가 웹 요청과 겹치지 않는지다.