본문 바로가기
👾 Server/👻 장애

[서버 장애] AWS 프리티어 배포 후 장애 - CPU 사용률 100%, 크레딧 0개 이후 ssh 접속도 안되는 상황과 해결 (HW / SW(페이징 limit 문제)

by kukim 2022. 6. 9.

상황

ec2 환경
ec2 : AWS 프리티어 t2.micro
app : Docker 위에 Spring Server + Nginx

  외부 DB : 약 10만개 데이터가 있는 MySQL

 

airbnb와 유사한 숙박 앱 프로젝트를 했다. DB에 약 10만여개 더미 데이터를 넣고 배포했다. AWS 프리티어 ec2에 spring 배포하여 사용하던 중 클라이언트의 많은 요청 이후 서버가 아예 멈춰 응답을 해주지 않았고 ssh 접속도 되지 않았다.


문제

클라이언트의 많은 요청으로 CPU 사용률이 90% 이상으로 사용하다 CPU 크레딧을 모두 사용하여 CPU 성능이 떨어져 서버 응답이 매우 늦거나 아예 ssh 접속까지 안 되는 상황 발생 

 

CPU 크레딧을 모두 사용하고
CPU 사용이 아예 멈췄다.

해결하기 위한 시도

HW적 해결 1 : CPU 크레딧 초기화하기 위한 단순한 방법 (임시 방편)

방법 : 해당 ec2를 인스턴스 중지 -> 인스턴스 시작 방법을 통해 CPU 크레딧을 초기화하여 사용 

해결 : 웹 상의 AWS EC2 페이지에서 버튼을 클릭하여 임시 방편으로 죽은 서버를 살릴 수 있다. 

문제 : 인스턴스가 다시 켜지는 시간동안 서버가 내려간다 / 직접 GUI에서 버튼을 끄고 켜야 한다. / 문제 원인을 모른다.

 

HW적 해결 2 : CPU 크레딧 초기화 자동화하기(오토스케일링으로 ec2 설정) (임시 방편)

방법 : CPU 크레딧 초기화 단순 방법을 자동화한다.

해결 : 해당 ec2를 AMI로 만든 후 오토스케일링 작업으로 일정 시간마다 ec2를 다시 만든다. 

문제 : 비용 문제가 있었다. 오토스케일링을 단순히 1개만 설정한다. 1개 뿐이니 끄고 켜지는것은 자동이지만 재시작 중에 서버가 내려간다. / 문제 원인을 모른다.

 

HW적 해결 3 :  프리티어 ec2는 감사하게

무료로 사용하고 있으니 aws에 감사한 마음을 느끼자. 비용을 추가하고 좋은 서버를 산다..? 

 

HW/SW적 해결 : 모니터링을 통해 문제 원인 파악 (메모리 확보, 스왑 메모리)

방법 : ec2의 메모리 모니터링은 기본으로 제공되지 않았다. Cloudwatch를 활용해 모니터링하려다 일단 top 명령을 통해 확인했다. 장애 재현을 재현하고 점검하니 메모리를 약 50% 사용했다. 프리티어의 메모리(1GB)의 한계로 부족할까 하여 가상 메모리 스왑을 통해 메모리를 확보한다.

해결 : 메모리가 부족할 때 하드 디스크 -> 메모리로 임시로 사용한다.

문제 : 하드 디스크 공간의 일부를 메모리로 사용하므로 용량이 줄었다. / 장애 재현 결과 메모리 부족 상태가 아니었다.

부하 테스트를 해보니 메모리는 최대 50% 정도만 사용했다. 스왑 메모리 이후 3~40% 대로 떨어졌지만 이전과 같은 문제가 발생했다.

SW적 해결  : 모니터링을 통한 해결 방법 2 (CPU 작업이 많을 곳을 찾자 -> 페이징이 문제였다.) 

원인 : 장애를 재현했다. 문제는 특정 검색 조건에 맞는 숙소를 리스트로 조회하는 페이징 API가 있었다. 페이징 limit 수 제한이 없었다. 클라이언트가 한 번에 limit을 100, 1000개 이상 요청해 서버가 한 번에 처리할 수 있는 양의 문제가 있었다.

해결 : 페이징 API의 제한과 성능을 올려야 한다.

- limit의 최대 범위를 10~20으로만 제한한다.

- 페이징의 전체 개수를 매번 요청하는 것이 아닌 첫 번째 요청에만 count를 조회하고 두 번째 요청부터 클라이언트가 첫 번째 요청 때 받은 전체 개수를 e.g. cachedCount를 요청할 때 함께 보내 count() 쿼리를 반복적으로 실행되지 않도록 한다. (참고 : 페이징 성능 개선하기 (이동욱님))

 

모니터링을 되돌아 봤을 때

로그/모니터링과 장애 재현을 되돌아 보니 문제가 있다. AWS에서 제공해주는 기본 모니터링을 제외하고 배포하고 있는 서버에 직접 로그를 달지 않았다. 장애 재현하기 위해 어떤 곳에서 CPU 부하가 걸리는지 한 번에 알 수 없었고 직접 ec2에 접속해서 top 명령어를 띄운 후 팀원과 함께 손으로 직접 서버에 API를 날리는 작업을 했다. (제리와 함께 동시에 새로고침 50번 하고 cpu 부하 100% 라고 웃었다) 앞으로의 프로젝트에선 로그와 모니터링을 직접 추적하고 관리해야겠다. 또한 부하 테스트도 생각해볼 수 있었다.


요약 : 서버 문제가 발생했을 땐 모니터링과 로그를 확인하고 천천히 살펴보자. 장애 재현을 해보고 어떤 문제인지 분석하자 (페이징은 처음이라..) / 기존 프로젝트들은 더미데이터가 많아야 천 개 였다. 이번 프로젝트에서는 실제 환경과 유사하게 만들고 싶어 10만개이상 넣으니 코드에서 바로 문제가 발생했다. 실제 서비스 환경처럼 프로젝트하자


+a) 호눅스의 피드백

코드스쿼드 프로젝트 회고에서 호눅스가 글을 보고 마스터 과정에서 이야기해준 내용을 개인이 이해한대로 작성했습니다. 내용이 다를 수 있습니다.

AWS에서 메모리 모니터링이 안되는 이유

- ec2가 VM 처럼 작동한다. 이때 CPU, DISK 모니터링은 가능하지만 메모리는 내부 프로세스 확인이기 때문에 AWS가 개인 ec2에 접속하여 메모리를 모니터링 할 수 없다.

- 이를 위해서 개인이 ec2에 접속하여 AWS Cloudwatch-agent를 설치하여 ec2의 모니터링 정보를 aws에 보내줘 로그를 쌓을 수 있다.

 

기술 소개 : Naver pinpoint

네이버 오픈소스(Java)로 만들어진 모니터링 에이전트이다. APM(Application performance Management)라고 한다.

사용하려면 별도의 서버에 pinpoint를 올려 사용한다.

 

기술 소개 : ELK

ELK란 Elastic Search, LogStatsh, Kibana의 약어이다.

Elastic Search : 로그 저장 및 검색

LogStatsh : 로그 수집

Kibana : 로그 시각화 및 관리

를 할 수 있다.

ELK 공식 사이트 배너 중

 

댓글