💡 발단
아침에 일어나자마자 섬뜩한 슬랙 알림을 보게됐다.
EC2 CloudWatch를 확인해보니 CPU 사용률이 99%를 찍고 사실상 중지된 모습.
DB 커넥션은 급락했다.
서버가 정상 작동하지 않는다는 간접적인 신호인 것으로 파악했다.
원인 파악
시나리오 1 : 누군가의 무분별한 요청 ❌
몇주동안 잘 작동하고 있었기 때문에 외부 변수부터 찾으려고 했다.
CloudWatch에서 서버 요청 로그를 확인했다.
무분별한 해외 IP 요청 때문에 스레드 풀이 초과됐다는 레퍼런스를 봤었기 때문이다.
아래는 서버가 죽을 당시의 로그 기록.
확인해보니 헬스 체크 컨트롤러로 계속해서 요청이 들어오고 있었다.
그런데 이게 의문사의 원인이라고는 생각하지 않는다.
해외 IP가 특별한가?라는 생각이 들기도 하고 무엇보다 빈도수가 적었기 때문이다. (1분에 4번)
더 정확한 원인 파악을 하기 위해 로그 항목에 IP를 추가했다.
알아보니 172로 시작하는 IP는 가상 IP라고 한다.
그리고 가상 IP는 어떤 네트워크 그룹의 대빵이라고 한다.
나중에 알고보니.. Route 53로 HTTPS 호스팅을 할 때 설정했던 헬스 체크였다.
같은 VPC(보안 그룹)내에 있는 로드밸런서가 헬스 체크를 해주고 있었던 것 같다. (정확한 구조는 더 공부해야 할 듯하다)
분명 내가 설정했는데... 왜 잊었을까
의심해서 죄송합니다 팀원분들..
아무튼 외부의 요청은 EC2 의문사의 원인이 아니었다.
시나리오 2 : 메모리 용량 초과? (알아보는 중)
9월 27일에 찍어뒀던 (htop 명령어) 인스턴스 상태.
인스턴스에 메모리 용량이 서버의 필요 용량에 비해 적은 편이라고 생각하긴 했다.
그런데… 10일만에 메모리(300M)를 더 잡아먹을 일이 뭔지 모르겠다.
EC2 CloudWatch에서 기본저긍로 메모리, 디스크 용량을 모니터링할 수 없음.
CloudWatch Agent를 사용할 수 있지만, 과금 리스크가 있음
시나리오 3 : 스케줄러로 인한 스레드 풀 초과 (알아보는 중)
@Async 에서는 기본 스레드 개수를 50, 최대 스레드 개수를 100으로 잡아놓은 상태.
여기서 문제가 발생했을 수 있다고 생각한다.
시나리오 4 : 크레딧 모두 소진 ❌
https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/burstable-credits-baseline-concepts.html
https://chance-story.tistory.com/66
AWS에선 원래 인스턴스의 CPU 사용률보다 많이 CPU가 사용될 경우 유동적으로 조절해주는 버스트 기능이란걸 제공한다.
그리고 이 기능을 쓸 때마다 크레딧이란걸 쓰는데, 결국 비용으로 이어지는 것 같다.
그러나 지금까지 인스턴스의 CPU 사용률이 그렇게 높아진 적은 없기 때문에 패스.