[쿠폰] 서버 모니터링 및 부하테스트

2024. 5. 12. 17:03프로젝트

 

https://github.com/Jungsu-lilly/Coupon-Service/issues/13

 

서버 모니터링 및 배포 · Issue #13 · Jungsu-lilly/Coupon-Service

Description 📝 Grafana로 서버 모니터링을 수행합니다. 실제 서비스를 배포하고 성능 테스트를 진행합니다. TODO ✅ grafana로 서버 모니터링 환경 구축 성능 테스트 수행

github.com

 

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만명이고, 따라서 톰캣 연결 수도 가파르게 증가합니다.

 

그라파나 - connections 지표

 

이와 같이 프로메테우스 + 그라파나로 서비스를 테스트, 모니터링 수 있습니다.

 


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 로 가는 부하를 크게 줄일 수 있었습니다.