APM과 성능테스트

이동엽·2024년 9월 1일
4

인프라

목록 보기
1/1
post-thumbnail

1. APM 소개

1.1 APM 정의

  • Application Performance Management의 약자
  • 애플리케이션의 성능을 모니터링, 관리, 최적화하는 데 중점을 둔 도구와 프로세스의 집합
  • 애플리케이션이 어디에서 성능 문제가 발생하는지, 사용자 경험에 어떤 영향을 미치는지를 파악하는 데 사용

1.2 APM의 역할

  1. 애플리케이션 성능 모니터링
    • 애플리케이션의 성능 지표(예: 응답 시간, 처리량, 오류율 등)를 실시간으로 모니터링
    • 이를 통해 애플리케이션의 상태를 지속적으로 파악하며, 오류나 예외를 실시간으로 감지하여 알림
  2. 트랜잭션 추적
    • 사용자가 애플리케이션과 상호작용하는 모든 트랜잭션의 흐름을 추적
    • 이를 통해 성능 병목 현상이 발생하는 지점을 식별하고, 특정 요청이 어디에서 지연되는지 분석
  3. 리소스 사용 모니터링
    • 애플리케이션이 사용하는 서버, CPU, 메모리, 네트워크 등 자원의 사용량을 모니터링
    • 이 정보를 통해 자원 최적화 및 확장을 위한 계획 수립에 도움

2. APM 도구 소개

2.1 상용 APM

Datadog

소개

  • 클라우드 기반의 모니터링 및 분석 도구
  • 서버, 데이터베이스, 도구 및 서비스의 성능 데이터를 실시간으로 수집하고 시각화

특징

  • 로그, 메트릭, 트레이스 통합 모니터링
  • 클라우드 네이티브 환경에 최적화
  • 다양한 통합 옵션 및 대시보드 커스터마이징 기능

각 Service의 Health Check 및 오류 로그 추적, API 응답 속도를 모니터링 하는 화면 예시 (출처 : 올리브영 기술블로그)

Jaeger

소개

  • 분산 트레이싱 시스템으로, MSA에서의 트랜잭션을 추적하고 성능 문제를 분석하는 데 사용
  • 트랜잭션의 흐름과 지연 시간을 시각적으로 분석 가능

특징

  • 분산 트레이싱 및 시각화
  • 트랜잭션 흐름 추적
  • CNCF 프로젝트로 클라우드 네이티브 지원

Jaeger Architecture

  • 추적 저장소로 NoSQL 데이터베이스인 Cassandra와 Elasticsearch를 지원
  • Jaeger의 UI를 사용하여 개별 추적을 시각화 가능

서비스, 기간 및 태그 등으로 추적을 필터링한 UI

Elastic APM

소개

  • Elastic Stack(Elasticsearch, Logstash, Kibana 등)과 통합되어 구축된 애플리케이션 모니터링 도구
  • 실시간 데이터 분석과 강력한 시각화 기능을 제공

특징

  • 애플리케이션 트랜잭션 추적
  • Kibana와의 통합으로 강력한 대시보드 제공
  • 다양한 언어 및 프레임워크 지원로그 분석과 통합된 모니터링

Elastic APM 아키텍처

  • APM Agent : 서비스에 설치되는 성능 데이터 수집 라이브러리
  • APM Server : 에이전트로부터 데이터를 수신, 검증 처리
  • Elasticsearch : APM 성능 지표를 저장
  • Kibana : 데이터 시각화

시각화 예시

2.2 오픈소스 APM

Prometheus

소개

  • 클라우드 네이티브 환경에서 매우 강력한 시계열 데이터베이스 및 모니터링 도구
  • 메트릭 수집, 쿼리, 시각화와 경고 시스템을 제공하여 복잡한 시스템의 성능을 모니터링하는 데 유용

특징

  • 시계열 데이터 저장
  • 강력한 쿼리 언어 (PromQL)
  • Grafana와의 통합
  • 클라우드 네이티브 및 컨테이너 환경 지원

아쉬운 점

  • Prometheus는 분산 추적을 제공하지 않는다. (시계열 데이터를 메트릭으로 모니터링하는 데 효과적)
  • 또한 단일 머신을 위해 설계되었기 때문에 규모에 제한이 있다.
  • 기본 UI의 기능이 제한적이기에, Grafana로 함께 시각화를 구성한다.

Zipkin

소개

  • 분산 트레이싱 도구로, 애플리케이션의 성능 문제를 추적하고 분석하는 데 유용
  • 다양한 서비스 간의 호출 관계와 지연 시간을 시각화

특징

  • 분산 트레이싱
  • 서비스 호출 관계 시각화
  • 다양한 저장소와의 호환성

Zipkin Architecture

  • Reporter : 각각의 서비스가 해당
  • Collector : 메트릭을 수집 / Store : 메트릭을 저장 / Database : 별도 DB 저장시 요구
  • API : 메트릭(Trace Id, Span Id ..)을 쿼리하는 API
  • UI : 사용자 인터페이스

아쉬운 점

  • Zipkin의 UI는 기능이 제한적이기에, Grafana나 Kibana 등과 함께 사용해야 효과적이다.

Pinpoint

소개

  • 대규모 분산 시스템에서의 Java 및 PHP 애플리케이션의 성능을 모니터링하는 오픈소스 APM 도구
  • 트랜잭션 추적과 애플리케이션 호출 관계를 시각적으로 표현하는 데 강점

특징

  • Java 및 PHP 애플리케이션 지원
  • 자동 트랜잭션 추적
  • 애플리케이션 호출 관계 시각화
  • 오픈소스 및 커스터마이징 가능

Pinpoint Architecture

  • 각각의 애플리케이션 내 JVM에 Pinpoint Agent를 설치(성능에 미치는 영향은 미미함)
  • Agent는 gRPC(구글의 원격 프로시저 호출 프레임워크)를 이용해 데이터를 전송
  • Collector는 Agent로부터 받은 데이터를 HBase에 저장
  • Web UI에서 확인

UI 예시

2.3 핀포인트로 모니터링 구축하기

Agent가 Collector로 로그를 전송할 때, 9991~9993 포트를 이용하기 때문에, 다른 서버에 존재할 경우 포트를 열어두어야 한다. 또한, HBase 상태를 확인하기 위한 16010 포트와 Web을 위한 8080 포트도 열어두어야 한다.

HBase 구성

Pinpoint는 HBase 1.2.X 버전에 최적화되어 있다.

# 설치 후 압축 해제
wget <https://archive.apache.org/dist/hbase/1.2.7/hbase-1.2.7-bin.tar.gz>
tar xzvf hbase-1.2.7-bin.tar.gz

# vi로 아래 내용 주석처리 (실행 시 warning 제거 역할)
vi /home/ubuntu/hbase-1.2.7/conf/hbase-env.sh >>>>>>>

# Configure PermSize. Only needed in JDK7. You can safely remove it for JDK8+
# export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m -XX:ReservedCodeCacheSize=256m"
# export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m -XX:ReservedCodeCacheSize=256m"
<<<<<<<< EOF

# hbase 시작
hbase-1.2.7/bin/start-hbase.sh

Pinpoint 정보를 담을 테이블 생성하기

# 스크립트 다운로드 후 실행
wget <https://raw.githubusercontent.com/pinpoint-apm/pinpoint/master/hbase/scripts/hbase-create.hbase>

hbase-1.2.7/bin/hbase shell hbase-create.hbase

Collector 구성

# 설치 후 실행 권한 부여
wget <https://github.com/pinpoint-apm/pinpoint/releases/download/v2.2.2/pinpoint-collector-boot-2.2.2.jar>
chmod +x pinpoint-collector-boot-2.2.2.jar

# 실행
nohup java -jar -Dpinpoint.zookeeper.address=localhost pinpoint-collector-boot-2.2.2.jar >/dev/null 2>&1 &

Pinpoint Web 구성

# 설치 후 실행 권한 부여
wget <https://github.com/pinpoint-apm/pinpoint/releases/download/v2.2.2/pinpoint-web-boot-2.2.2.jar>
chmod +x pinpoint-web-boot-2.2.2.jar

# 실행
nohup java -jar -Dpinpoint.zookeeper.address=localhost pinpoint-web-boot-2.2.2.jar >/dev/null 2>&1 &

Pinpoint Agent 구성

# agent 설치
wget <https://github.com/pinpoint-apm/pinpoint/releases/download/v2.2.2/pinpoint-agent-2.2.2.tar.gz>

# 압축 해제
tar xvzf pinpoint-agent-2.2.2.tar.gz

# 이동
cd pinpoint-agent-2.2.2

# config 파일 수정
sudo vi pinpoint-root.config

# 모니터링이 설치된 IP 주소 입력(동일 서버일 경우 127.0.0.1)
profiler.transport.grpc.collector.ip={pinpoint ip}

Agent와 함께 Spring Boot 기동

# 절대경로로 작성해주어야 함
sudo java \
-javaagent:/home/ubuntu/pinpoint-agent-2.2.2/pinpoint-bootstrap-2.2.2.jar \
-Dpinpoint.agentId=helloDongyeop \
-Dpinpoint.applicationName=hello \
-Dpinpoint.config=/home/ubuntu/pinpoint-agent-2.2.2/pinpoint-root.config \
-jar /home/ubuntu/hello.jar &

실행 결과

3. 성능 테스트 도구

3.1 nGrinder

nGrinder 소개

  • 네이버에서 진행한 오픈 소스 프로젝트로 서버의 부하 테스트를 위한 도구
  • 주요 기능
    • 스크립트 레코딩: 웹 브라우저에서 사용자 동작을 녹화하여 테스트 스크립트를 생성
    • 분산 테스트: 다수의 에이전트 머신을 사용하여 대규모 테스트를 수행
    • 실시간 모니터링: 테스트 진행 중에 성능 지표를 실시간으로 모니터링
    • 분석 및 리포팅: 테스트 결과를 다양한 그래프와 테이블로 분석하고, 리포트를 생성
  • JMeter와 차이점
    • JMeter는 단일 데스크톱 컴퓨터에서 수행되는 반면, nGrinder 는 컨트롤러 및 에이전트로 구성된 분산 아키텍처로 수행된다.
    • nGrinder는 jython 또는 Groovy 같은 스크립트 언어를 사용하여 스크립트를 작성한다.
    • 도커, 클라우드 환경에서도 실행 가능하다.

nGrinder 주요 개념

  • Controller
    • 테스트를 생성하고, 실행하고, 테스트 결과를 수집하고 분석
    • 단일 머신에 설치
  • Agent
    • 컨트롤러가 생성한 테스트를 수행하는 실행 환경
    • 각 에이전트는 분산된 머신 또는 가상 머신에 설치
    • 에이전트가 테스트에 필요한 부하를 생성하고, 데이터를 수집하여 컨트롤러에 전송

nGrinder 사용 방법

  1. nginder 설치 (버전 참고 링크)
wget <https://github.com/naver/ngrinder/releases/download/ngrinder-3.5.9-p1-20240613/ngrinder-controller-3.5.9-p1.war>

2. nginder 실행

ngrinder는 현재(2024.08.25)까지 Java 8과 11까지만 지원하고 있다.

따라서, Java 11 환경에서 실행하기 위해 아래와 같이 Docker 환경을 구성

nGrinder-Controller를 위한 Dockerfile

# ngrinder-controller-3.5.9-p1.war 파일이 존재하는 디렉토리에 작성
FROM openjdk:11-slim

ARG WAR_FILE=./*war
COPY ${WAR_FILE} app.war

ENTRYPOINT ["java", "-jar", "/app.war"]

docker-compose.yml

version: "3.8"
services:
  ngrinder-controller:
    container_name: ngrinder-controller-arm

    build:
      context: ./ngrinder-controller
      dockerfile: Dockerfile
    restart: always

    ports:
      - "8080:8080"
      - "12000-12100:12000-12100"
      - "16001:16001"

3. 실행 결과 확인

{서버주소:8080} 접속시, 초기 계정 : admin/admin

4. Agent 설치

5. Agent 압축 해지 및 실행

압축 해지

tar -xvf ngrinder-agent-3.5.9-p1-localhost.tar

nGrinder-agent를 위한 Dockerfile

controller와 마찬가지로 agent 또한 Java 8/11 만 지원하기에 Docker 환경 구성

# run_agent.sh 이 존재하는 디렉토리에 작성
FROM openjdk:11-slim
COPY / /home/

CMD /home/run_agent.sh -ch ngrinder-controller-arm

docker-compose.yml 수정

version: "3.8"
services:
  ngrinder-controller:
    container_name: ngrinder-controller-arm

    build:
      context: ./ngrinder-controller
      dockerfile: Dockerfile
    restart: always

    ports:
      - "8080:8080"     # nGrinder UI 포트
      - "12000-12100:12000-12100"  # nGrinder Agents 포트(에이전트 개수만큼 12000+@)
      - "16001:16001"   # nGrinder Controller 포트
    networks:
      - ngrinder

  ngrinder-agent:
    container_name: ngrinder-agent-arm
    depends_on:
      - ngrinder-controller
    build:
      context: ./ngrinder-agent
      dockerfile: Dockerfile
    restart: always

    networks:
      - ngrinder

networks:
  ngrinder:
    driver: bridge

실행 결과 확인

6. 테스트 스크립트 작성



7. 테스트 스크립트 실행 결과 확인

8. 성능 테스트 (Performance Test) 작성

9. 성능테스트 실행 결과 조회

3.2 Apache Benchmarking (AB)

AB 소개

  • AB(Apache HTTP server benchmarking tool)는 커맨드 라인을 활용한 매우 가볍고 유용한 웹서버 벤치마킹 도구
  • 간단한 REST API나 정적 컨텐츠에 대한 성능 테스트 시에 빠르고 간편하게 벤치마킹 정보를 얻어올 수 있다.
  • 성능개선 작업을 진행하면서 수정된 API에 대해서 개발환경에는 ngrinder를 활용하고, 운영 환경에서는 설치 및 성능테스트틀 하기 힘든 환경이라 AB를 활용해서 테스트를 하는 경우도 있다.

AB 참고사항

  • HTML이나 CSS, image등은 해석하지 않는다.
  • HTTP 1.0 클라이언트를 사용한다.
  • 동적 페이지는 Content-Length 헤더 내용을 미리 작성할 수 없기 때문에 -k KeepAlive 옵션이 동작하지 않는다.
  • request간에 delay를 주는 옵션은 없으므로 DDOS attack으로 간주 될 수 있다.

AB 옵션 설명

옵션설명
-n성능을 검사하기위해 보내는 요청수.
-c동시에 요청하는 요청수. 기본적으로 한번에 한 요청만을 보낸다.
-H요청에 헤더 추가
-p바디와 함께 POST 요청
-u바디와 함께 PUT 요청
-TContent-Type 지정
-g측정한 모든 값을 'gnuplot' 혹은 TSV (Tab separate values, 탭으로 구분한 값) 파일에 기록한다. 라벨은 output 파일의 첫번째 라인을 참고한다.
-t성능을 검사하는 최대 초단위 시간. 내부적으로 -n 50000을 가정한다. 정해진 시간동안 서버 성능을 검사할때 사용한다. 기본적으로 시간제한 없이 검사한다.
-v출력 수준을 지정한다.4 이상이면 헤더에 대한 정보를,3 이상이면 (404, 202, 등) 응답코드를,2 이상이면 경고(warning)와 정보(info)를 출력한다.
-A프록시를 통해 BASIC Authentication 정보를 제공한다.:로 구분한 사용자명과 암호를 base64 인코딩하여 전송한다.
-Xproxy[:port] 프록시 서버를 사용하여 요청한다.

AB 사용 방법

Apache2-Utils 설치

$ sudo apt-get install apache2-utils

google.com/index.html 파일에 10개의 동시 요청으로 총 100개의 요청을 벤치마킹한 예시

위 요청에서 실패율이 높은 이유

  • AB는 매번 응답이 동일한 정적 웹 서버를 테스트하기에 적합
  • 다만, 요청을 보낸 google의 경우는 동적 웹페이지를 응답하여, 같은 요청에 대해 응답 크기가 매번 달라질 수 있다. (예를 들어, 광고, 실시간 데이터, 또는 다른 외부 콘텐츠..)
  • 이러한 경우 ApacheBench는 이를 "Length" 오류로 처리

Gnuplot으로 결과 시각화

Gnuplot 이란?

  • gnuplot은 Command-line 기반의 그래픽 유틸리티로 2D나 3D 그래프를 쉽게 그릴 수 있다.
  • AB는 간략하게 결과는 바로 확인해 볼 수 있으나 디테일한 각 요청에 대한 로그 값을 원하는 경우, -g [data_file] 옵션을 사용해 gnuplot 형식으로 데이터를 남길 수 있다.

Gnuplot 설치

$ sudo apt install -y gnuplot

요청별 응답 시간을 그래프로 그려주는 쉘 스크립트 작성(script.plot)

# 터미널 사이즈 조정(이미지 사이즈)
set terminal png size 1024,768

# 가로, 세로 비율
set size 1,0.5

# 결과 파일 설정
set output "result.png"

# 범례/key 위치
set key left top

# y축 grid line
set grid y

# Label the x-axis
set xlabel 'requests'

# Label the y-axis
set ylabel "response time (ms)"

# Tell gnuplot to use tabs as the delimiter instead of spaces (default)
set datafile separator '\\t'

# Plot the data
plot "result.plot" every ::2 using 5 title 'response time' with lines
exit

시각화 결과

$ gnuplot script.plot

4. 마무리

Pinpoint를 이용해 APM을 구축해보았고, nGrinder와 Apache Bench(AB)를 이용해 성능 테스트를 진행해보았다.

Pinpoint와 nGrinder는 Java 8/11 에서만 동작한다는 점이 아쉬웠고, AB의 경우는 정적 웹 서버를 테스트하기에 적합하다는 점에서 API 성능을 테스트하기에는 부적절했다.

분산 환경에서의 요청을 추적하고 모니터링하기에는 Pinpoint는 Java 8 환경을 도커로 구축한다면 괜찮은 것 같지만, 성능 테스트의 경우는 Apache Jmeter가 nGrinder와 Apache Bench보다 개인적으로는 더 좋아보인다.

5. 참고자료

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

0개의 댓글