코딩을 잘하고 싶은 코린이 동토니

스마트 스토어 프로그램 health Check 본문

기술낙서장

스마트 스토어 프로그램 health Check

dongtony 2024. 9. 2. 17:22

이전에 작성한 스마트 스토어의 경우 인스턴스가 AWS-EC2에 생성되어있다.

해당 프로그램은 종종 알 수 없는 이유로 갑자기 CPU메모리가 확 튀게 되면서 순간적으로 죽어버리는 현상이 발생했었다.

여기서 더 큰 문제는 정작 AWS콘솔을 확인해봤을 때 아무런 이상점이 없다는 것이 가장 큰 문제였다.

 

업무시간중 이러한 문제가 발생되면 그나마 슬랙채널을 통해 CX팀에서 문의가 들어오지만, 가장 큰 문제는 주말이나 휴일에 해당 프로그램이 메모리 과부화로 죽어버리게 된다면 직접 눈으로 확인하기 전까지는 이를 알 방법이 없었다.

이러한 문제를 해결하기 위해서 여러가지 방식을 생각해봤었다.

생각 했던 해결법들은 다음과 같다.

1. 스마트 스토어 인스턴스 내부에서 서버를 구축하고 외부 서버에 요청을 지속적으로 한다.

이 방법의 경우 해결 방법 자체는 나쁘지 않았지만 외부 서버에서 내부서버를 위한 요청을 계속 잡고있어야 된다는 점과, 과연 이 해결을 위해 ec2 인스턴스 내부에까지 서버를 구축해야하는가?가 문제였다.

서버를 구축하는 시간 자체는 많이 들지 않겠지만, 단순한 Health Check 하나만을 위해서 서버를 띄어둔다는게 굉장히 비효율적으로 보였다.

2. 외부에서 내부서버로 요청을 지속적으로 보낸다.

해당 방법의 경우도 위의 경우와 비슷했다. 결국 인스턴스 내부에서 서버를 구축해야하고, 외부 서버에서 내부서버의 요청을 지속적으로 잡고있어야 했다.

다른 방법이 없을까 하면서 고민하고 있던 찰나, 업무시간중 마침 인스턴스가 메모리 과부화로 죽어버리는 현상이 발생되었다. 이때를 놓치지 않고 혹시나 하는 마음에 콘솔로 ping을 쏴보았다.

 

ping이란?

확인을 해보니 로컬 터미널에서 스마트 스토어 인스턴스의 public IP로 ping을 쐈을 때 패킷 손실 100%에 돌아오는 응답이 하나도 없다는 것을 확인 할 수 있었다. 또한 AWS콘솔을 확인 했을 시 역시나 인스턴스 동작자체에는 아무런 문제가 없다는 것을 확인했다. 이 말이 의미하는 바는 다음과 같았다.

  • 인스턴스는 정상이지만 메모리 과부화로 일시적으로 멈추게 되었다.
  • AWS 콘솔상 인스턴스 정보는 1분 주기로 읽기 때문에 순간적인 문제가 생기더라도 콘솔로는 확인 할 가능성이 매우 희박하다.
  • 결국 메모리 과부화로 내부 프로세스만 죽어있는 상태고 인스턴스는 정상적으로 살아있다.
  • ping을 쏘게 되면 내부 프로세스들은 전부 죽어있는 상태이기에 돌아오는 응답은 없다.(근데 생각해보면 인스턴스가 죽어야지 응답이 안오는게 맞지않나라는 생각이 들기도 한다. 이부분은 좀 더 공부해봐야 알 수 있을것같다.)

그럼 Ping을 통해 인스턴스의 프로세스 동작 여부를 확인 할 수 있으니 단순히 ping을 쏴보고 응답이 없으면 슬랙채널에 알림이 오도록 연결만 해주면 끝나게 된다.

// check-health.ts

const instanceName = 'some instance'

    const ec2 = new AWS.EC2({
      region: 'ap-northeast-2',
    })

    const data = await ec2
      .describeInstances({
        Filters: [
          {
            Name: 'tag:Name',
            Values: [instanceName],
          },
          {
            Name: 'instance-state-name',
            Values: ['running'],
          },
        ],
      })
      .promise()

    for (const reservation of data.Reservations) {
      for (const instance of reservation.Instances) {
        if (instance.PublicIpAddress) {
          const res = await ping.promise.probe(instance.PublicIpAddress)

          console.log(res, '<<< ping result')

          if (!res.alive) {
            console.log('인스턴스 죽음')

            await postToSlack('인스턴스 확인 필요!!!!')
          } else {
            console.log('인스턴스 정상')
            return
          }
        }
      }
    }

AWS에서 제공하는 aws-sdk 패키지를 이용하여 해당 인스턴스의 정보를 받아오고, 받아온 정보중 public IP만을 뽑아내서 ping을 쏘면 해당 문제가 해결된다.

근데 여기서 하나 더 문제가 발생되었다.

로컬에서 해당 프로그램을 동작시켰을 땐 정상 동작을 했지만, 막상 k8s에 올리고 나니 ping이 계속 응답이 없는것이였다.

해당 문제를 해결하기 위해서 AWS 공식문서와 GPT에게 도움을 많이 구했는데 결론은 내부 batch 프로젝트가 돌고있는 인스턴스와 스마트 스토어 프로그램 인스턴스의 보안그룹이 서로 다르기 때문에 원활하게 통신이 되지 않는 문제였다.

내부 batch 프로그램이 돌고있는 보안그룹에 스마트스토어 프로그램 관련 IP들을 전부 추가해주고 다시 내부 batch 프로젝트를 릴리즈 시켜주고 나니 정상적으로 동작하는 것을 확인 할 수 있었다.

그럼 여기서 끝?

이렇게 스마트 스토어 프로그램이 비정상적으로 죽게되는것을 확인 할 수 있게되고나니 이런 생각이 문득 들었다.

  • 이제 얘가 죽는 시점을 알 수 있게됬는데 인스턴스 재시작을 해줄 방법은 없을까?
  • AWS-SDK에 인스턴스 재시작 관련 코드는 존재하는데 재시작하고나서 다시 VNC server를 키고 내부 프로그램들을 완전 자동으로 재실행 시킬 수 없을까?

위 문제들만 해결이 되면 스마트스토어 프로그램 작업자체는 완전 자동화로 돌아가기 때문에 어쩔수 없이 수동으로 해결해야되는 문제를 제외하곤, 비정상적인 종료에 대해서는 따로 신경을 쓰지 않아도 되는 큰 장점이 있었다.

위 방법을 찾아보던 중 우연히 AWS-SSM이라는 방법을 찾게되었다.

AWS-SSM을 사용하게 되면 해당 인스턴스에 직접적으로 command를 입력할 수 있다.

즉 내가 VNC 서버를 키는 command부터 프로그램 동작을 위한 yarn serve까지 command로 쏠 수 있다는 말이다.

아직 이부분까지는 구현을 하지 않았는데, 이 부분에 대해서는 직접적으로 command를 쏴서 해결을 하기 보다는, docker에 스마트 스토어 자동화 프로그램 이미지를 빌드시켜놓고 내부 프로세스가 죽었을 때 해당 이미지만 다시 실행시키면  자동으로 실행 될 수 있게 할 수 있을거 같아서이다.

 

해당 부분에 대해서 완전 자동화가 이루어진다면 다른 포스트로 글을 적게 될 거 같다.