Nginx 시리즈

Nginx 로드밸런싱 설정

mayleaf 2020. 4. 14. 00:30

이 글은 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번 포트로 분배되도록 설정된 것입니다.

 

 

위의 설정 파일을 실제로 적용한 예시, 위에서부터 3000, 3002, 3003번 포트에 대해서 바인딩 되어있는 서버

위의 사진을 보면 각각 다른 포트에 바인딩되어있는 서버에 요청이 분배된 것을 확인할 수 있습니다.

 

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를 사용하는 데에 필요한 정보들을 시리즈로 적고 있습니다.

궁금하거나, 하고 싶은 말이 있으시면 댓글을 통해서 말해주시길 바랍니다.

 

감사합니다

'Nginx 시리즈' 카테고리의 다른 글

Nginx 프록시 서버  (0) 2020.04.04
Nginx 란?  (1) 2020.04.02
Nginx 설치  (0) 2020.04.01