오픈소스 APM 핀포인트 활용 사례 (우리생협 쇼핑몰)

1. 개요

본 문서는 우리생협 쇼핑몰에 오픈소스 APM 핀포인트를 도입하여 활용한 사례를 설명합니다.

APM(Application Performance Management)은 응용 소프트웨어의 성능과 서비스 이용성을 감시하고 관리하는 데 초점을 둔 시스템 관리 방법론을 의미합니다. 또한, 운영 중인 시스템의 성능을 모니터링하고 분석하여, 시스템의 가용성 및 안정적인 시스템 운영을 돕는 도구입니다.

기업 입장에서는 애플리케이션 개발부터, 테스트, 오픈, 운영, 안정화의 전 단계에 걸쳐 성능을 모니터링하고 분석할 수 있는 솔루션으로 활용할 수가 있습니다.

제니퍼(Jennifer)라는 강력하고 유명한 국내 솔루션이 있지만 구입비용을 고려하면 현실적인 장벽에 직면하기 때문에, 대안으로 OSS(Open Source Software) APM 중에 네이버가 개발하고 작년에 오픈소스화한 핀포인트를 먼저 선정하고 적용해 보았습니다.

1.1. 핀포인트를 먼저 선정한 이유

  • 애플리케이션 소스 수정없이 적용 가능
  • 트랜잭션 단위별로 소스 레벨까지 추적이 가능하여 문제를 빠르게 진단할 수 있을 것으로 보임
  • 응답속도나 에러에 대한 알람을 설정하여 이메일이나 SMS로 알림을 받을 수 있음
  • 오픈소스이지만 계속적인 릴리즈를 진행하고 있음

그렇다고 APM이 모든 애플리케이션을 지원하지는 않습니다. 제니퍼도 Java, .NET, PHP 기반의 애플리케이션 정도를 지원하고 있습니다. 핀포인트는 Java 기반의 애플리케이션을 지원하며 Tomcat(or Jetty)과 같은 JVM 기반의 WAS에 적용이 가능합니다. (자세한 지원사항은 Supported Modules 참고)

1.2. 적용 후 무엇이 가능해 졌나?

  • 과거에는 발견하지 못했던 문제를 발견
  • 문제를 쉽고 빠르게 해결하여 문제 진단과 수정시간이 대폭 단축
  • 모니터링 View와 알람을 통해 애플리케이션 상태를 실시간으로 감지

1.3. 어디에 활용하면 좋을까?

기업이 APM을 잘 활용하여 성공적인 프로젝트를 수행하는 것이 이 문서를 작성한 목적입니다. 경험적으로 몇가지 시나리오를 제시합니다.

개발 초기에 아키텍처를 검증

  • 방법
    • 개발 초기에 성능에 영향이 큰 모듈부터 개발하고 APM을 통해 성능을 분석하여 아키텍처에 대한 성능을 검증
  • 효과
    • 아키텍처를 사전에 검증하여 프로젝트 후반에 아키텍처를 변경하는 불상사가 발생하지 않도록 예방
    • 투입 인력 초과비용 발생과 납기일 미준수에 대한 리스크 감소

프로젝트 진행 시 지속적인 품질 관리

  • 방법
    • 프로젝트 개발 중에도 개발-빌드-배포-테스트 환경을 구축하고 주기적으로 APM을 통해 문제를 진단하고 수정
  • 효과
    • 개발자들에게 소스코드를 커밋하는 시점이 개발완료가 아니라 테스트가 통과 했을 때 개발이 완료된 것이라는 점을 주지
    • 프로젝트 후반에 애플리케이션에 문제가 많다는 것을 인식하여 인력을 초과 투입하고 일정이 지연되는 상황을 예방

서비스 운영 시 모니터링 용도

  • 방법
    • 운영 및 안정화 단계에 APM을 적용하여 문제점을 진단하고 수정
  • 효과
    • 모니터링과 알람을 위한 별도의 개발이 필요 없음(로그 생성, 수집, 분석, 시각화, 알람 등의 개발)
    • 쉽고 빠르게 서비스 안정화 진행

2. 우리생협 쇼핑몰에 핀포인트 적용

2.1. 우리생협 쇼핑몰 품질 개선 활동

필자는 병신년(丙申年) 새해에 우리생협 온라인사업 TF 팀에 투입되어 서버 안정화 및 개선, 추가기능 개발 등의 미션을 수행하였습니다. 서비스 안정화와 운영 효율화를 위해 시스템 구조를 개선하고 반복되는 작업에 대해서는 자동화를 지향하였습니다.

애플리케이션 시스템 구조 개선

우리생협 쇼핑몰 서버 시스템은 크게 Web Application Server(이하 WAS), DB서버, 검색서버로 구성되어 있고, WAS는 PC Web 요청에 대응하는 Shopping 서버와 Android와 iOS 앱에 대응하는 Gateway 서버, 상품과 주문을 관리하는 CMS 서버로 구성되어 있습니다. 문제는 Shopping, Gateway, CMS 서버가 하나의 Tomcat으로 구동되고 있어서 매우 불안정한 상태로 운영 중이었습니다. (다행히? 트래픽이 높지 않아 장애 상황이 표면화 되지는 않았음) 트래픽이 높지 않아 서버 증설은 하지 않고 서비스만 분리하는 작업을 진행하였습니다.

시스템 구조 개선

CI(Continuous Integration) 환경 구축

Continuous Integration(지속적인 통합)은 소프트웨어의 질적 향상과 소프트웨어를 배포하는데 걸리는 시간을 줄이는데 초점이 맞추어져 있는 프로세스 입니다. 사내 기반시스템인 GitLab을 이용하여 개발자가 소스를 git에 push하면 자동으로 빌드와 배포를 수행하도록 자동화 하였습니다. 이러한 자동화를 통해 빌드/배포에 대한 휴먼 에러를 없애고 배포하는게 걸리는 시간을 줄이면서 개발자가 개발에 좀 더 집중할 수 있는 환경을 조성하였습니다.

배포 전략

백업

쇼핑몰에서 상품과 주문, 결제 내역은 매우 중요한 데이터이기 때문에 백업은 필수입니다. DB와 검색서버에 저장되어 있는 데이터를 일일 백업하도록 적용하였습니다.

서비스 실시간 모니터링을 하려다가 핀포인트를 도입

실시간으로 응답코드나 응답시간을 체크하여 기준치를 벗어나면 담당자에게 이메일을 전송하고 애플리케이션의 전반적인 상황을 모니터링 하고 싶었습니다. 이러한 환경을 구축하기 위해서는 기본적으로 로그 생성, 수집, 분석, 시각화, 알람 등의 개발이 필요하였고 이런 것들을 개발하기 위해 회사를 설득할 자신은 없어서 서버 리소스(CPU, 메모리, 디스크 사용량) 모니터링 정도만 자동화 하였습니다. 그러던 중에 공공사업본부에서 산업부 Trouble Shooting 사례 세미나를 진행하였고, 문제에 대한 원인 분석 과정에서 APM 활용에 대한 아쉬움이 남아 리서칭하던 중에 핀포인트를 발견하였습니다. 우리생협 쇼핑몰이 앞에서 언급한 핀포인트를 먼저 선정한 이유에 적합하기도 하고 사내에 APM 도입 검토를 위해 재빠르게 우리생협에 적용을 시작합니다.

2.2. 핀포인트 설치 및 적용

핀포인트 구성

핀포인트는 애플리케이션의 프로파일링 정보를 추출하는 Agent와 데이터를 수집하는 Collector, 수집된 데이터를 시각화하는 Web UI, 데이터를 저장하는 HBase로 구성되어 있습니다.

핀포인트 구성

컴포넌트 설명
Agent 프로파일링이 필요한 애플리케이션 JVM(such as tomcat)에 java agent 형태로 추가되어 Collector에 프로파일링 정보를 전송
Collector Agent가 보낸 프로파일링 정보를 수집하고 HBase에 저장
Web UI 수집된 데이터를 다양한 형태의 정보로 사용자에게 Web을 통해 제공
HBase 수집된 데이터를 저장하고 조회하는 빅데이터용 데이터베이스

핀포인트 설치 및 적용

Agent는 프로파일링 하고자 하는 애플리케이션에 설치하고(애플리케이션을 구성하는 인스턴스가 N개라면 Agent도 N개를 설치) 나머지 Collector, Web UI, HBase는 별도의 서버(유휴서버나 개발서버)에 설치합니다. 자세한 설치 방법에 대해서는 별도로 설명하고 지금은 개념만 이해하면 되겠습니다.

핀포인트 설치 및 적용

Agent에 대한 JVM 옵션에 보면 pinpoint.agentId와 pinpoint.applicationName이 있습니다. pinpoint.applicationName는 애플리케이션이나 서비스 이름이고 pinpoint.agentId는 agent가 구동중인 인스턴스의 유니크한 식별자입니다. 예를 들면, 우리생협의 Shopping 서버는 2개의 Tomcat 인스턴스로 구동되어 이중화 되어 있습니다. 따라서 인스턴스별로 agentId와 applicationName은 다음과 같이 설정하면 됩니다.

인스턴스 applicationName agentId
tomcat 1번 -Dpinpoint.applicationName=shopSvr.real -Dpinpoint.agentId=shopSvr1
tomcat 2번 -Dpinpoint.applicationName=shopSvr.real -Dpinpoint.agentId=shopSvr2

핀포인트 적용 전 우리생협 구성도

우리생협에 프로파일링 대상은 고객이 접속하는 Shopping 서버와 Gateway 서버로 하고 핀포인트를 적용하였습니다.

핀포인트 적용 전

핀포인트 적용 후 우리생협 구성도

Shopping 서버와 Gateway 서버에 Agent를 설치하고 별도의 서버에 Collector, Web UI, HBase를 설치하였습니다. 이제 관리자는 웹브라우저로 Web UI에 접속하여 애플리케이션을 모니터링할 수 있습니다.

핀포인트 적용 후

3. 핀포인트 Web UI 둘러보기

핀포인트 Web UI는 애플리케이션 프로파일링 정보를 시각화하고 이메일이나 SMS로 알림을 하는 기능을 합니다. 주요 기능만 빠르게 살펴보겠습니다.

3.1. 대시보드

Web UI에서 보여주는 메인 화면입니다. 상단의 드롭메뉴에서 모니터링 하고자 하는 애플리케이션(applicationName)을 선택하면 다음과 같은 화면이 나타납니다.

대시보드

서버 맵

애플리케이션과 연동하는 노드와 링크를 자동으로 발견해 주고 이를 토폴로지 형태로 시각화 합니다. 애플리케이션 구성을 한 눈에 파악할 수 있고 노드 간에 호출된 건수를 파악할 수 있습니다. 필터를 통해서 특정 요청에 대해서 조회가 가능합니다.

서버 맵

성능 차트

사용자를 통해 들어온 콜에 대한 성공/실패수, 응답시간 등의 성능 지표를 시각화 합니다. 또한 특정 콜에 대해서 마우스로 드래그하여 Callstack Trace(소스레벨 추적)가 가능합니다.

성능 차트

3.2. Callstack Trace

모든 콜에 대한 소스레벨의 Trace View를 제공하여 오류나 병목이 발생한 지점을 바로 발견할 수 있습니다.

Callstack Trace

3.3. 애플리케이션 리소스 보드

애플리케이션 인스턴스 별로 CPU usage, Memory/Garbage Collection, TPS, JVM arguments 등의 리소스 정보를 제공합니다. Full GC가 너무 자주 발생하거나 실행시간(Stop-The-World)이 긴 경우는 튜닝이 필요하다는 것을 판단할 수 있습니다.

애플리케이션 리소스 보드

3.4. 알람

애플리케이션의 응답시간 지연시간 및 지연율, 응답 에러수 및 에러율, 힙메모리 사용율, CPU 사용량 등에 대한 임계치를 설정하면 이메일이나 SMS를 통해 실시간으로 Notification을 받을 수 있습니다. 단, 이메일이나 SMS 전송에 대한 interface만 제공하기 때문에 전송하는 코드는 직접 구현(implementation)해야 합니다. 필자는 이메일과 Slack 채널로 전송하는 코드를 구현하였습니다. SMS는 유료서비스에 가입해야하기 때문에 Slack 채널로 대체하였지만 Slack은 휴대폰번호 베이스가 아니기에 개개인에게 발송되지는 않고 특정 Slack 채널로 전송이 되는 문제가 있습니다. 일단 빠르게 적용해 보는 것이니 SMS는 나중에 구현하고 휴대폰번호 베이스인 카톡이나 텔레그램 연동을 고려해봐야겠습니다.

알람 설정

알람은 먼저 그룹과 멤버를 생성하고 해당 그룹에 알람 Rule을 설정하면 됩니다. 그림은 Shopping 서버와 Gateway 서버에 대해 에러수, 응답지연율, 힙메모리 사용율, CPU 사용량에 대한 임계치를 적용하여 알람을 설정한 내용입니다.

알람 설정

이메일 전송

이메일 전송

Slack 채널 전송

Slack 채널 전송

4. 핀포인트를 활용한 애플리케이션 문제 진단

핀포인트를 적용했으니 우리생협 애플리케이션에 대해서 문제를 진단해 보겠습니다. 절차는 다음과 같습니다.

  1. Slack 채널을 통해 알람 확인
  2. 핀포인트 Web UI에 접속해서 알람이 발생한 시간대의 성능 지표와 Callstack Trace 확인
  3. 문제를 진단하고 후속 조치(수정이 필요한 경우는 GitLab에 이슈로 등록)

4.1. Slack 채널을 통해 알람 확인

Slack 채널 알람 발생

4.2. 핀포인트 Web UI를 통해 문제를 진단

대시보드에서 알람이 발생한 콜을 검색

에러 발생콜 검색

Callstack Trace로 문제 진단

해당 콜은 searchCategory 메소드에서 파라미터가 Null이라서 Exception이 발생하였습니다.

에러 발생콜 Callstack Trace

정상적인 콜과 비교

대시보드에서 /product/list 라는 URL을 필터링하여 정상적인 콜과 에러 콜을 비교해 보면 정상적인 콜은 http.param 파라미터가 넘어오고 에러 발생콜은 파라미터가 비어 있습니다.

특정 URL 패턴으로 필터 적용

정상적인 콜 Callstack Trace

4.3. 진단 결과

소스를 확인해 보니 categoryId 파라미터에 대한 필수값 체크를 하지 않아서 발생한 에러로 후속 처리를 위해 우선 GitLab에 이슈로 등록하고 프로세스에 따라 후속 처리를 진행할 예정입니다.

5. 맺음말

지금까지 오픈소스 APM 도구인 핀포인트를 설치하고 애플리케이션에 적용하고 활용하는 방법에 대해서 설명하였습니다. 막상 문서로 작성하고 보니 설명이나 문제를 진단하는 예제가 아쉬운 부분이 남아 있지만 도입한지 1주일 밖에 되지 않았기 때문에 지속적으로 활용하면서 Good Practice를 공유하도록 하겠습니다.

관련 문의는 시스템사업팀 서영준 부장에게 메일이나 구두로 해주시고, 도입 검토가 필요한 부서가 있으면 핀포인트 서버를 공유해 드릴 수 있으니, agent만 적용하면 APM이 가능하도록 지원해 드리겠습니다.

6. 참고자료