갑자기 EC2 인스턴스에 배포한 서버가 다운되었는데 이유가 무엇일까?
상황
--
전날까지만 해도 정상 동작하던 서버가 갑자기 접속이 불가능해졌다.
1. 초입을 담당하는 로드밸런서(ELB)를 먼저 확인
ELB에서 전체적인 상황을 보기 위해 "리소스 맵"으로 이동하여 확인한 사진으로
현재 최종 목적지인 EC2의 인스턴스에서 "Request timed out"으로 연결이 불가능하다는 것을 알았다.
Request timed out은
ELB가 인스턴스(대상)와 연결을 시도했으나 응답이 없어서 타임아웃이 발생했다는 의미다.
2. EC2 인스턴스 상태 확인
해당 인스턴스의 상태검사에서 "1/2개 검사 통과" 상태를 확인할 수 있었다.
인스턴스의 상태 검사 종류
1. 시스템 상태 검사 (System Status Check) : AWS 인프라(AWS의 하드웨어, 네트워크 등)와 관련된 문제 확인
2. 인스턴스 상태 검사 (Instance Status Check) : 인스턴스 내부에서 발생한 문제 확인
3. EC2 인스턴스의 자세한 상태 확인하기
상태 검사를 자세히 모녀 "인스턴스 연결성 검사 문제"인 것을 확인했다.
이로 인해 인스턴스에 대한 상태 검사에서 실패했다는 것을 알았다.
즉, 인스턴스에서 문제가 생긴것이다.
인스턴스에 연결하여 접근이 불가능하다.
4. EC2 인스턴스 모니터링
인스턴스 모니터링을 통해 CPU의 사용률이 특정 시간 동안 99.9%에 도달했던 기록을 확인했다.
아마 CPU에 과부하가 와서 인스턴스가 다운된 것으로 추측했다.
CPU 사용률이 높아질 원인
- 애플리케이션의 무한 루프 or 비효율적인 코드 실행
- 서버에서 과도한 트래픽 처리
- 잘못된 설정으로 백그라운드에서 불필요한 프로세스 실행 (+ 스케줄링된 작업)
- 메모리 부족으로 인한 스왑(swap) 발생
- 외부 공격
- 자동 업데이트 or 패치 (운영체제 업데이트 or 애플리케이션 업데이트)
- 로그 or 에러 출력 과도
등이 존재한다.
우선 CPU 사용률이 99.9%에 도달한 시간대에 아무도 해당 서버에 접근한 적이 없다.
즉, 어떠한 작업을 동작시킨 적이 없는 상태였다.
5. 인스턴스 로그 확인하기
로그 사진을 캡처 못함..
다만 어떠한 이상 현상을 발견하지 못했다.
기억으로는 서버를 동작시킬 때 찍힌 로그 외에는 없었다.
--
해결 방안 탐색
--
우선 로그를 확인해 보았다.
[2121845.503360]
Out of memory: Killed process 146836 (java) // 메모리 부족으로 인해 프로세스 ID146836 프로세스가 종료됨
total-vm:2394004kB, // java 프로세스는 약 2.4GB의 가상 메모리를 사용했으며
anon-rss:381340kB, // 익명 페이지(anon-rss)에서 약 380MB를 사용했다.
file-rss:128kB,
shmem-rss:0kB,
UID:0 pgtables:1072kB oom_score_adj:0
마지막에 위와 같은 로그가 찍혀있는 것을 확인할 수 있었다.
Out of memory (OOM)는
인스턴스에서 실행 중인 프로세스가 강제로 종료되었다는 것인데
이는 시스템의 메모리가 부족해서 발생한 것으로,
java 애플리케이션이 많은 메모리를 사용하면서 다른 프로세스나 시스템 전체에 영향을 미친 상황으로 보인다.
추측되는 원인들
- 메모리 누수 : 작업한 자원을 적절히 해제하지 않고 쌓여서 점점 더 많은 메모리를 차지하게 됨
- 백그라운드 작업 : 백그라운드에서 주기적으로 데이터를 수집하는 작업으로 인해 점점 많은 메모리가 쌓여감
- 가비지 컬렉션(GC) 문제 : 가비지 컬렉터의 메모리 회수 방식에 문제 or GC가 자주 실행하여 CPU 사용량 증가
- 버그 및 무한 루프
- AWS 서버 문제 (가능성이 가장 낮음)
위 일부 예측 원인들은 점진적으로 CPU 사용량이 늘어나야 하는데
현재 인스턴스에서는 갑자기 CPU 사용량이 100%를 찍은 것으로 보아
해당 원인들은 아니라고 판단했다.
- 외부 공격 : 디도스(DDos)처럼 외부에서 트래픽 공격을 당함 (가능성 낮음)
- 스케줄러 : 스케줄러로 인해 특정 일정 시간에 대규모 작업을 처리
배포한 서버에서 작성한 스케줄러는
매년 초에 동작하거나 A동작을 수행하고 나서 7일 후에 동작하는 스케줄러이므로
아직 연초가 아니고 A동작은 수행하지 않았으니 스케줄러는 아니다.
알아낸 원인들은
현재 "인스턴스 연결성 검사 실패"가 발생한 원인이라고 하기 어려워 보인다.
우선 결과적으로
AWS 문제가 아니라면 내 코드 문제이므로
코드를 다시 살펴보던지 다른 설정을 하던지
결국엔 인스턴스를 재시작해야 한다.
번외
프리티어는 현재 CPU 크기가 작으므로
보조기억장치(하드 디스크)에 가상 메모리를 할당해서 사용하는 방법도 존재한다.
속도는 느리지만 그래도 메모리 공간을 부족하지 않도록 하므로
위와 같은 문제에 대해서는 안정성이 있어 보인다.
--
'AWS' 카테고리의 다른 글
[S3] S3 버킷에 정책 설정하기 (0) | 2024.11.13 |
---|---|
[S3] S3란? (3) | 2024.11.13 |
[ELB] ACM(SSL/TLS 인증서)를 통해 HTTPS 설정하기 (+ HTTP요청시 HTTPS로 자동 리다렉트) (0) | 2024.09.06 |
ACM 인증서 (0) | 2024.09.05 |
[ELB] ELB 생성 (0) | 2024.09.05 |