이전까지 과정을 통해 prometheus, grafana 설정을 마무리 했다.
이 글에서는 spring actuator, scouter 를 통한 스프링 애플리케이션 데이터 수집과 nGrinder, k6를 사용한 테스트방법에 대해 다룬다.
jvm을 모니터링 하기 위해선 다양한 방법이 존재한다.
1. JMX API를 사용한 모니터링
2. APM 툴을 사용한 모니터링
3. actuator 를 사용한 모니터링
나는 요청 처리 시간, 에러, cpu, memory, io, gc, heap의 정보가 필요했다.
각 모니터링 툴들의 특징 및 장단점에 대해 알아보자.
jmx는 자바 애플리케이션에서 MBean을 통해 자바 객체를 관리하고 모니터링할 수 있는 API다.
jmx 포트를 노출시키고 VisualVM등의 툴을 사용해 JMX MBean에 접근해 모니터링을 할 수 있다.
JMX의 경우 이를 모니터링 하기 위해선 모니터링 툴이 필요로 하게 된다. 또한 웹 기반의 UI 가 없기 때문에 grafana와 통합하기 힘들다는 문제도 있다.
APM 툴은 BCI기술을 통해 바이트코드를 조작하여 모니터링 하는 방법이다.
다른 모니터링 방법들에 비해 상세한 애플리케이션 상태를 모니터링 할 수 있다는 큰 장점이 있다.
하지만 설정이 다소 복잡하고, 비용이 많이 들어간다는 단점이 있다.
나는 LG CNS의 오픈소스인 Scouter 를 사용해 모니터링을 수행해봤다.
이 글에서는 Scouter
의 설치 및 설정방법에 대해선 다루지 않는다.
Scouter 는 LG CNS에서 개발한 오픈소스 APM 툴로써 비교적 간단한 사용방법을 가진다.
Scouter는 데이터를 수집하는 Collector
와 자바 애플리케이션, 호스트를 모니터링하며 Collector
로 데이터를 보내는 Agent
, 그리고 수집된 데이터를 시각화하는 Client(Viewer)
로 구성된다.
scouter 역시 viewer 로 collector 에 직접 연결해야 한다는 특징있고, 이로인해 grafana와 통합이 힘들다는 단점이 있다.
하지만 scouter의 데이터를 influxdb
로 수집하고 influxdb
를 grafana
와 통합할 수 있기 때문에 불가능한건 아니다.
하지만 최근에는 scouter
의 influxdb
지원이 이루어지지 않는것 같고 레퍼런스들이 대부분 influxdb1
버전을 대상으로 설명하고 있다.
그리고 scouter를 사용하기 위해선 Collector
, Agent
가 항상 필요하기 때문에 비교적 복잡하고 비용이 많이 들어간다.
하지만 요청 하나하나를 상세하게 분석할 수 있다는 APM툴의 특징도 있다.
spring 은 Acuator 를 통해 JVM 상태 및 톰캣의 상태를 메트릭 형태로 노출시킬 수 있다. 그리고 이 메트릭은 prometheus 를 통해 주기적으로 수집할 수 있다.
앞에서 prometheus
설정을 보면 docker sd 기능을 사용해서 spring 애플리케이션의 엔드포인트를 추상화해 수집하는것을 확인할 수 있다.
Actuator 의 장점은 설정이 간단하고, 아키텍쳐가 간단하다는 장점이 있다. 하지만 APM툴에 비하면 비교적 러프하게 데이터를 수집한다는 단점또한 있다.
하지만 prometheus를 통해 수집한 데이터를 grafana를 통해 자유롭게 시각화하고 분석할 수 있다는 큰 장점또한 가지고 있다.
게다가 나에게 필요한 정보인 요청 처리 시간, 에러, cpu, memory, io, gc, heap 를 모두 제공해주었기 때문에 Acuator를 자바 애플리케이션 기본 모니터링 툴로 결정했다.
성능 테스트를 위한 툴로는 jmeter
, k6
, nGrinder
등이 있었다.
각 툴들의 특징 및 장단점들에 대해 알아보자.
jmeter는 자바 성능 및 부하를 측정할 수 있는 아파치 오픈소스 프로젝트이며, 역사가 깊은 테스트 툴이다.
오래된 역사로 환경이 탄탄하다는 특징이 있지만, xml을 사용해서 테스트를 정의해야 한다는 큰 단점이 있다.
다른 툴들은 스크립트 언어를 통해 편하게 테스트를 설정할 수 있지만 jmeter 는 xml로만 테스트를 정의해야 하기 때문에 이점은 나에게 큰 단점으로 작용헀다.
k6는 그라파나랩스에서 개발한 오픈소스로, javascript 를 사용해 테스트를 정의할 수 있고 그라파나와 연동이 쉽다는 장점을 가지고 있다. (사실 써보면 아니다.)
그리고 단일 에이전트로 테스트를 진행할 수 있기 때문에 비교적 간단하게 사용할 수 있다는 장점도 있다.
이점때문에 초반에는 k6로 꽤 기울었고 직접 세팅해 사용해봤다.
k6는 설치와 사용법이 아주 간단하다는 장점이 있었지만 큰 단점또한 있었다.
k6는 기본적으로 GUI를 지원하지 않는다. 사실 테스트툴의 GUI가 크게 필요로 하진 않지만 테스트결과나 테스트를 수행할때 GUI가 있으면 편한것은 사실이다.
web-dashboard라는 확장을 통해 GUI를 지원하긴 하지만 아주 제한적으로 지원된다.
웹 대시보드가 지원되긴 하지만 테스트 스크립트가 종료되면 대시보드또한 종료된다. replay 기능이 있긴 하지만 이렇게 쓰기엔 너무 힘들다.
k6를 선택한 큰 이유중 하나는 grafana와 통합이 좋다는 점이였다. 하지만 실제로 사용해보니 전혀 그렇지 못했다.
우선 grafana와 통합이 좋다는건 grafana cloud 를 사용할때의 얘기다. 하지만 오픈소스로 사용할때는 테스트 결과를 직접 수집하고 이를 grafana에서 시각화 해야한다.
띠용? 그럼 어떻게 수집을 해야하나??
많은 외부 db에 수집을 할 수 있지만 내가 선택한 방법은 influxdb
와 prometheus rw
였다.
하지만 influxdb
수집 방법은 influxdb1
버전을 기준으로만 동작했고 2.0 버전부터는 동작하지 않았다.
그래도 확장을 통해 influxdb2.0
에 데이터를 수집하는 방법을 찾긴 해서, 저장하고 시각화를 해봤다. (이 과정도 순탄치는 않다)
하지만 grafana로 테스트 결과를 확인하기에는 너무 치명적인 문제가 있었다.
grafana는 시계열 데이터를 보기위해 전역 시간을 설정해서 모든 패널이 공유한다. 하지만 특정 테스트의 시작과 끝을 알아야지만 이 시간을 설정할 수 있다.
때문에 지금 실행한 테스트를 보기에는 쉽지만 과거 테스트를 찾기 위해선 타임라인을 직접 뒤져야 한다는 큰 단점이 있었다.
nGrinder 는 네이버에서 개발한 성능 테스트 도구로, 한국어 커뮤니티가 활발하다는 특징이 있다.
nGrinder 는 컨트롤러, 에이전트라는 두가지 서비스로 구성되어 있다. 이런점은 구조가 복잡해지고 비용이 올라간다는 단점이 있긴 하다.
사용자는 컨트롤러에게 테스트를 요청하면, 컨트롤러에 연결된 에이전트가 그 테스트를 수행하는 방식이다.
그래도 docker-compose.yml
을 제공해줘 편하게 설정할 수 있었다. (지금까지 다른 툴들을 아무리 문서를 보고 따라해도 안맞는 부분이 너무 많아 따로 공부를 하고 진행해야 했다)
설치를 완료하면 다음과 같은 메인 화면을 볼 수 있다 (초기계정은 admin / admin)
여기서 스크립트를 작성하고, 성능 테스트 탭에서 작성한 스크립트를 사용해 테스트 계획을 수립하고 수행하는 방식이다.
nGrinder 의 테스트 스크립트는 groovy
와 jython
를 지원한다.
테스트 계획을 정의하고, 테스트를 시작하면 잠시후 테스트가 시작된다.
테스트가 끝나면 리포트를 받아볼 수 있다.
여러개의 에이전트로 구성되어 비교적 복잡한 구성을 가지지만, GUI를 통해 테스트를 편하게 진행할 수 있다는점, 과거 테스트 이력을 편하게 확인할 수 있다는점, 한국어 지원이 풍부하다는점이 nGrinder 를 테스트 툴로 선정하게 된 결정적인 이유가 되었다.
모니터링툴, 테스트툴에 대한 개인적인 생각이다
Collector
, Agent
로 나뉘어져 있어 설정이 복잡하고, 비용이 많이 들어간다는 단점이 있다. groovy
, jython(python)
으로만 작성해야 한다는 단점이 있다. (나에게는)