MySQL의 metrics에 접근하기 위해서는 MySQL Exporter를 사용하여야 합니다.
이를 통해 mySQL의 Threads_running, Queries, Innodb_rows_read 등의 metrics를 가져올 수 있습니다.
기본적으로 변환된 메트릭 데이터를 9104 포트의 /metrics 엔드포인트를 통해 HTTP로 외부에 노출합니다
MySQL Exporter가 수집한 데이터를 Prometheus가 주기적으로 가져와 저장하며, 이 데이터를 그라파나가 시각화합니다
구현
docker-compose.yml 파일 수정
services:
airdnb-prometheus:
image: prom/prometheus
# 로컬에서 만든 prometheus.yml을 컨테이너 안에 그대로 덮어씌워서 사용
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
networks:
- monitoring-net
# grafana
airdnb-local-grafana:
image: grafana/grafana
ports:
- "3001:3000"
networks:
- monitoring-net
mysql_exporter_service:
image: prom/mysqld-exporter:latest
container_name: mysql-exporter
restart: always
ports:
- "9104:9104"
command:
- "--mysqld.username=taehyun:0136"
- "--mysqld.address=host.docker.internal:3306"
networks:
- monitoring-net
networks:
monitoring-net:
MySQL Exporter는 기본적으로 9104 포트를 사용하며, 로컬 MySQL에 접근하기 위해 Exporter 전용 계정을 생성해야 합니다.
로컬 mysql에 접근하여 아래와 같은 명령어를 통해 Exporter 계정 생성
CREATE USER '[아이디]'@'%' IDENTIFIED BY '[비밀번호]';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO '[아이디]'@'%';
FLUSH PRIVILEGES;
저 같은 경우 taehyun에 0136으로 설정
command:
- "--mysqld.username=taehyun:0136"
- "--mysqld.address=host.docker.internal:3306"
‼️‼️ 문제 발생
MySQL Exporter의 공식 문서에서 권장하는 environment를 사용하여 DATA_SOURCE_NAME을 통해 mysql에 접근하는 방식이 작동하지 않아 위와 같이 설정
~~environment~~:
~~- DATA_SOURCE_NAME=taehyun:0136@(host.docker.internal:3306)/~~
prometheus.yml 파일에 아래 코드 추가
- job_name: "mysql"
metrics_path: '/metrics'
static_configs:
- targets: ['mysql_exporter_service:9104']

Grafana 연동
이전에 만든 datasource를 통해 7362번으로 임포트하여 대시보드를 생성

그라파나 mysql 주요 기능
MySQL 서버가 현재까지 가동된 시간초당 처리된 쿼리 수InnoDB의 버퍼 풀 크기현재 연결된 클라이언트 수와 최대 사용된 연결 수MySQL 클라이언트의 활성 스레드 수 데이터베이스 테이블의 잠금 발생 빈도MySQL에서 캐시된 스레드 수와 캐시 크기Kafka를 모니터링 하기 위해 kafka exporter를 사용하도록 하겠습니다.
기존의 로컬에서 사용하던 카프카를 docker 컨테이너에서 사용하도록 변경하였습니다.
test-kafka:
image: confluentinc/cp-kafka:latest
container_name: test-kafka
ports:
- "29092:29092"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: 'broker,controller'
KAFKA_CONTROLLER_QUORUM_VOTERS: '1@test-kafka:29093'
# 프로젝트는 로컬에서 실행중
KAFKA_LISTENERS: 'PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:29093,PLAINTEXT_HOST://0.0.0.0:29092'
KAFKA_ADVERTISED_LISTENERS: 'PLAINTEXT://test-kafka:9092,PLAINTEXT_HOST://localhost:29092'
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT'
KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT'
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
CLUSTER_ID: 'ciWo7IWazngRchmPES6q5A=='
KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
networks:
monitoring-net:
test-kafka-cli:
image: confluentinc/cp-kafka:latest
container_name: test-kafka-cli
entrypoint: /bin/sh
tty: true
networks:
monitoring-net:
kafka-exporter:
image: danielqsj/kafka-exporter:latest
container_name: kafka-exporter
ports:
- "9308:9308"
command: [ "--kafka.server=test-kafka:9092" ]
networks:
- monitoring-net
depends_on:
- test-kafka
restart: always ‼️ kafka-exporter가 Kafka에 접속하지 못하는 문제 발생 ( connection refused ) ‼️
Connection refused 오류는 다음 두 가지 원인으로 인해 발생할 수 있습니다.
docker-compose.yml에서 depends_on 설정은 단순히 컨테이너가 실행되었음만 보장하므로, Kafka 브로커가 완전히 기동되고 연결을 받을 준비가 될 때까지 보장하지는 않습니다.
이러한 상황을 해결하기 위해, restart: always 설정을 사용하면 Kafka Exporter가 일시적인 연결 실패 후에도 자동으로 재시작을 시도하여, Kafka 브로커가 준비될 때까지 계속 접속을 시도하게 하여 문제를 해결하였습니다.
spring.kafka.producer.bootstrap-servers=localhost:29092
queue.event.topic.name=test_queueing_system
spring.kafka.consumer.bootstrap-servers=localhost:29092
spring.kafka.consumer.group-id=test_consumer_group01
spring.kafka.consumer.auto-offset-reset=earliest - job_name: 'kafka'
static_configs:
- targets: [ 'kafka-exporter:9308' ] 이후 promethus에서 kafka-exporter metric을 잘 수집하는지 확인해보면 정상적으로 up 되는 것을 확인할 수 있음

이를 통해 Grafana에서 7589 대시보드를 만들어 확인 가능

임의로 특정 토픽에 100개의 메세지를 보냈을 때의 그래프
Kafka-cli 컨테이너에서 아래 명령어 실행
sh-5.1$ kafka-verifiable-producer --topic test_queueing_system --max-messages 100 --bootstrap-server test-kafka:9092

kafka-ui:
image: provectuslabs/kafka-ui
container_name: kafka-ui
ports:
- "8989:8080"
restart: always
environment:
- KAFKA_CLUSTERS_0_NAME=local-single-broker
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=test-kafka:9092
networks:
monitoring-net: 이후 http://localhost:8989/ 에 접근하면 kafka ui에 접근 가능

UI for Apache Kafka 옵션
[ 메인 대시보드 ]
[ Broker 대시보드 ]
[ Topic 대시보드 ]

[ consumer 대시보드 ]
Redis 모니터링을 위해 redis-exporter를 사용할 예정이며, 현재 Redis는 컨테이너가 아닌 로컬 환경에서 실행 중입니다.
docker-compose.yml 파일에 추가
redis-exporter:
container_name: redis-exporter
image: oliver006/redis_exporter:latest
# 로컬에서 사용중인 redis 사용
environment:
- REDIS_ADDR=redis://host.docker.internal:6379
ports:
- "9121:9121"
depends_on:
- airdnb-prometheus
networks:
- monitoring-net
restart: always
prometheus.yml 파일에 추가
- job_name: 'redis-exporter'
static_configs:
- targets: [ 'redis-exporter:9121' ]
application.properties 설정
redis.host = localhost
redis.port = 6379
이후 promethus에서 redis-exporter가 metric을 잘 수집하는지 확인해보면 정상적으로 up 되는 것을 확인할 수 있음

Grafana에서 14615 대시보드를 import 하여 실행

각각 서버 1, 2, 3의 부하



분산 서버 환경으로 확장함으로써, 단일 서버 환경에서 나타나던 부하로 인한 간헐적 오류가 해소되었고, 요청 분산이 효과적으로 이루어짐을 검증할 수 있었습니다.