이번에 아마존 EC2 인스턴스를 12개월 동안 무료로 사용할 수 있는 프리티어 기간이 끝난다는 메일을 받았다.
아무생각 없이 영원히 이용할 수 있을 것 같았던 EC2가.. 끝이라니..! 무료 사용 종료는 2020년 4월 30일.. 이번달이 지나고 나서 온디멘드 요금으로 전환된다.
그래서 그냥 유료로 기존 EC2 서버를 운용 할 것인가. 아님 그냥 서비스를 종료할까, 아니면 다른 서버로 이주해서 계속 서비스를 할 것인가 고민을 많이 했다.
고민끝에 서버를 이전하기로 했고, 기존 EC2 서버는 더 이상 요금이 발생하지 않도록 삭제하기로 했다.
1. EC2 인스턴스 종료 및 삭제
인스턴스 중지
EC2 인스턴스를 삭제하기 전에 실행중이라면 인스턴스를 종료해주자.
1. EC2 대시보드에서 인스턴스를 눌러주자.
2. 삭제하려는 인스턴스 선택
3. 인스턴스 상태 클릭
4. 인스턴스 중지 선택
정지할꺼냐고 물어보는데 중지를 눌러줍시다.
상단에 성공적으로 중지됐다고 나오고, 인스턴스 상태가 중지됨으로 나오면 완전히 중지된 상태이다.
인스턴스 종료(삭제)
이제 인스턴스를 삭제할 꺼다. 예전에 AWS 처음 할 때 저 인스턴스 종료가... 그냥 윈도우 잠깐 시스템 종료 해두듯이. 그냥.. 단순 종료인줄 알았는데.. 저거 서버 삭제다.. ㅋㅋ 아무생각없이 눌렀다가 서버 날아가서 오열했던 기억이 잠깐 난다.
1. 삭제할 인스턴스 선택
2. 인스턴스 상태 선택
3. 인스턴스 종료 선택
진짜 삭제할꺼냐고 묻는다. 종료를 눌러주자.
그럼 성공적으로 종료되었다는 메시지와 함께 인스턴스 상태를 보면 종료됨으로 표시된다. 처음에 어..? 삭제 끝났는데 왜 목록에 자꾸 남아있지!? 하고 이상해했다. 계속 새로고침을 눌러봐도 종료됨으로 떠있어서 이게 삭제가 아닌가? 했는데 한 5~10분 지나면 목록에서 사라진다 ㅋㅋ..
몇분 후면 이렇게 목록에서 사라져있다 ㅎㅎ 여기까지 EC2 인스턴스 삭제는 끝이다.
하지만, 인스턴스만 삭제고, 나머지 EIP 등으로 과금이 생길 수 있기때문에 깔끔하게 다른 것 까지 지워주자.
2. EIP 삭제 (Elastic IP / 탄력적 IP)
EIP를 사용하지 않고 유동 IP를 사용했다면 추가 과금 될 것은 없다. 하지만 서버에서 서비스를 운영하는 입장에서는 보통 고정 IP를 쓰고 프리티어에서 1개의 EIP는 무료로 사용 할 수 있기 때문에 아마도 다들 EIP 할당이 되어있을 것 같다.
EIP는 프리티어에서 1개까지는 무료지만, EIP할당 받아놓고 인스턴스를 Run 해놓지 않으면 과금이 발생한다. 보통 대학생들이 AWS에 돈나갔어요 ㅜㅜ 한번만 봐주세요 하고 보내는는 이유중, 이런 사유로 발생하는 경우가 많다 ㅋㅋ..
AWS 입장에서는 고정 IP를 한정적으로 가지고있고, 여기에 인스턴스가 돌아가지 않고 있다면, IP 자원 하나를 손실보는 것이기 떄문에 인스턴스가 안돌아가는 경우 과금을 하는 것 같다. 이제 할당된 EIP를 삭제하는 법에 대해 알아보자.
1. 좌측에 탄력적 IP를 눌러주자.
2. 삭제하려는 IP를 선택해주자.
3. 상단 작업을 클릭
4. 탄력적 IP 주소 릴리즈 를 눌러주자
진짜 삭제할 꺼냐고 묻는다. 릴리스를 눌러주자.
일단 여기까지 하면 보통 과금될 일은 없다. 추가적으로 AWS S3, Route 53, RDS, 스냅샷 을 사용할 경우 이 서비스들 각각 다 서비스를 삭제해주면 된다. 하지만 난 S3, RDS를 사용하지 않고 Route 53은 계속 사용할 것이기 떄문에 일단 여기까지만 했다.
다음은, 과금에 영향은 없지만 이 EC2와 관련된 것은 다 지우고 싶다 할 경우 진행하면 된다.
3. 보안그룹 삭제
일단 기존 EC2 에서 사용되었던 보안그룹도 삭제할 것이다. 보안 그룹이 뭐지? 하는 사람은 머.. 방화벽 정책정도로 생각하면 될 것 같다. 나중에 다시 EC2 인스턴스를 올려서 동일한 방화벽 정책을 사용할 경우에는 남겨두어도 좋지만, 난 라이트세일 서버로 이전했기 때문에 필요 없어서 지웠다. 머.. 나중에 EC2 인스턴스를 다시올릴때 필요하다면 다시 만들려고 한다. 머 어차피... DB포트정도만 열면되기 떄문..
1. 네트워크 및 보안 탭에 보안그룹을 클릭
2. 삭제하려는 보안 그룹 선택
→ 2번에 빨간 박스친 밑에 default 보안그룹은 말그대로 기본 설정이기 때문에 안지워도 된다. 본인이 만든것만 지우면 되기때문에 디폴트는 걍 무시한다.
3. 작업 선택
4. 보안그룹 삭제 선택
진짜 삭제할 꺼냐고 물어본다. 삭제를 눌러주자.
짜잔 삭제 완료
4. 키 페어 삭제
이제 기존 EC2 서버 접속간 사용했던 키페어를 삭제할 예정이다. 이거 머 삭제해도 되나..? 한번 고민은 해봤었는데 어치파.. 기존 EC2 접속에만 사용했었기 때문에 더 이상 그 인스턴스는 필요하지 않으니, 삭제해도 상관 없을 것이라고 판단됐다.
1. 네트워크 및 보안 키 페어 클릭
2. 삭제하려는 키 페어 선택
3. 작업 클릭
4. 삭제 클릭
그 다음 진짜 삭제할꺼냐고 묻는데 상당히 중요한 판단인가본지 직접 "삭제"라고 타이핑 하고 진행하라고 한다. 일단.. 삭제하기로 맘먹었기 때문에 그냥 삭제 치고 삭제를 누르자.
짜짠.. 키 페어 삭제 완료
삭제 후기
삭제 후기? 별거 없다. AWS 프리티어 1년간 정말 잘 썼다. 앞으로 이거 관련해서 추가 과금은 없겠지..? ㅎㅎ 요금 폭탄 안나오길 바란다.
톰캣 로그를 확인하니, 발생 했을 때로 추정되는 시간때에 모두 java.lang.OutOfMemoryError: GC overhead limit exceeded 오류가 찍혀있었다.
GC에 대해서 간단하게 알아보고 넘어가보자. JVM은 메모리 확보를 위해서 GC를 수행한다. 대학 Java 시간에 잠깐 배웠던 그 GC가 맞다 바로 가비지 컬렉션(Garbage collection)이다. 더 이상 사용되지 않는 객체에 대해서 메모리를 해체해주면서 메모리 풀을 관리해주는 친구다.
근데 저 GC overhead limit exceeded 메시지는 왜 띄었는가..?
* GC를 진행하는데 CPU 98% 이상 사용
* GC 진행 후 메모리 2%미만이 복구 되었을 때
일단은 메모리가 부족했던 걸까? 생각이 들었다. 찾아보니, 위 문제에 직면한 경우 보통 JVM 옵션으로 힙 리밋 제한을 없애거나 메모리 사용량을 늘리라고들 하더라. 사실. 나는 이런 셋팅쪽 문제가 아닐거라고 개인적으로 생각은 들었지만, 팀 내부적으론 일단 메모리 부족으로 방향을 잡고, 톰캣, 자바 셋팅쪽을 손봤다.
하지만, 내 예상처럼 이런 증상은 셋팅으로 해결되지 않았다. 몇 일간 원인모를 이유로 서버는 다운됐다..ㅠ
그리고 GC 로그를 확인하기 위해서 서버에 GC로그를 남기는 설정도 추가하여 해당 문제가 발생했을 때 GC로그를 확인했으나, "GC 할껀데 메모리 없어~~~" 사실상 이런 내용만 도배되어있었다. 그런데 GC 시도 엄청 많이 했긴 했더라......암튼 이문제를 해결하는데 GC로그는 도움되지 않았다..
단서 3. 특정 요청에 문제가 생기는 것은 아니었다.
이게 어떤 특정요청에만 생기는 현상일까 생각이 들었다. 머 배치가 돌때 먼가 잘못 도는게 있는걸까? 아니면 사용자가 이상한 파라미터를 던져서 처리를 못하나...? 신기하게도 새벽에는 이런일이 발생하질 않네?.. 해서 의심이 갔었다.
문제가 발생했었을 때의 로그를 확인했으나, 공통점은 없었다. 심지어 GC error 가 발생한 해당 요청을 같은 파라미터를 넣고 다시 요청해도 같은 현상은 발생하지 않았다.
결론부터 말하자면, 특정한 요청이 문제가 됐었다. 다만, 내가 바로 찾지 못한 이유는, 이미 문제가 발생한 이후에 로그에 찍힌 GC error 로그에만 집착했기 때문이었다. 일단은 GC error 로그가 어떤 요청에 찍혔다 하더라도, 그 요청이 문제가 아니라는 거다. 이미 문제는 발생했고, 우연히 그 요청을 처리중일 때 GC 가 동작하여 error 을 띄운거란거다.
만약 이방법으로 간단하게 볼려면, GC Limit 이 발생하기 전 로그들을 뒤져봐야 한다.
이런 현상이 지속되고, 팀원들이 이 문제를 해결하기 위해 이미 붙어있었기 때문에, 내 업무를 좀 쳐내고 나중에 시간이 남으면 보려고 생각했다. 뭐 그때쯤 가서 이미 해결이 되면, 좋은거긴 한데, 나는 셋팅쪽 문제가 아닐꺼란 생각이 계속 들었다.
단서 4. 힙메모리 사용량 증가
시간적 여유가 생겨 다시 문제를 분석해봤다. 보니까 해당 문제가 발생 했을 때 CPU사용량도 돌라갔었지만, 힙 메모리 사용량도 폭발적으로 증가하는 현상이 확인되었다.
왜 처음부터 힙메모리 관제에 신경쓰지 않았을까, 평소에 악성쿼리처럼 CPU를 많이 점유하던 장애를 주로 만났었기 때문에 메모리보다는 CPU 사용량이나 어떤 요청이 왔는지 이런거 위주로 봤던게 좀 방심했던 것 같다.
원래 힙메모리 사용량의 이상적인 그래프는 맨 아래 그래프처럼 어느정도 메모리가 올라가다 GC가 작동하여 떨어지고, 계속 반복하여 적정한 수준을 유지하는게 이상적이다.
하지만 위 사진을 보다시피 3월 16일동안 3회나 01번 02번 WAS 힙메모리 점유율이 급격하게 올라가는 것을 볼 수 있다.
문제 해결을 위한 방향성 잡기
자 여기까지 정리를 해보자.
1. 새벽이 아닌 주야간 워크 타임때, 그리고 불특정, 비규칙적인 시간에 서버가 다운이 된다.
2. CPU 사용량과 힙 메모리 점유율이 급격히 상승한다.
3. 서버 에러 로그에는 GC overhead limit exceeded 이 발생한다.
자 일단 에러로그에 GC 할 메모리가 부족하다고 되어있어서 GC에만 문제가 있었던건가 여기에만 집중했지만, 내 생각에는 이건 메모리가 부족해지고 나서, 즉 어떤 문제가 발생하고 그 이후에 파생된 현상이지 주 원인은 갑작스럽게 메모리를 차지한 어떤게 있을거라고 생각했다.
즉, 어떤 원인에 의해 메모리가 급격하게 사용되었고, 그 이후에 평소처럼 GC를 하려니 GC 리밋 로그를 띄운 것 이다. 나도 그랬지만, 보통 다른 사람들도 이 GC 리밋 에러 로그를 보고, 왜 GC 리밋 로그를 띄었을까..? 검색해보면 "서버 힙메모리가 부족하네요 ㅎㅎ" 이럴텐데 이렇게 접근해서는 해결 할 수 없는 문제였다. (내 케이스의 경우)
자. 정리하자면 GC 관련된 문제가 아닐꺼다, 무언가가 힙메모리를 엄청나게 차지하니까, 당연히 GC도 못하니 저 오류를 띄운거고, 우리는 앞으로 어떤 녀석이 힙메모리를 그 순간에 차지하고 있었는지를 찾아야한다.
앞으로 해야할게 바로 힙메모리 분석이다. 다음 포스팅을 통해서 힙메모리 분석을 어떻게 했고, 어떤게 원인이었으며, 어떻게 조치했는지에 대해서 알아보자