2024. 5. 12. 17:03ㆍ프로젝트
https://github.com/Jungsu-lilly/Coupon-Service/issues/13
Prometheus + Grafana 를 사용해 서버 매트릭을 수집하고, 모니터링한 과정을 작성하려고 합니다.
실제 AWS 에 배포한 후 CloudWatch로 모니터링도 진행했습니다.
현재 프로젝트는 3가지 모듈로 구성되어 있습니다.
- coupon-api
- 제일 앞단에서 API 요청을 받는 서버, 응답 또한 반환한다.
- coupon-core
- 서비스 비즈니스 로직 및 공통 로직이 포함되어 있다.
- coupon-consumer
- 쿠폰을 발급하는 로직을 담당하는 서버.
- 레디스 큐에 있는 적재된 발급 요청 내역들을 순차적으로 처리하는 역할을 한다.
배포에서 사용할 application profile 설정입니다.
application-api.yml
spring:
application:
name: coupon-api
server:
port: 8080
tomcat:
mbeanregistry:
enabled: true
management:
metrics:
tags:
application:
${spring.application.name}
endpoints:
web:
exposure:
include: prometheus
consumer 에도 해당 설정을 적용해주었습니다.
application-consumer.yml
spring:
application:
name: coupon-consumer
server:
port: 8081
management:
metrics:
tags:
application:
${spring.application.name}
endpoints:
web:
exposure:
include: prometheus
마지막으로는 application-core.yml 에 최종 prod 프로필 설정을 해줍니다.
spring:
config:
activate:
on-profile: prod
datasource:
hikari:
jdbc-url: jdbc:mysql://{{PROD_URL}}:3306/coupon?useUnicode=yes&characterEncoding=UTF-8&rewriteBatchedStatements=true
driver-class-name: com.mysql.cj.jdbc.Driver
maximum-pool-size: 10
max-lifetime: 30000
connection-timeout: 3000
username: admin
password: {RDS_PASSWORD}
jpa:
hibernate:
ddl-auto: update
show-sql: false
properties:
hibernate:
format_sql: true
data:
redis:
host: {REDIS_URL}
port: 6380
프로메테우스로 8080 포트의 매트릭을 지속적으로 수집하고, 그라파나로 데이터를 시각화하고 대시보드로 만들어 활용할 것입니다.
Grafana 테스트 해보기 (in 로컬)
톰캣의 현재 connections 수를 모니터링 해보겠습니다.
Locust로 부하테스트 진행
- 최대 유저 수 : 10000
- 초당 200명의 유저 생성
최대 동시 접속자 수는 1만명이고, 따라서 톰캣 연결 수도 가파르게 증가합니다.
이와 같이 프로메테우스 + 그라파나로 서비스를 테스트, 모니터링 수 있습니다.
AWS ec2, rds, elasticache 에 서버를 띄우고, 실제 모니터링, 성능 테스트를 수행해보겠습니다.
ElastiCache - Redis 캐시를 생성해줍니다.
스펙 : t3.micro
RDS - DB를 띄워줍니다.
스펙 : t3.micro
EC2 인스턴스는 3개 생성해줍니다.
원래는 coupon-api, coupon-consumer 용으로 2개만 띄워도 되지만, ElastiCache 테스트용 서버를 하나 더 두었습니다.
서버 스펙은 각각 t2.medium 으로 설정했습니다. (레디스 테스트 서버 제외)
coupon-consumer 서버 실행 : prod 프로필
listen... 을 출력하면서 리스너를 실행시키고 있습니다.
(coupon-consumer 는 대기하면서 Redis 대기열 큐에 있는 요청을 처리하는 역할을 하는 서버입니다.)
마찬가지로 coupon-api 서버도 띄워줍니다.
서버 매트릭 수집하기
coupon-api, coupon-consumer 에 있는 매트릭을 프로메테우스로 수집해줍니다.
coupon-api, consumer 가 타겟으로 잡혀 있고, OK 상태입니다. (현재 ip 주소가 노출되어 있지만, 테스트 후 서버는 모두 내렸습니다.)
그라파나 : coupon-api, coupon-consumer 모니터링 중
CloudWatch
- RDS, Redis에 관한 매트릭을 수집, 모니터링
부하 테스트
조건 : 최대 유저 2천명, 초당 200명의 유저 생성
결과 - cloudwatch
트래픽을 받고 있는 Redis 는 크게 부하를 받지 않습니다. RDS 도 마찬가지.
부하를 받는 동안 레디스 커맨드 수와, 네트워크 수도 순간적으로 올라갔습니다.
CPU Usage 가 각각 4~5%, 2.1% 정도로, 아주 여유롭습니다. 이는 서버에서 로컬 캐시를 활용해 DB, Redis 로 가는 횟수를 많이 줄였기 때문입니다.
그라파나 - 서버 매트릭 수집
다만 Coupon-api 의 CPU 부하가 100% -> 해당 서버는 Scale-Out이 필요할 것 같습니다. (또는 Scale-Up)
즉 DB, Redis 에 가는 부하는 획기적으로 줄였지만, 서버 자체의 성능은 부족한 것으로 보입니다.
정리
약 29만 건의 요청에 대하여 Failure 는 90건 : 0.03% 의 실패율
초당 200명씩 생성, 최대 2000명의 유저가 동시 요청을 보내도, 99.97 % 확률로 동작하는 서버를 구축했습니다.
평균 응답 속도는 약 81ms, 평균 RPS 는 5000 으로 볼 수 있을 것 같습니다.
동시성 이슈를 해결하여 처음에는 분산 락을 사용했습니다.
하지만 성능이 저조했고, 병목을 해결하기 위해 Redis 쿼리를 사용해 RPS 를 4~5배 향상 시켰습니다.
후에는 Redis 캐시를 로컬 캐시로 바꾸어 Redis 로 향하는 빈도를 줄였고, 그 결과 레디스 및 RDS 로 가는 부하를 크게 줄일 수 있었습니다.
'프로젝트' 카테고리의 다른 글
[프로젝트] 레디스 Pub/Sub, RabbitMQ 도입으로 구조 개선 (0) | 2024.06.18 |
---|---|
[프로젝트] SSE 로 실시간 알림 기능 구현하기 (0) | 2024.06.13 |
레디스 쿼리로 서버 RPS 개선 (0) | 2024.04.29 |
[쿠폰] Redis 기반 비동기 시스템 구현 (0) | 2024.04.21 |
[쿠폰] 트러블 슈팅 - 동시성 처리 (0) | 2024.04.15 |