민스씨의 일취일장

프로젝트 LOG | 로드밸런스 도입해 서비스 이중화하기 본문

Projects/MetaPay

프로젝트 LOG | 로드밸런스 도입해 서비스 이중화하기

읻민스 2024. 8. 30. 20:48
반응형

서비스 컨테이너를 하나 더 띄워서 서비스를 이중화 하고, 이를 위해 로드밸런서를 도입하는 과정(Github Issues #18)에 대한 글입니다.

로드밸런서 도입해 서비스 이중화하기

로드밸런서 도입해 서비스 이중화하기 썸네일 이미지이다.
로드밸런서 도입해 서비스 이중화하기

작업 순서 계획

1. 새로운 서버에 동일한 PaymentService 컨테이너 띄우기
2. 로드밸런서 서버에 nginx 컨테이너 띄우기
3. 로드밸런서와 PaymentService1, 2 연결하기
4. 순서대로 로드밸런싱 되는지 확인하기
5. 프로메테우스가 PaymentService2와 로드밸런서도 인식할 수 있도록 세팅
6. 그라파나 대시 보드 구성하기

1. 새로운 서버에 동일한 PaymentService 컨테이너 띄우기

AMI를 생성해 기존 세팅을 갖고 있는 서버를 생성해주었다. 컨테이너는 이미 생성돼 있는 상태로 이미지가 만들어 지기 때문에, 컨테이너를 실행만 해주면 된다는 이점이 있다. 자세한 과정은 아래 글에서 확인할 수 있다.

 

AWS | 구동중인 EC2 인스턴스와 똑같은 인스턴스를 생성하는 방법

현재 운영중인 EC2 인스턴스와 똑같은 인스턴스를 생성하는 방법에 대한 글이다.AWS 구동중인 EC2 인스턴스와 똑같은 인스턴스 생성 방법동기똑같은 서버를 하나 더 증설하거나, 테스트 하기 위해

ydmins.com

3. 로드밸런서와 PaymentService1, 2 연결하기

 

2번이 아니고 3번을 먼저하는 이유는 서비스를 연결한다는 건, nginx.conf 파일을 작성(설정)하는 것인데 nginx.conf 설정이 제대로 되어있지 않으면 로드밸런서 컨테이너가 뜨고 바로 다운돼 버린다. 그리고 nginx.conf를 수정만 해도 nginx 컨테이너는 재실행 해줘야 한다. 따라서 3번을 먼저 해준다.

💡 팁
서버들을 같은 VPC내에 위치시켰다면 Public IP가 아닌 Private IP로 연결해주면 된다.

2. 로드밸런서 서버에 nginx 컨테이너 띄우기

3번이 잘 작성되었다면 2를 해준다.

4. 순서대로 로드밸런싱 되는지 확인하기

3번까지는 문제없이 빠르게 진행했는데, 도통 Nginx로 요청 자체가 가질 않는 이슈가 있었다. 아래 글에도 작성해 두었지만, EC2 보안 규칙 꼭 확인해 봐야 한다.

 

TIssue | EC2에 로드밸런서 도입했는데 신호가 Nginx에 도달도 안한다

EC2에 띄운 로드밸런서로 요청이 도달하지 않을 때 빨리 한 번 고려해 보면 좋은 방법에 대한 글입니다.상황EC2 도커로 로드밸런서를 도입하였다. 이미 지난 번에 해본적이 있기 때문에 설정에는

ydmins.com

5. 프로메테우스가 로드밸런서와 서비스들을 인식할 수 있도록 세팅

payment server

2개의 Payment 서버의 prometheus.yml을 수정해준다.
global:
  scrape_interval: 15s

scrape_configs:
  - job_name : 'metapay_payment_service'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 15s
    static_configs:
      - targets: ['172.31.5.214:8080']
        labels:
          instance_name: 'metapay-payment1'
  - job_name: 'node_exporter'
    static_configs:
      - targets: ['172.31.5.214:9100']

서버주소와 이름만 다르고 내용은 동일하다.

nginx server

이 부분은 살짝 작업이 필요하다. 

nginx 컨테이너 리소스 메트릭을 수집하기 위해 nginx-prometheus-exporter 설치

Nginx 서버의 리소스 사용량을 추적하기 위해서는 nginx-pormetheus exporter 컨테이너를 띄워줘야 한다. nginx는 프로메테우스가 수집하는 메트릭을 직접 제공하지 않기 때문에 이런 작업이 필요하다.

nginx.conf 수정

exporter가 /stub_status 엔드포인트로 메트릭을 수집할 수 있도록 설정하기 위해 아래 내용을 nginx.conf에 추가해준다.

server {
    location /stub_status {
        stub_status;
    }
}
nginx 서버의 prometheus.yml 작성
global:
  scrape_interval: 15s

scrape_configs:
  - job_name : 'nginx_exporter'
    static_configs:
      - targets: ['172.31.3.30:9113']
        labels:
          instance_name: 'load-balancer'
  - job_name: 'node_exporter'
    static_configs:
      - targets: ['172.31.3.30:9100']
🚨 주의사항
Nginx 메트릭은 9113 포트를 통해서 접근하기 때문에, EC2 인스턴스 인바운드 규칙에 9113이 닫혀 있는지 확인해줘야 한다.

Prometheus Server

Prometheus 서버의 prometheus.yml 작성

프로메테우스가 어떤 곳을 타겟으로 메트릭을 수집할 것인지 알려줘야 한다.  

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
        labels:
          service: 'prometheus'

  - job_name: 'node_exporter'
    static_configs:
      - targets: ['172.31.5.214:9100'] # payment1
        labels:
          instance: 'payment1'
          service: 'node_exporter'
      - targets: ['172.31.15.150:9100'] # payment2
        labels:
          instance: 'payment2'
          service: 'node_exporter'
      - targets: ['172.31.3.30:9100'] # load balancer
        labels:
          instance: 'load-balancer'
          service: 'node_exporter'

  - job_name: 'metapay-payment'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['172.31.5.214:8080'] # payment1
        labels:
          instance: 'payment1'
          service: 'metapay-payment'
      - targets: ['172.31.15.150:8080'] # payment2
        labels:
          instance: 'payment2'
          service: 'metapay-payment'

  - job_name: 'nginx_exporter'
    static_configs:
      - targets: ['172.31.3.30:9113'] # load balancer
        labels:
          instance: 'load-balancer'
          service: 'nginx'
nginx & prometheus 재실행

이렇게 설정을 마무리 한 다음에는 Nginx와 프로메테우스를 재실행 해준다.

연결확인하기
http://<prometheus-host-ip>:9090

 

연결이 성공적으로 되었는지 확인하기 위해서 위의 주소로 접속한다. host-ip는 EC2의 IP를 말한다. 그런 다음 'Staus -> Targets'으로 들어가준다.

프로메테우스 콘솔창 모습이다. Status , Targets을 선택한 모습이다.
Prometheus Console

그럼 아래와 같이 3개의 컨테이너의 메트릭을 프로메테우스가

프로메테우스 콘솔에서 연결된 타겟들의 리스트 모습이다.
Prometheus Console Targets List

확인할 수 있게 된 것을 확인할 수 있다.

6. 그라파나 대시보드 설정하기

CPU 사용량

CPU 사용량 @Grafana 그래프 모습이다.
CPU 사용량 @Grafana

CPU 사용량은 아래 Query를 이용해 구성했다.

100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle", instance=~"payment1|payment2|load-balancer"}[5m])) * 100)

JVM Heap Memory 사용량

JVM Heap Memory @Grafana 그래프모습이다.
JVM Heap Memory @Grafana

JVM Heap Memory 사용량은 아래의 Query를 이용해 구성했다.

label_replace( label_replace( jvm_memory_used_bytes{area="heap", id=~"Eden Space|Survivor Space|Tenured Gen", instance=~"payment1|payment2"}, "memory_area", "$1", "id", "(.*)" ), "service", "$1", "instance", "(.*)")

Connection Pool 남은량

Connection Pool @Grafana 그래프 모습이다.
Connection Pool @Grafana

Connection Pool은 최대값과 남은 연결수를 한 그래프에 담아, 최대값 대비 어느정도 소모됐는지 보이도록 구성했다.

hikaricp_connections_max
hikaricp_connections

평균 반응 시간

평균 반응 시간 @Grafana 그래프 모습이다.
평균 반응 시간 @Grafana

평균 반응시간은 아래와 같은 Query로 구성했다.

rate(http_server_requests_seconds_sum[1m])

전체 대시보드

Dashboard @Grafana 모습이다.
Dashboard @Grafana

여기까지 구성 된 아키텍처

단일 서비스 서버 이중화까지 완성된 아키텍처는 아래와 같다.

아키텍처 모습이다.
아키텍처

정리

  • 단일 서버로 작동할 때와 이중 서버로 구동할 때 어떤 성능 차이가 있는지 테스트를 통해서 살펴볼 것이다.
  • 정말 한 3주정도 걸려서 이제 하나의 서비스다운 아키텍처가 완성됐다. 하지만 모든 서비스를 개별 서버 인스턴스로 구성하는 건, 결정하고 단 하루만에 구성을 완료할 수 있었다. 지난 2주간의 수많은 트러블슈팅을 거치면서 고생한 보람을 오늘에서야 느낄 수 있었다.
728x90
반응형