일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 인텔리제이
- 스프링 부트
- 구현
- bfs
- dfs
- 개발자
- HTTP
- 스프링부트
- 도커
- Java
- 스타트업
- spring boot
- HashMap
- 주니어
- 구름LEVEL
- 이직
- 해결
- 백엔드
- docker
- 자료구조
- 스프링
- 문자열
- 명령어
- 배열
- Linux
- spring
- 해시맵
- 코딩테스트
- 프로그래머스
- IntelliJ
- Today
- Total
마이의 개발 블로그
[Network] Docker Compose와 Nginx를 이용한 수평 스케일(scale-out)과 로드 밸런싱(Load Balancing) 본문
[Network] Docker Compose와 Nginx를 이용한 수평 스케일(scale-out)과 로드 밸런싱(Load Balancing)
개발자마이 2024. 12. 10. 10:46배경
납품한 솔루션 WAS의 응답이 피크 시간대에 느려지는 현상이 관찰되었습니다. 초당 약 600개 이상의 페이지 요청이 지속적으로 발생함을 모니터링할 수 있었는데 이는 기존 고객사들 대비 많은 처리량을 요구하다보니 별도의 조치가 필요했습니다. 이에 따라 제한된 자원 내에서 수평 스케일(scale-out)에 대한 부하 테스트를 수행하여 적당한 타협점을 도출해낼 수 있었는데, 그 과정과 결과를 공유하고자 합니다. 로드밸런싱은 도커와 Nginx를 이용하여 수행했습니다.
테스트 수행 방식
- JMeter 이용
- OS에서 도커 자원 제한: 8코어 16GB 메모리 (다수 컨테이너가 공유함)
- 가장 많은 부하가 걸리는 WAS의 API에 대해 초당 요청 수를 증가시켜가며 평균, 최대 응답시간 측정
테스트 결과
*결과표의 'CPU(코어)' 수는 솔루션의 여러 컨테이너가 함께 사용하는 총 코어 수를 의미합니다.
*부하테스트의 대상이 되는 단일 WAS의 최대 사용 코어 수는 workers * WAS 도커 인스턴스 수입니다.
*workers: uvicorn의 workers 인자를 의미합니다. 서버의 동시 요청 처리를 위한 프로세서 개수를 지정하는 옵션입니다.
- workers는 도커 인스턴스당 1개로 유지할 때 가장 높은 효율을 보였습니다. 코어 수보다 workers를 높일 경우 유의미한 성능 향상을 관찰할 수 없었습니다. 이는 테스트 대상 API의 비즈니스 로직이 CPU집약적인 동작을 포함하여 단일 코어를 하나의 worker로 사용하는 것이 효율적이기 때문인 것으로 추측됩니다.
- 동일한 환경에서 로드밸런싱을 수행했을 때가 아닐 때보다 더 빠른 평균응답시간을 보여주었습니다.
- 로드밸런싱을 수행할 때 특정 수준까지 인스턴스 개수가 늘어날 수록 최대지연시간이 줄어들었습니다.
- 인스턴스 개수가 늘어나더라도 평균 지연시간이 더이상 줄어들지 않는 지점이 관찰되었으나 제한된 자원으로 인해 해당 결과는 적용할 수 없었습니다.
-> 인스턴스 4개, 인스턴스당 1코어 할당
Docker Compose와 Nginx를 이용한 로드밸런싱 예제
1. Docker Compose 설정
version: '3'
services:
test-server1:
image: <이미지>
container_name: <컨테이너1>
restart: always
command: uvicorn src.server.main:app --host=0.0.0.0 --port=8000 --timeout-keep-alive=60
working_dir: /app
test-server2:
image: <이미지>
container_name: <컨테이너2>
restart: always
command: uvicorn src.server.main:app --host=0.0.0.0 --port=8000 --timeout-keep-alive=60
working_dir: /app
test-server3:
image: <이미지>
container_name: <컨테이너3>
restart: always
command: uvicorn src.server.main:app --host=0.0.0.0 --port=8000 --timeout-keep-alive=60
working_dir: /app
test-server4:
image: <이미지>
container_name: <컨테이너4>
restart: always
command: uvicorn src.server.main:app --host=0.0.0.0 --port=8000 --timeout-keep-alive=60
working_dir: /app
2. Nginx 설정
upstream test-server {
server test-server1:8000;
server test-server2:8000;
server test-server3:8000;
server test-server4:8000;
}
server {
listen 80;
location / {
proxy_pass http://test-server/;
}
}
3. 설명
- Nginx와 WAS 둘 다 도커 컨테이너로 동일한 네트워크에서 동작하게끔 구성되어있습니다. 그렇기 때문에 Nginx에서 WAS 컨테이너를 이름(test-server1~4)으로 직접 호출 가능합니다.
- Docker Compose에서 동일한 WAS 이미지를 사용하여 4개의 컨테이너를 각각 생성합니다. 이 때, 외부노출 포트, 서비스명, 컨테이너명 등이 겹치지 않아야 합니다.
- Nginx에서는 upstream 블록을 사용하여 test-server1~4를 test-server라는 하나의 이름으로 묶어줍니다. 그리고 원하는 위치에 test-server를 호출하게끔 설정합니다.
- Nginx에서는 기본 설정으로 라운드 로빈(Round Robin) 방식의 로드밸런싱을 수행합니다.
Note
오토스케일링이 필요한 경우, 모니터링 및 인스턴스 증감을 조절하는 스크립트를 이용하거나 쿠버네티스(Kubernetes), 도커 스웜(Docker Swarm) 등의 오케스트레이션 툴을 사용할 수 있습니다.
'개발지식 > 인프라' 카테고리의 다른 글
[Linux] cgroups를 사용해 도커 사용 자원 제한하기 (0) | 2024.12.10 |
---|---|
[Docker] 도커(Docker) 삭제 후 도커 네트워크 인터페이스를 삭제해야하는 경우 명령어(RHEL 8.8) (0) | 2024.11.22 |
[Linux] 도커(Docker) 동작 중 firewalld를 켜면 서비스가 동작하지 않는 현상(RHEL 8.8) (0) | 2024.11.22 |
[Linux] tcpdump로 로컬 서버에서 외부로 나가는 모든 요청(request) 확인하기 (0) | 2024.09.24 |
[Docker] 자주 사용하는 도커 명령어 모음 (0) | 2024.06.13 |