서버 운영
서버에서만 에러가 날 때 체계적으로 찾기
로컬에서는 안 나는데 서버에서만 나는 에러는 환경 차이부터 확인해야 한다.
개발 환경에서는 완벽하게 작동하는데, 배포 후에는 서버에서만 간헐적으로 에러가 발생하는 경우가 있다. 특히 혼자 개발하면 로컬 환경만 믿다가 운영 환경의 차이를 간과하기 쉽다.
핵심은 서버 문제를 '서버 코드'의 문제로만 보지 말고, 환경 자체의 차이를 체계적으로 확인하는 것이다.
서버 로그 확인
먼저 서버에서 실제 어떤 에러가 발생했는지 로그를 본다.
# 어플리케이션 로그
sudo journalctl -u myapp -n 100 --no-pager
# 또는 특정 로그 파일
tail -f /var/log/myapp/error.log
서버 리소스 확인
로컬에서는 여유가 있는 리소스가 서버에서는 부족할 수 있다. 메모리, CPU, 디스크를 먼저 본다.
# CPU와 메모리
free -h
top -bn1 | head -20
# 디스크
df -h
du -sh /*
# 프로세스별 메모리
ps aux --sort=-%mem | head
네트워크 연결 상태
API 엔드포인트나 데이터베이스 연결이 로컬과 다를 수 있다. 방화벽, DNS, 라우팅 등이 영향을 준다.
# 포트가 열려 있는지
sudo ss -lntp
# 외부 API 연결 확인
curl -v https://external-api.com
# DNS 확인
nslookup database.server.internal
환경변수 확인
서버의 환경변수가 로컬과 다를 수 있다. 특히 배포 자동화 도구에서 환경변수를 잘못 설정했을 수 있다.
# 현재 환경변수
env | grep -E 'API|DATABASE|DEBUG'
# 또는 어플리케이션 프로세스의 환경
cat /proc/$(pgrep -f myapp)/environ | tr '\0' '\n'
파일 시스템 권한
로컬에서는 모든 파일에 접근 가능하지만, 서버에서는 파일 권한이 제한될 수 있다.
ls -la /app/data/
# 파일을 쓸 권한이 있는지 확인
라이브러리 버전 차이
로컬과 서버의 Node.js 버전이나 라이브러리 버전이 다를 수 있다. 특히 native 모듈을 쓰면 버전 차이가 문제가 될 수 있다.
node --version
npm list | grep -E 'critical|warning'
간헐적 에러 추적
간헐적 에러는 패턴을 찾기 어렵다. 어느 시간대에 발생하는지, 어떤 조건에서 발생하는지 로그에서 찾는다.
# 시간대별로 에러 개수 세기
grep "ERROR" /var/log/myapp/error.log | cut -d ' ' -f 1-2 | uniq -c
프로덕션 환경에서 디버깅
필요하면 로깅 레벨을 일시적으로 올리거나, 추가 로그를 삽입해서 어느 부분에서 에러가 나는지 확인한다.
- 서버 로그를 먼저 본다.
- 서버 리소스 상태를 확인한다.
- 환경변수와 파일 권한을 본다.
- 로컬과 서버의 라이브러리 버전을 비교한다.
마지막 확인
에러를 고친 후에는 로컬과 동일한 환경을 만들어서 재현 가능한 상태로 만들어야 한다. 그래야 다음에 비슷한 문제가 나올 때 빨리 찾을 수 있다.