현재 운영 중인 서비스에서 특정 이벤트로 인하여 약 2000명 정도의 사용자가 동시에 특정 기능을 사용할 예정이었다.
아직 사용자가 많지 않아 APM 은 따로 이용하지 않았고 AWS cloud watch 로 버그로그만 슬랙에 쏘도록 해놓은 상태였다. 그러나 사용자가 특정 시간에 몰릴 것이며 추후에도 계속 사용자가 서비스를 이용할 것이기에 현재 애플리케이션 서버의 성능과 실시간 트랜잭션 모니터링, 분석을 할 수 있도록 APM 을 달기로 결정하였다.
APM 은 여러 서비스들이 있는데 그 중 비용, 제공 기능 등을 조사하여 현재 우리 팀에 맞는 서비스를 선정하였다. 어떤 APM 을 사용하게 되었는지는 따로 작성하지 않겠다.
우선 현재 AWS Elastic Beanstalk(EB) 을 이용하여 서비스를 운영하고 있으며, 비용적인 측면으로 인해 N대의 서버 중 1대에만 APM 달기로 하였다.
관련 EB 문서는 여기 에서 확인하면 된다.
문서를 보면 아래와 같이 leader_only 라는 옵션이 존재한다. 해당 옵션을 통해서 나는 N대의 ec2 서버 중 한 대에서만 특정스크립트를 실행하게 하여 APM 달았다.
참고할 점은 container_commands 를 이용할 때 지정한 명령은 루트 사용자로 실행되며, 지정한 각 명령어들은 이름의 영문자 순서대로 처리된다는 것이다.
스크립트 짜기
.ebextensions 에 대한 소개는 따로 이번 글에서 소개 하지는 않겠다. .ebextensions 폴더를 프로젝트 경로에 생성하여 해당 폴더 내에 스크립트를 넣고 EB 로 배포 시 단순 jar 만 배포하는 것이 아닌 .ebextensions 폴더와 함께 zip 파일로 압축을 하여 배포를 하면 된다.
1. 우선 APM 과 관련된 설정 파일, jar 를 폴더에 넣어두고 압축파일로 만들어서 s3 에 업로드 해둔다.
2. sources 를 이용하여 해당 s3 url 에 접근해 자동으로 다운로드, 압축이 풀어지도록 한다.
3. 우선 여기까지는 N대의 서버에서 모두 압축을 해제한 상태일 것이다. container_commands 에 대한 키가 아니라 leader_only 를 사용하지 못하기 때문이다. 만약 이게 불편하다면 직접 스크립트를 짜면되긴 한다.
4. 이제 압축해제 한 폴더명이 ../apm/ 이라면
나는 leader_only 명령어를 통하여 N대중 1대에서만 ../apm-target/ 으로 변경하도록 스크립트를 짰다 (이유는 5번에서 설명한다).
이 때 중요한 것은 실제 jar 를 실행하는 사용자는 root 사용자가 아니기 때문에 다른 사용자가 접근할 수 있도록 권한 설정을 해줘야 한다는 것이다.
5. 그리고 직접 쉘스크립트를 작성하여 ../apm-target/ 이 존재하면 apm jar 와 함께 배포하려는 프로젝트의 jar 가 실행되도록 스크립트를 짜고, 해당 폴더가 존재하지 않는다면 그냥 jar 만 실행되도록 쉘스크립트를 짠다.
6. Procfile 에서 해당 쉘스크립트를 실행하도록 한다.
이렇게 해서 나는 EB 에서 APM 을 1대에만 달 수 있었다. 물론, 1~6번까지를 보면 알 수 있듯이 꼼수를 부려 해결한 것이다. IDC 센터를 이용해서 서버 관리할 때는 못 느꼈는데 이렇게 자동화된 툴을 이용하니 불편한 점이 있는 듯하다. 우아한형제들에서 2017년 즈음에 관련 글이 있는데 그곳에서도 커스텀하는게 쉽지 않아 단점으로 얘기하니 참고하면 될 듯 하다.