APM 도입 계기
1월 초 여느 때처럼 기술 사이트들을 둘러보다가 아래 글을 보게 되었다.
15 DevOps and SRE Tools you Should Know About in 2023
With the constantly evolving landscape of technology, professionals in the DevOps and SRE fields need...
dev.to
Elastic APM을 보고 바로 이거야~! 하고 서버팀에 글을 공유하고, 바로 로컬 테스트 해보고, 바로 CTO님한테 개발 서버에 도입해보겠다고 했다. (기존 prometheus, grafana도 내가 적용했지만 도입하고 들어가보지도 않았다.)
APM 도입 이유
- prometheus, grafana, zipkin 대체 가능
- Error count, API 처리 속도, 세부 쿼리 속도, 분산 추적, tpm 등등 모니터링 가능
- 아주 그냥 만능 도구라고 생각했다.
APM 구성
- Elasticsearch
- 수집된 데이터를 검색 및 집계를 하여 필요한 관심 있는 정보를 획득
- Kibana
- Elasticsearch의 빠른 검색을 통해 데이터를 시각화 및 모니터링버전
- APM
- Application Performance Monitoring의 약자
- APM Server, APM Agent로 구성
- APM Agent
- 실시간으로 Performance 및 error 데이터를 수집 하여 APM Server로 전달
- APM Server
- APM Agent에서 수집된 데이터에 대한 유효성 체크
- 수집된 데이터를 Elasticsearch의 Document 포멧으로 변환
- 버전
- 7.15.2
이렇게 해서 서버는 총 세개가 떠야 한다.
Docker-compose 구성
간단하게 하기 위해 docker compose로 구성했다. security는 아이디/비밀번호로 로그인하는 방식만 추가했다.(SSL은 나중에,,,)
https://www.elastic.co/guide/en/apm/get-started/7.15/quick-start-overview.html (공식문서)
https://github.com/deviantony/docker-elk (security 부분 참조)
두 코드를 짬뽕해서 구성했고 kibana에 도메인을 입힐 거라서 kibana 포트는 80으로 설정했다.
docker-compose.yml
version: '2.2'
services:
setup:
build:
context: setup/
args:
ELASTIC_VERSION: ${ELASTIC_VERSION}
init: true
volumes:
- setup:/state:Z
environment:
ELASTIC_PASSWORD: ${ELASTIC_PASSWORD:-}
LOGSTASH_INTERNAL_PASSWORD: ${LOGSTASH_INTERNAL_PASSWORD:-}
KIBANA_SYSTEM_PASSWORD: ${KIBANA_SYSTEM_PASSWORD:-}
networks:
- elastic
depends_on:
- elasticsearch
apm-server:
image: docker.elastic.co/apm/apm-server:${ELASTIC_VERSION}
depends_on:
- elasticsearch
- kibana
cap_add: [ "CHOWN", "DAC_OVERRIDE", "SETGID", "SETUID" ]
cap_drop: [ "ALL" ]
ports:
- 8200:8200
networks:
- elastic
command: >
apm-server -e
-E apm-server.rum.enabled=true
-E setup.kibana.host=kibana:80
-E setup.template.settings.index.number_of_replicas=0
-E apm-server.kibana.enabled=true
-E apm-server.kibana.host=kibana:80
-E apm-server.kibana.username=elastic
-E apm-server.kibana.password=${ELASTIC_PASSWORD:-}
-E output.elasticsearch.host=elasticsearch:9200
-E output.elasticsearch.username=elastic
-E output.elasticsearch.password=${ELASTIC_PASSWORD:-}
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION}
volumes:
- ./volume/elasticsearch-volume:/usr/share/elasticsearch/data
environment:
- xpack.security.enabled=true
- discovery.type=single-node
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD:-}
- ES_JAVA_OPTS=-XX:UseAVX=2 -Xms1g -Xmx1g # local 실행 시 주석
ports:
- 9200:9200
networks:
- elastic
kibana:
image: docker.elastic.co/kibana/kibana:${ELASTIC_VERSION}
depends_on:
- elasticsearch
ports:
- "80:5601"
environment:
KIBANA_SYSTEM_PASSWORD: ${KIBANA_SYSTEM_PASSWORD:-}
ELASTICSEARCH_USERNAME: elastic
ELASTICSEARCH_PASSWORD: ${ELASTIC_PASSWORD:-}
networks:
- elastic
volumes:
setup:
networks:
elastic:
driver: bridge
APM Agent 추가
이제 모니터링 하고자 하는 서버에 Agent를 추가해주어야 한다. Agent가 APM server에 각종 metric을 전송한다.
https://www.elastic.co/guide/en/observability/7.15/instrument-apps.html (공식문서)
- 위 페이지에 들어가서 Agent 다운로드
- 프로젝트에 추가( /src/main/apm 경로에 넣었다.)
- 서버 실행 시에 VM option을 추가해준다. (intelliJ의 경우 run configurations → add vm options)
-javaagent:./src/main/apm/elastic-apm-agent-1.35.0.jar
-Delastic.apm.service_name=service-name-local
-Delastic.apm.server_urls=http://localhost:8200
-Delastic.apm.application_packages=kr.co.packages.path
Jib 이용 시 이미지에 Agent 추가
우리 회사는 도커 이미지를 만든 후 배포하는데 이때 jib을 이용한다.
도커 이미지에 APM agent가 추가되도록 해야하고 entrypoint에 vm option도 추가하려고 한다.
jib {
extraDirectories {
paths = ['src/main/apm', 'build/libs']
}
from {
image = 'openjdk:17-alpine'
}
container {
entrypoint = ['java',
'-javaagent:./elastic-apm-agent-1.35.0.jar',
'-Delastic.apm.server_urls=http://apm.server.com:8200',
'-Delastic.apm.application_packages=kr.co.package.path',
'-jar', 'api-1.0-SNAPSHOT.jar'
]
jvmFlags = ['-Xms512m', '-Xmx512m', '-Xdebug', '-XshowSettings:vm', '-XX:+UnlockExperimentalVMOptions', '-XX:+UseContainerSupport']
}
}
extraDirectories에 agent가 있는 경로를 추가해주었고 entrypoin 코드도 추가해주었다.
vm option을 주는 방법으로 jvmFlags에 추가하라고 했는데 안 돼서 entrypoint에 직접 적어주었다.
개발과 운영 서버에서 apm.service_name은 ecs task 환경변수로 정의해서 전달하고 있다.
Kibana에서 APM 보는 법
- kibana 접속
- 메뉴 Observability -> APM
APM 도입 후 활용 경험
도입 후에 팀원 분이 APM 너무 좋다고 하루에 한 번씩 이야기 해주는데 너무 뿌듯,,ㅎ
- 응답시간 긴 API의 경우 어느 로직에서 오래 걸리는지 확인하고 개선점을 빠르게 찾을 수 있다.
- 배포 전에 tpm(transactions per minute)으로 API 호출량이 많은지 확인하고 배포를 미룰 수 있다.
- JVMs 메뉴에서 15시간 동안 생성됐던 서버 90개가 넘는 것을 보고 원인 파악 후 서버 스펙 변경한 적이 있다.
이정도로도 APM에 도입에 투자한 시간이 전혀 아깝지가 않다.
다음 게시글은 해당 구성에 logstash만 추가하는 글이 될 것이다.
'DevOps > Monitoring' 카테고리의 다른 글
[AWS/RDS] RDS MySQL 슬로우쿼리 모니터링 -> 슬랙 알림 (0) | 2022.09.04 |
---|---|
[AWS] CloudWatch로 EC2 인스턴스 종료 모니터링 (0) | 2022.09.04 |
[AWS] CloudWatch 이상 지표 슬랙 전송(SNS, Lambda) (0) | 2022.08.21 |