일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- backend
- 도커
- Spring
- MySQL
- FLAB
- 코딩테스트
- java
- github
- 플러터
- nGrinder
- 부트캠프
- 레디스
- 멘토링
- 데이터구조
- 알고리즘
- 백엔드
- redis
- 로드밸런서
- EC2
- 후기
- error
- F-Lab
- 에프랩
- 트러블슈팅
- 자바
- 성능테스트
- Flutter
- 자바백엔드
- AWS
- grafana
- Today
- Total
민스씨의 일취일장
프로젝트 LOG | 로드밸런스 도입해 서비스 이중화하기 본문
서비스 컨테이너를 하나 더 띄워서 서비스를 이중화 하고, 이를 위해 로드밸런서를 도입하는 과정(Github Issues #18)에 대한 글입니다.
로드밸런서 도입해 서비스 이중화하기
작업 순서 계획
1. 새로운 서버에 동일한 PaymentService 컨테이너 띄우기
2. 로드밸런서 서버에 nginx 컨테이너 띄우기
3. 로드밸런서와 PaymentService1, 2 연결하기
4. 순서대로 로드밸런싱 되는지 확인하기
5. 프로메테우스가 PaymentService2와 로드밸런서도 인식할 수 있도록 세팅
6. 그라파나 대시 보드 구성하기
1. 새로운 서버에 동일한 PaymentService 컨테이너 띄우기
AMI를 생성해 기존 세팅을 갖고 있는 서버를 생성해주었다. 컨테이너는 이미 생성돼 있는 상태로 이미지가 만들어 지기 때문에, 컨테이너를 실행만 해주면 된다는 이점이 있다. 자세한 과정은 아래 글에서 확인할 수 있다.
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 보안 규칙 꼭 확인해 봐야 한다.
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'으로 들어가준다.
그럼 아래와 같이 3개의 컨테이너의 메트릭을 프로메테우스가
확인할 수 있게 된 것을 확인할 수 있다.
6. 그라파나 대시보드 설정하기
CPU 사용량
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 사용량은 아래의 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은 최대값과 남은 연결수를 한 그래프에 담아, 최대값 대비 어느정도 소모됐는지 보이도록 구성했다.
hikaricp_connections_max
hikaricp_connections
평균 반응 시간
평균 반응시간은 아래와 같은 Query로 구성했다.
rate(http_server_requests_seconds_sum[1m])
전체 대시보드
여기까지 구성 된 아키텍처
단일 서비스 서버 이중화까지 완성된 아키텍처는 아래와 같다.
정리
- 단일 서버로 작동할 때와 이중 서버로 구동할 때 어떤 성능 차이가 있는지 테스트를 통해서 살펴볼 것이다.
- 정말 한 3주정도 걸려서 이제 하나의 서비스다운 아키텍처가 완성됐다. 하지만 모든 서비스를 개별 서버 인스턴스로 구성하는 건, 결정하고 단 하루만에 구성을 완료할 수 있었다. 지난 2주간의 수많은 트러블슈팅을 거치면서 고생한 보람을 오늘에서야 느낄 수 있었다.
'Projects > MetaPay' 카테고리의 다른 글
Performance Analysis | Redis 캐시 도입 후 성능 변화 (0) | 2024.09.12 |
---|---|
프로젝트 LOG | REDIS를 이용해 캐시 도입하기 (0) | 2024.09.12 |
TIssue | AWS EC2 running 상태이고 시스템 로그 문제 없는데 접속 안되는 이유 (Feat. FreeTier) (0) | 2024.08.30 |
TIssue | EC2에 로드밸런서 도입했는데 신호가 Nginx에 도달도 안한다 (0) | 2024.08.25 |
TIssue | AWS EC2 작동중인데 연결 안되는 이슈 (Feat. 연결 추적 테이블 nf_conntrack table이 가득참) (0) | 2024.08.25 |