ep 13. 주니어 개발자의 90일 성장기: 불안정에서 안정으로

이동엽·2025년 1월 20일
0
post-thumbnail

서론

지난 회고록을 작성하고 정확히 이틀 뒤, 입사를 하고나서 그동안의 자잘한 이슈들을 모두 잊게 만드는 대형 장애가 발생했다.

덕분에(?) 그동안 간과하고 있었던 모니터링부터 백업 자동화 및 롤백 프로세스를 구축하는 데에 많은 시간을 쏟았던 3개월이다.

서비스가 안정적이여야 여유가 생기고, 올바른 판단을 할 수 있음을 깨닫게 되었고
장애가 발생했을 때에는 당황하기 마련이니, 평소에 메뉴얼을 잘 작성하는 데에 중요성을 깨닫은 겨울이다.

2024년은 바쁘게 지나갔으니, 부디 2025년은 무탈하기를 응원하며.


AWS CLI를 이용한 EC2(AMI, EBS Snapshot) 시작템플릿 갱신 자동화

개요

지난 2024년 9월 24일, 사용하지 않지만 만들어놓은 탓에 요금이 청구되는 AWS 리소스들이 많았다.
요금을 줄여보고자 필요하지 않은 리소스들을 제거하기 시작했고, EC2 오토스케일링 그룹을 삭제한 것이 문제의 시초가 되었다.

당시 슬랙으로 EC2 헬스체크에 대한 결과를 전달받고 있었는데, 상용 서비스 중인 EC2 인스턴스가 종료되고 있다는 알림이 수차례 쏟아졌다.

원인은 오토스케일링 그룹을 삭제할 경우 연결된 인스턴스도 삭제되는데, 이를 확인하지 못했던 것이다.
이로 인해 EC2 인스턴스를 생성하고 초기 세팅하는 과정부터, 서비스를 재기동하기까지 약 3시간이 소요되었다.


쉽게 말해, 당시 회사 홈페이지부터 약 4개의 앱이 서비스가 중단되었다는 것이다.
장애가 발생했을 때, 백업/롤백에 대한 프로세스가 전혀 구축되어있지 않아 오랜 시간이 소요되었다.

이후에는 진행 중이던 작업들을 모두 중단하고, 기술이사님과 백업/롤백 프로세스를 구축하는 데에 참 많은 시간을 쏟았다.


작업 내용

처음에는 AWS Console의 수명 주기 관리자를 이용해 주기적으로 백업하려 했지만,
이 방식은 단순 EBS만 백업할 뿐이며 태그나 이름 등을 원하는대로 지정할 수 없어서 반려했다.


나는 당장의 EC2 인스턴스에 문제가 생겼을 경우, 기존과 완전히 동일한 스펙의 새로운 인스턴스를 바로 실행할 수 있기를 원했다. 여기서 말하는 "완전히 동일한 스펙"은 인스턴스 타입부터, 네트워크 설정, EBS 사양, 태그 및 보안그룹 등의 모든 설정을 의미한다.

결국 AWS CLI를 이용해 쉘 스크립트를 작성하고, 이를 Linux crontab에 등록하여 주기적으로 백업하도록 동작했다.


자세한 쉘 스크립트 원본을 첨부할 수는 없지만, 큰 동작 흐름은 아래와 같다.

  1. 기존 인스턴스 사양 조회
  2. 기존 인스턴스와 연결된 EBS 사양 조회
  3. AMI 백업 (내부적으로 EBS 스냅샷이 동시에 생성)
  4. 3번에서 생성된 EBS 조회
  5. 시작템플릿 생성 및 버저닝
  6. 오래된 시작템플릿 버전 제거

느낀 점

  • 평소 백업에 대한 생각을 하지 못하고, 신규 기능을 개발하기에 바빴던 시기였음을 반성하게 되었다.
  • 동시에 장애를 해결한 후, 어떤 형식으로 보고를 해야 하는지를 기술이사님께 많이 배웠다.
  • 백업이 생명이다. 긴급 상황에는 당황하기 쉬우니 메뉴얼을 잘 만들어놓자.

문자 전송 서비스 변경

개요

위에서 상용 서비스 중인 EC2가 삭제되었을 때, 해당되는 항목 중에는 레거시 인증 API 서버도 포함되어 있었다.
당시 문자 전송 기능은 EC2에서 Client JAR 파일을 실행시켜, Client가 DB에 직접 접근하여 값을 확인하고 문자를 보내는 방식이였다.

다만, 가장 큰 문제점은 해당 클라이언트를 실행시킬 IP 대역을 직접 제한할 수 있는게 아니라, 고객센터에 문의하여 제한할 IP 대역을 요청해야 한다는 점이였다.

실제로 급한 상황에서 고객센터 전화번호를 찾고, 필요한 서류(재직증명서, 기타 서류)를 모두 보내고 기다리는 건 말도 안되는 상황이라고 생각한다. 따라서 서비스가 안정화되고, 문자 전송 서비스를 변경하는 작업을 진행했다.


작업 내용

  1. 문자 전송 업체 선정(비용, 카톡 전송 기능 여부, 해외 문자 전송 가능 여부 등)
  2. 문자 전송 과정에서 외부 API 호출 실패시 Retry 정책 수립
  3. Retry 과정에서 서버 재기동 시, 최종 완료되지 않은 작업에 대한 Batch 처리 구현
  4. 레거시/고도화 인증 API 서버에서 문자 전송 작업을 단일 포인트로 관리하기 위한 로직 처리
  5. 문자 전송 API 호출 시, 비동기로 처리하되 OpenFeign 기반으로 동작하기 위해 Reactive Feign 도입

느낀 점

  • Reactive Feign을 도입하며, 비동기 처리에 대한 성공/실패 작업 후처리에 많은 고민을 할 수 있었던 시간이다.
  • Retry 과정에서 서버가 재기동될 경우, 손실되는 메시지에 대한 처리를 고려하지 못했다. 😂

n8n 헬스체커 및 Nginx 모니터링 구축

개요

기존에는 Grafana & Prometheus 기반으로 고도화 API 서버 및 RDS만 모니터링이 구축되어 있었다.
따라서, 웹 서버와 레거시 API 서버들은 모니터링이 구축되어 있지 않은 상태였다.

앞서 말했던 장애를 겪고난 뒤, 평소에도 힙 메모리와 스레드 사용량을 확인해야 할 필요성을 느꼈다.


작업 내용

  1. Nginx Exporter를 이용한 Grafana & Prometheus 모니터링 구축 및 알람 설정
  2. n8n을 이용한 헬스체크 구축 (구글 스프레드시트 읽기, 헬스체크 조건 검증, 슬랙 알림 전송)

느낀 점

  • 웹 서버의 경우, 하나의 EC2 인스턴스에서 Nginx를 사이트별로 나누어 운영하고 있다. 이 경우, 각각의 사이트별로 스레드 사용량을 통계내지 못했다. 다만, Nginx Plus를 사용할 필요성을 아직까지는 느끼지 못하여 이대로 유지하기로 했다.
  • n8n이라는 노코드 툴을 이용해, 헬스 체크 자동화를 구축했다. 새로운 기술을 볼 때면 아직까지 신나는 걸 보니, 여전히 개발이 재밌다고 할 수 있을 것 같다.

송아리에어 서브사용자 모니터링 기능 개발

개요

  • 이번 신기능은 A 사용자가 IoT를 이용해 산소포화도를 측정할 때, B 사용자가 실시간으로 모니터링이 가능해야 했다. 이때, 측정 값에 따라 위험/주의 알람이 A, B 사용자 모두에게 알람이 울려야 한다.

고민 내용

  • 실시간 이라는 특성으로 인해 SSE/WebSocket/MQTT 중 고민을 하였고, 서버에서 클라이언트로 일방적인 알림 전송이 목적이기에 SSE를 택했다.
  • 단, SSE를 이용할 경우, OSIV(Open Session In View) 속성을 반드시 Off로 설정해야 한다.
    • 이 옵션이 켜져있을 경우, 클라이언트에게 응답이 갈 때까지 DB 커넥션을 계속 유지한다.
    • 이로 인해 사용자가 많아질 경우, 유지되는 커넥션도 많아지므로 DB 커넥션이 고갈되기 쉬웠다.
    • 또한, OSIV 속성을 Off로 바꿈으로 인해서 기존 서비스가 받는 영향도를 모두 조사하기에는 무리가 있다고 판단했다.
  • 따라서, 약간의 시간 차가 발생하더라도, REST 방식으로 DB에 저장하고 조회하여 알람을 울리는 방식으로 결정했다.

느낀 점

  • 서비스의 안정성을 위해서, "실시간"이라는 기획이 구현이 힘들다고 표현하는 방법을 배웠다.
  • Client 간의 실시간 통신을 위한 WebRTC라는 기술을 최근에 알았다. 미리 알았더라면 이 방식도 고려해보았을 텐데, 아쉽다. 이후 2025년 상반기에 프론트엔드 팀원들과 WebRTC나 gRPC를 공부해보고 싶다.

온프레미스 서버 이관

개요

현재 사내 개발 서버는 총 2대의 온프레미스로 구성되어 있다.

  • 구 서버 : 기존 레거시 서비스들의 개발 환경
  • 신 서버 : 고도화 서비스들의 개발/스테이지 환경

서비스들 별로 고도화 유무에 따라 서버가 분리되어 있으며, CI/CD 환경 또한 달라 매번 주의가 필요했다.
시간이 지나고 구 서버의 사양이 좋지않아 메모리가 가득 차기 시작했고, 결국 신 서버로 이관을 진행하기로 했다.


작업 내용

  • 정전 상황이 끝나고, 전원이 공급되었을 때 각 API/Web 서버 및 DB Reboot/복구 프로세스 설계
  • 레거시에서 사용하던 Gitlab CI/CD를 고도화 서비스와 동일하게 Jenkins로 통합
  • 레거시 API 서버 이관 : 고도화 API 서버와 JDK 버전이 달라 Docker 환경 구축
  • 레거시 Web 서버 이관 : Nginx 설정 및 Access/Error 로그 관리 프로세스 구축
  • ssh 접속 시, 패스워드 입력 방식에서 pem 키를 이용한 접속 방식으로 변경하여 보안 강화

느낀 점

  • Nginx 설정을 초기부터 진행할 수 있었고, 압축 방식(gzip, brotli)도 적용해볼 수 있었다.
  • 서비스들을 이관하며 CI/CD를 비롯한 관리 포인트를 단일화하니 훨씬 편해진 것을 몸소 느끼고 있다.

Spring Cloud MSA

인프런에서 수강 중이던 강의를 마무리했다.
Spring Cloud와 MSA에 대한 개념이 처음인 사람들에게 추천하는 강의다.

해당 강의를 수강한 내용에 대해서는 README에 자세히 작성해놓았다.


JDK 21, Spring Boot 3.4, Spring Cloud 2024.0.0 버전업 가이드

2025년 상반기에는 JDK 17, Spring Boot 3.0.13, Spring Cloud 2022.0.4로 구성된 고도화 프로젝트들을 버전업할 계획이다.

버전업을 진행하기 전, 최신 버전에서 변경된 주요 사항들에 대해 정리했다.
해당 내용에 대해서는 별도의 포스팅을 작성했다.


동시성 이슈 해결방법(Synchronize, DB Lock, Redis Distributed Lock)

인프런에서 동시성 이슈 해결 방법에 관련된 강의를 수강했다.
해당 내용에 대해서는 README에 자세히 작성했다.


마무리

나름의 백업/복구 프로세스를 구축하고, 여러 모니터링을 구축했다곤 해도
수많은 메트릭 중에서 알람을 설정할 메트릭과 기준을 선별하고,
쌓여가는 로그들 사이에서 진짜 에러 로그들을 판별하는 데에 아직 바쁜 것 같다.

시간이 지나면서, 점차 기준이 명확해지는 내가 기대된다.


다사다난했던 2024년 연말을 마치고 2025년이 되자, 놀랍게도 평온해져 당황스러운 요즘이다.
1월이 된 지도 어느새 20일이 지났다. 매년 연말연초에 세웠던 신년계획도 아직 세우지 못했다.
지금이라도 늦지 않았으니, 남은 1월 내에만 세워보기로 마음을 먹는다.

올해도 지치는 순간이 언젠가는 올테지만, 금방 회복하고 앞으로 나아가는 내가 되었으면 한다.
2025년 파이팅!

profile
백엔드 개발자로 등 따숩고 배 부르게 되는 그 날까지

0개의 댓글

관련 채용 정보