🦁멋쟁이사자처럼 백엔드 부트캠프 13기 🦁
TIL 회고 - [74]일차
🚀74일차에는 Docker의 로드밸런싱을 이용하여 각 컨테이너 별 순차처리에 대해서 학습할 수 있었다.
학습 목표 : docker-compose.yml 설정이나 nginx를 통해 컨테이너 별로 서버를 열어 관리할 수 있도록 해야함
학습 과정 : 회고를 통해 작성
웹서버와 웹어플리케이션서버
➡️웹서버 = 정적 페이지 처리
➡️WAS = 동적 페이지 처리
주요 역할 | 정적 페이지(HTML, CSS, JS) 제공 | 동적 페이지(데이터 처리, 비즈니스 로직 실행) 제공 |
처리 방식 | 클라이언트 요청 → 정적 리소스 반환 | 클라이언트 요청 → 애플리케이션 로직 처리 → 동적 응답 생성 |
예시 | Apache HTTP Server, Nginx | Tomcat, JBoss, WebLogic |
Nginx
- HTTP웹서버, Reverse Proxy, 로드밸런서, 메일 프록시 등의 기능을 수행할 수 있는 가벼운 오픈소스 서버
- 이벤트 기반 아키텍처로 설계되어 동시에 많은 연결을 효율적으로 처리 가능
- 정적파일 서비스 제공 (HTML, CSS, JS, 이미지 등의 정적자원)
- Reverse Proxy : 외부 클라이언트 요청을 내부 서버로 중계, 서버 IP나 포트를 감추고 보안을 강화함
- TLS / SSL 처리 : HTTPS 종단, 인증서 관리 등
로드밸런싱 (Load-Balancing)
- 여러 서버 (ex. Spring Boot 애플리케이션)로 트래픽을 분산하여 부하를 균등하게 나누고 장애 시 다른 서버로 우회
- 여러 서버에 트래픽을 분산시켜 부하를 줄이고 성능을 향상시키는 기술
- ex. 로드밸런서 없는 단일 서버
사용자가 www.example.com 접속 ➡️ 서버 1이 모든 요청 처리 (과부하 가능성)
ex. 로드 밸런서 적용
사용자가 www.example.com 접속 ➡️ 로드 밸런서가 여러 서버 중 하나를 선택
(=서버1, 서버2, 서버3 중 분산 처리)
로드밸런싱의 알고리즘 (=방식)
1. 라운드 로빈 (Round Robin)
- 요청을 순차적으로 서버에 배분
- (A → B → C → A → B → C ... )
2. 가중 라운드 로빈 (Weighted Round Robin)
- 서버 성능에 따라 가중치(weight)를 부여해 트래픽 배분
- 성능이 높은 서버는 더 많은 요청을 받음
ex.
서버 A (가중치 3) → 3번 요청 처리
서버 B (가중치 2) → 2번 요청 처리
서버 C (가중치 1) → 1번 요청 처리
▶️실습 - Nginx 컨테이너로 로드밸런싱
- Nginx 컨테이너 2개 (각각 Reverse Proxy와 로드 밸런서 설정)
- 외부에서 들어오는 요청을 뒤에 있는 Spring Boot API 컨테이너 3대로 분산
- Spring Boot API 컨테이너 3대
- 각각 다른 포트로 동작하거나 Docker 네트워크에서 독립된 IP로 띄워 로드밸런싱 테스트가능
- Docker 환경에서 모두 운영 - 목적 : Nginx가 Spring Boot API 서버에 라운드로빈 (Round Robin) 으로 요청 전달하는 것을 실습
- 컨테이너 간 네트워크 (ex. bridge 모드 + 사용자 정의 네트워크) 를 활용하여 통신
- ./gradlew build -x test 로 빌드를 진행
- java -jar ./build/libs/ 안에 있는 jar를 실행해봐서 서버가 잘 동작하는지 테스트
- 이미지 만들기 docker build -t todoapp:3.0 .
- todoapp 3개가 잘 돌아가고 있는지 확인 ➡️9513, 9514, 9515 열려있는 중
- todoapp자체는 9512에서 실행중
- 각각 9513, 9514, 9515 로 접근해서 열 수 있었고 모두 접속이 가능한 상태
- api1을 넣었을떄 우측 가장 위 cmd 에서 insert가 수행되었음을 실시간 로그로 확인할 수 있다. (9513포트)
- 실시간 로그 확인 : docker logs -f [컨테이너ID]
- 다른 9514, 9515 포트에서도 실시간 로그 추적을 확인 가능
설정 추가
Dockerfile
FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream spring-backend {
# 라운드 로빈 대상
server api1:8080;
server api2:8080;
server api3:8080;
}
server {
listen 80;
location / {
proxy_pass <http://spring-backend>;
}
}
}
- 이 설정파일들을 만든 디렉토리에서 cmd를 열고
- docker build -t mynginx:1.0 . : 이미지 만들기
▶️실습 - Nginx컨테이너 2대 실행
docker run -d ^
--name nginx1 ^
--network spring-net ^
-p 9601:80 ^
mynginx:1.0
docker run -d ^
--name nginx2 ^
--network spring-net ^
-p 9602:80 ^
mynginx:1.0
- docker rm nginx1 nginx2 : 기존것들은 지우고 새롭게 만든다.
- 9601, 9602 포트로 만들어준다
- 데이터를 넣어보니 9514 포트에서 로그 추적
- fff 값을 넣어보니 9513 포트에서 로그 추적
- ggg값에는 9515 포트가 로그 추적
이처럼 순서대로 로드밸런싱이 라운드로빈 알고리즘 방식으로 순차적으로 동작하고 있음을 알 수 있다.
마찬가지로 9601이 아닌 9602포트인 nginx2 를 쓰더라도 둘 중 어느것을 접속해도 동일한 스프링부트 3대에 분산이 된다.
정리하자면
현재 서버가 5대가 구동 중인 상태
- Nginx 서버: 2대 (9601, 9602 포트로 접근 가능)
- Spring Boot API 서버: 3대 (9513, 9514, 9515 포트로 접근 가능)
Round Robin을 사용하면
- 업스트림 설정 별도 weight(가중치)나 ip_hash를 넣으면 특정한 서버 (포트)가 더 많은 요청이 들어가도록 할 수 있다.
- (ex. server api1:8080 weight = 2; /// server api2:8080 weight = 1;)
➡️3개의 요청 시 api1, api1, api2 처럼 api1에 더 할당되는 설정인 것
헬스 체크(Health Check)
- 로드 밸런서(ex. Nginx)가 백엔드 서버(API 서버)의 상태를 주기적으로 확인하여
정상적으로 작동하는 서버에만 트래픽을 전달하도록 하는 기능 - 헬스 체크를 통해 응답하지 않거나 오류가 발생하는 서버를 자동으로 감지하고
트래픽 분배 대상에서 제외하여 서비스의 안정성을 높일 수 있습니다. - 헬스 체크는 서버의 건강 상태를 실시간으로 감지하여 트래픽 분배를 제어하고,
로그는 서버의 상세한 동작 기록을 제공하여 문제 진단 및 분석에 활용
▶️실습 - 설정 파일로 5개의 컨테이너 동시 선언 및 생성
- docker compose up -d 활용
- http://localhost:[포트번호], http://localhost:[포트번호]로 로드밸런싱 확인해보기
services:
# 1) MySQL 컨테이너
mymysql:
image: mymysql:1.0
container_name: mymysql-1.0
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=testdb
- MYSQL_USER=testuser
- MYSQL_PASSWORD=testpass
ports:
- "3308:3306"
networks:
- todo-net
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-ptestpass"]
interval: 10s
timeout: 5s
retries: 3
# 2) Todo 애플리케이션 컨테이너
todoapp1:
image: todoapp:5.0
container_name: todoapp1
depends_on:
mymysql:
condition: service_healthy # DB가 먼저 시작된 후 todoapp을 띄움 (단, 실제 DB 초기화가 끝났는지는 보장X)
ports:
- "9091:8080"
networks:
- todo-net
# healthcheck 제거
#... todoapp2, todoapp3
# 3) Nginx 컨테이너
nginx:
image: todo-nginx:1.0
container_name: mynginx
depends_on:
- todoapp1
- todoapp2
- todoapp3 # todoapp이 시작된 뒤에 nginx 기동
ports:
- "9666:80"
networks:
- todo-net
networks:
todo-net:
driver: bridge
- depends_on에 todoapp1, todoapp2, todoapp3 를 넣어 todoapp을 먼저 시작하도록 설정
- mymysql은 기존에 사용중이던 mymysql DB와 충돌될 수 있으므로
image로 1.0 태그로 새로 생성 후 컨테이너 이름도 mymysql-1.0으로 참조
🚀회고 결과 :
컨테이너 5개를 docker-compose.yml 파일로 한 번에 선언했을때 포트 충돌 및 이미 존재하는 DB 오류가 계속 발생해서 회고에서 시간이 오래걸렸다.
정확한 오류에 대해서 더 알아볼 필요가 있을 것 같다.
라운드 로빈 방식 또한 자격증 공부때에만 잠깐 접했었는데 도커와 함께 로드밸런싱의 알고리즘으로 배워보니 이해가 쉬웠다.
향후 계획 :
- 포트충돌 해결법 공부
- nginx 활용법
'Recording > 멋쟁이사자처럼 BE 13기' 카테고리의 다른 글
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_76일차_"쿠버네티스 Kubernetes" (0) | 2025.03.28 |
---|---|
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_75일차_"프로메테우스 + 그라파나" (0) | 2025.03.27 |
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_73일차_"Docker 이미지" (0) | 2025.03.25 |
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_72일차_"Docker 네트워크" (0) | 2025.03.24 |
[멋쟁이사자처럼 부트캠프 TIL 회고] BE 13기_71일차_"Docker + Linux (3)" (0) | 2025.03.21 |