본문 바로가기
aws

[AWS] EC2 서버 다운 현상 해결 과정

by s_hoonee 2023. 11. 5.
반응형
서버 장애 상황

EC2 프리티어이며 사용자 3~4명 어플의 간단한 crud API를 스프링부트로 열어논 상태였습니다. 근데 하루에 2~3번 CPU가 100%를 차지하며 1시간 가량 유지되다가 서버가 터졌고 (상태검사 실패) 서버에 대해 잘 몰랐던 저는 nohup.out 파일만을 보고 에러를 해결하기 시작하였습니다. 

 

아래는 제가 썻던 해결 메모장입니다.


(1)

2023-11-02T15:08:26.118Z  WARN 1290 --- [io-8080-exec-10] o.s.web.servlet.PageNotFound             : No mapping for GET /cluster/list.query 

10/30 -> 이런 요청이 옴  내 프로젝트에 저런 주소는 없음…

11/01 ->> 시큐리티 적용 후 일어나지 않음

 

(2)

Thread starvation or clock leap detected (housekeeper delta=48s763ms136µs340ns). 

10/30 -> 위 문장이 수십 개 뜸

11/01 ->> 히카리풀을 20으로 늘림 경과 보는 중

 

(3)

[nio-8080-exec-9] o.s.web.servlet.PageNotFound        

     : No mapping for GET /hudson 

10/30 -> 프로젝트엔 저런 주소가 없음 

11/01 ->> 시큐리티 적용 후 일어나지 않음

 

(4)

2023-11-02T17:14:57.707Z  WARN 1290 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 08001

2023-11-02T17:14:57.906Z ERROR 1290 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper   : HikariPool-1 - Connection is not available, request timed out after 119201ms. 

10/30->  데이터베이스 연결 실패가 뜸 

10/31 ->> 예상원인 pool이 부족해서 연결 가능한 쓰레드가 없어서 커넥트가 안됨

11/01 ->>> 풀 늘리고 경과 보는 중

 


문제상황(1)  - 프로젝트에 없는 주소로 요청이 들어옴

제가 설정한 api에 대해서만 요청을 하도록 스프링 시큐리티를 도입했고 아래 포스팅에 자세히 적어 놓았습니다!

(업로드 예정)

 

⭐️⭐️ 문제상황(2) -  Thread starvation or clock leap detected Dead Lock, hikari  ⭐️⭐️

1. 프로젝트의 한 thread 내의 별도 트랜잭션에서 추가적인 SQL문 실행이 필요해지면서 쓰레드가 커넥션을 더 필요로 하게 됨,

2. JPA 개념 중 영속성 컨텍스트 전략을 생각했을 때, 만약 서비스 메소드에서 2개의 다른 JPA레파지토리(extend)가 있고 각각 엔티티 매니저를 가지고 있을 때 엔티티 매니저는 DB연결이 필요한 시점에 각 각의  커넥션을 얻어야 한다. 이때 하나의 쓰레드에서 2개의 레파지토리(엔티티매니저)가 하나의 트랜잭션 범위에 있고 이 두개의 레파지토리(엔티티매니저)는 같은 영속성을 공유한다! 

3. 이때 엔티티 매니저가 2개니까 한 트랜잭션에 2개의 커넥션이 필요하다! 
그러나 쓰레드가 커넥션을 필요로 하는데 커넥션 풀에 자원이 부족하면 데드락이 발생한다. 쓰레드는 하나의 트랜잭션을 끝내지 못하고 쓰레드 Starvation 상황으로 이어진다. 이 상황에서 추가적인 다른 요청이 오면

4. 새로운 요청에 대한 작업을 할 쓰레드가 없어 NIO 커넥터가 계속 쓰레드를 생성하지만 2,3번 과정으로 남은 커넥션이 없어서 (나머지 쓰레드들은 커넥션이 부족해서 데드락) 반복해서 NIO 커넥터가 쓰레드를 생성하고 무한 반복이 되다가 총 쓰레드 량이 부족해지고 cpu를 과하게 쓰다가 99.9 까지 간 것이다.. 그래서
Thread starvation or clock leap detected Dead Lock, hikari 에러가 계속해서 생긴 것이고  EC2 서버는 상태검사를 통과하지 못 하고 죽은 것! 

이후 히카리풀의 설정을 바꾸었다.

pool size = Tn x (Cm - 1) + 1  -> 최적의 Maximum Pool Size 구하는 공식 이용

이후 추가적인 작업을 해준 뒤에는 Thread starvation or clock leap detected Dead Lock, hikari  

에러는 줄어들었고 cpu를 계속해서 점유하지 않았다.

      hikari:
        maximum-pool-size: 20
        #클라리언트가 커넥션을 기다리는 최대시간(ms)
        connection-timeout: 10000
        #커넥션이 유휴상태로 풀에 유지되는 최대시간(ms)
        idle-timeout: 10000
        #커넥션이 풀에 의해 폐기되기 전에 유휴상태로 풀에 유지되는 최소시간(ms)
        max-lifetime: 580000
        data-source-properties:
            #캐쉬 사용 여부
            cachePrepStmts: true
            #드라이버가 연결당 cache할 statement 수
            prepStmtCacheSize: 200
            #캐쉬할 SQL의 최대 길이
            prepStmtCacheSqlLimit: 2048
            #최신 버전 지원 받는 설정
            useServerPrepStmts: true

문제상황(3) 그러나 계속해서 다른 프로세서가 80% 가량 CPU를 머금고 있어서 확인을 시작하였다.

문제의 프로세스 2개       snapd & amazon-ssm-agen

snapd란?

linux Open Source 로 구성된 OS 이기 때문에 그 기반으로 확장되어 개발사에 따라 Ubuntu, Fedora, Debian, Cent 등 다양하게 파편화 되었다.

그 상황에서 패키지 관리 툴은 apt, yum 등으로 해당 OS에 맞는 버전의 패키지만 관리할 수 있도록 함께 파편화 되었다.

따라서 linux 관리자는 다양한 패키지 관리 툴을 익혀야 하는 불편한 상황이 연출되었다.

이에 따라 Ubuntu 에서는 일원화된 패키지 관리 툴을 발표하는데 그것이 Snapd 이다.

출처 : https://yhjin.tistory.com/49

- 난 snap 관련 명령어를 쓰지 않는다. 그래서 지우기로 마음 먹었다 또한 디렉터리를 보다 알게 된 것인데 amazon-ssm-agen는 Snap안에 있는 파일로 같이 날렸다.

 

아래 게시물을 보고 지울 수 있었다. 꼭 마지막 apt-mark hold snapd 명령어로 다시 설치되지 않게 방지하자!

sudo systemctl status snapd.service
sudo systemctl stop snapd.service
sudo systemctl disable snapd.servic
sudo apt-mark hold snapd -> 다시 설치되지 않게 방지

https://hoing.io/archives/8933

 

우분투 snapd.service CPU 과점 사례 - Usage High CPU of snapd.service

 

hoing.io

 

https://dragontory.tistory.com/445

 

 

이후

Thread starvation or clock leap detected Dead Lock, hikari 에러는 잘 보이지 않고 서버가 꺼지지도 않았다 ..흑 ㅠ.... 

 

 

 

'aws' 카테고리의 다른 글

[AWS] EC2  (0) 2023.09.15