Nginx 로드밸런싱 설정
이 글은 Nginx 로드밸런싱 방법을 적은 글입니다.
이 글에서 다루고자 하는 내용은 크게 두 가지로
첫 번째는 로드밸런서의 정체와 사용하는 이유이고,
두 번째는 Nginx를 로드밸런서로 운용하는 방법입니다.
로드밸런서의 정체
로드밸런서는 번역하면 부하 분산기입니다. 말 그대로 부하 분산을 위한 프로그램 혹은 하드웨어입니다.
로드밸런서의 역할은 가상의 주소를 향한 요청을 여러 서버에 분배하는 것입니다.
로드밸런서를 사용하는 이유
로드밸런서가 사용되는 이유를 크게 분류하면 두 가지가 있습니다.
첫 번째는 부하를 분산하여 하나의 서버의 부하를 조절할 수 있다는 점,
두 번째는 고가용성으로 두 개 이상의 서버를 운영하여 한쪽 서버가 장애가 생길 시 다른 쪽에서 해당 서비스를 운영할 수 있는 구성을 통해 운영 안정성을 확보할 수 있다는 점
Nginx 로드밸런싱 설정하기
우리는 두 가지 실습을 진행할 것입니다.
첫 번째는 간단한 Nginx 로드밸런서 세팅하는 것이고
두 번째는 Nginx 로드밸런서 서버 그룹에 애플리케이션 서버에 세팅하는 것,
세 번째는 Nginx 로드밸런서의 분배 방식을 비교하는 것입니다.
https://nginx.org/en/docs/http/load_balancing.html
Using nginx as HTTP load balancer
Using nginx as HTTP load balancer Introduction Load balancing across multiple application instances is a commonly used technique for optimizing resource utilization, maximizing throughput, reducing latency, and ensuring fault-tolerant configurations. It is
nginx.org
※첫 번째 내용은 위의 링크를 참조한 내용입니다.
실습을 진행하기에 앞서
nginx는 바이너리 패키지를 통해서 설치되었을 것이라고 가정합니다.
그리고 이 경우 /etc/nginx/ 디렉토리에 설정 파일들이 생성되어 있습니다.
또한 설정 파일은 보통 설정 파일디렉터리 안에 conf.d/*. conf와 같은 형식으로 파일을 관리합니다.
ex) /etc/nginx/conf.d/proxy.conf
간단한 Nginx 로드밸런서 세팅하기
http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80; //for request to 80 port
location / {
proxy_pass http://myapp1; //pass request to myapp1 server group
}
}
}
위의 코드 블록은 Nginx를 http 로드밸런서로 사용할 때 쓰는 간단한 예시입니다.
upstream myapp1 블록은 myapp1이라는 서버 그룹을 의미합니다.
해당 서버 블록을 보면, srv1.example.com, srv2.example.com, srv3.example.com 가 해당 서버 그룹에 속하는 것을 알 수 있습니다.
server 블록을 분석하면 80 포트로 들어온 요청을 myapp1 서버 그룹으로 포워딩해준 것을 알 수 있습니다.
포워딩된 요청은 어떻게 요청을 분배할지 규칙이 정해져 있지 않기 때문에 round-robin(요청된 시간에 따라 분배) 방식으로 분배됩니다.
Nginx 로드밸런서 서버 그룹에 애플리케이션 서버 설정하기
위의 로드밸런서 세팅을 실제 애플리케이션에 연결할 때의 세팅은 다음과 같습니다.
server {
listen 80;
server_name <your-server-ip>;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://<server-groupname>;
}
}
upstream <server-groupname> {
server localhost:3000;
server localhost:3002;
server localhost:3003;
}
위의 설정은 프락시 서버의 설정과 공통된 부분이 많습니다.
변경된 부분에 대해서 말씀드리면 proxy_pass의 파라미터가 서버 그룹으로 변경되고
서버 그룹이 추가되었는데, 이때 요청은 3000, 3001, 3002번 포트로 분배되도록 설정된 것입니다.
위의 사진을 보면 각각 다른 포트에 바인딩되어있는 서버에 요청이 분배된 것을 확인할 수 있습니다.
Nginx 로드밸런싱 분배 방식 비교
Nginx 로드밸런서는 분배 방식을 설정할 수 있습니다.
분배방식을 설정하지 않으면 방금 전의 설정과 같이 기본 값인 round-robin 방식으로 분배를 합니다.
기본 값을 제외한 방식으로는 least_conn, ip_hash가 있고, 추가적으로 서버 그룹 내의 특정 서버에 weight를 부여하는 경우도 있습니다.
least_conn
least_conn은 클라이언트의 연결이 가장 적은 서버에게 요청을 분배하는 방식으로, 요청을 공평하게 분배하기 위해서 사용되는 방식입니다.
upstream <server-groupname> {
least_conn;
server localhost:3000;
server localhost:3002;
server localhost:3003;
}
위와 같이 설정을 하면 least_conn 설정이 됩니다.
하지만 개인 PC에서 테스트하면 round-robin과 다른 점을 파악하기가 어렵습니다. 왜냐하면 ip 바인딩이 되어있지 않기 때문에, 매 요청마다 다른 서버로 분배되기 때문입니다. 그리고 이러한 상태에서의 문제는 세션을 통해 사용자 정보를 들고 있던 상황에 다른 서버로 요청이 간다면 사용자 인증해야 하거나 문제가 생길 수 있습니다.
ip_hash
그래서 전에 한번 요청을 받은 서버가 있을 때 해당 서버에만 요청을 분배해주는 옵션이 있습니다.
바로 ip_hash입니다.
upstream <server-groupname> {
ip_hash;
server localhost:3000;
server localhost:3002;
server localhost:3003;
}
위 코드처럼 서버 그룹에 ip_hash 옵션을 설정하면
위 사진과 같이 한번 요청을 받은 서버로만 연결이 됩니다.
마무리
Nginx를 사용하는 데에 필요한 정보들을 시리즈로 적고 있습니다.
궁금하거나, 하고 싶은 말이 있으시면 댓글을 통해서 말해주시길 바랍니다.
감사합니다