nginx 로드 밸런싱 설정 (load balancing)
nginx 로 cluster 를 구성 및 load balancer 설정하는 방법 정리
upstream 설정
cluster 에 참여하는 서버 정보와 포트를 upstream 지시자로 설정하며 첫 번째 설정한 서버가 우선적으로 응답을 처리함.
http { server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; ## upstream phpserver { ## LB method # least_conn, ip_hash; ## fastcgi 를 사용하는 경우 #server unix:/var/run/php/php7.0-fpm.sock; #server fpm-server-ip:9000; ## proxy 를 사용하는 경우 server was1-ip:1234; server was2-ip:1234; }
nginx 를 여러 개 사용하여 클러스터를 구성할 경우 upstream 에 was 의 ip 를 기술하지 말고 /etc/hosts 에 alias 를 주고 사용하는 것이 아래 예제처럼 nginx.conf 를 동일하게 사용할 수 있으므로 권장.
nginx1
nginx2는 100 이 main was 이며 100 이 장애일 경우 101 로 전환
192.168.10.100 was1 192.168.10.101 was2
nginx2
nginx2는 101 이 main was
192.168.10.101 was1 192.168.10.100 was2
공통 nginx.conf
http { upstream app1-was { server was1:9000; server was2:9000 backup; } upstream app2-was { server was1:8080; server was2:8080 backup; } }
이제 위 nginx.conf 를 git 에 넣어서 배포하면 동일한 설정으로 각각 was 를 배분해서 사용할 수 있음
Load Balancing method
Round robin(RR)
기본 설정이며 upstream 서버를 RR 방식으로 순회하며 서비스.
RR + Server Weights
클러스터내에 특정 서버가 최근에 도입해서 장비 사양이 좋은 경우 이 서버에서 처리량을 늘릴 필요가 있음.
이렇게 일부에 가중치를 줄 경우 다음과 같이 weight 항목에 가중치를 설정하며 설정하지 않을 경우 기본 값은 1임.
upstream phpserver { server was1-ip:1234 weight=5; server was2-ip:1234 ; server 192.0.0.1 backup; }
was1 서버에 5번 요청한 후에 was2 서버에 요청.
backup 으로 지정된 서버는 메인 서버가 다 fault 일 경우에만 서비스.
Server Slow Start
최근에 장애로부터 복구한 서버에 요청이 폭주하지 않도록 slow_start 에 주어진 시간만큼 기다려 줌.
upstream backend { server was1-ip:8080 slow_start=30s; server was2-ip:1234; server 192.0.0.1 backup; }
slow_start 기능은 nginx Plus 를 구매해야 사용할 수 있음
least connection
가장 클라이언트 연결 갯수가 적은 서버로 전달하는 설정.
upstream backend { least_conn ; server was1-ip:8080 slow_start=30s; server was2-ip:1234; server 192.0.0.1 backup; }
ip hash
클라이언트 IP 를 hash 해서 특정 클라이언트는 특정 서버로 연결하는 설정. session clustering 이 구성되지 않은 경우 유용하나 부하가 골고루 분산되지 않고 특정 서버에 몰릴 수 있는 위험이 있습니다.
upstream backend { ip_hash; server was1-ip:8080 slow_start=30s; server was2-ip:1234; server 192.0.0.1 backup; }
server block 설정
proxy_pass 사용시
- proxy 를 사용할 경우 다음과 같이 proxy_pass 에 설정한 upstream 을 http:// 로 설정
proxy_next_upstream 에 에러 처리할 항목과 http 코드를 지정하며 gateway 에러 코드인 502, 503, 504 추가
500 에러는 운영자 판단에 의해 추가
server { listen 80; server_name laravel53.app; index index.html index.htm index.php; charset utf-8; location ~ \.php$ { proxy_pass http://phpserver; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; }
fastcgi_pass 사용시
- fastcgi_pass 에 upstream 이름 설정(http:// 제외)
- fastcgi_next_upstream 을 사용하고 fastcgi 는 502, 504 를 지원하지 않으므로 http_502, http_504 키워드를 제외.
upstream backend { server unix:/var/run/php/php7.0-fpm.sock; server localhost:9001; } server { listen 80; server_name laravel53.app; index index.html index.htm index.php; charset utf-8; location ~ \.php$ { fastcgi_pass phpserver; fastcgi_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; }
테스트
proxy_pass 방식과 Round Robin 으로 설정했을때 테스트가 편리하며 두 개의 web app 를 준비
composer create-project --prefer-dist laravel/laravel cluster1 composer create-project --prefer-dist laravel/laravel cluster2
각각 두개의 라라벨 standalone 서버를 구동
cluster1 $ php artisan server --port 1234 cluster2 $ php artisan server --port 1235
- 브라우저로 연결하여 정상 동작 확인
cluster1 웹 app 에 연결하여 다음 명령어 수행하여 503 응답 발생
$ php artisan down
- 브라우저로 연결하여 정상 동작 확인
nginx log 를 확인하여 다음과 같이 upstream 에 연결 못한 로그가 남았는지 확인
2016/10/12 07:39:32 [error] 2112#2112: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.10.1, server: laravel53.app, request:
"GET /hello HTTP/1.1", upstream: "http://127.0.0.1:1234", host: "laravel53.app"