HAProxy 와 Nginx 의 로드밸런싱

Nginx Logo

NGINX

Nginx 는 대표적인 웹서버인 Apache 의 문제점을 해결하면서 만들어진 웹서버로 비동기 방식으로 개발되어 가볍고 빠른 것으로 유명한 오픈소스 어플리케이션이다. Nginx 는 http 나 reverse proxy 같은 기능 외에도 load balancer 기능 또한 강력하다.

# Load Balancing
upstream target-server {  
  least_conn;
  server [서버주소1] weight=5 max_fails=3 fail_timeout=10s;
  server [서버주소2] weight=10 max_fails=3 fail_timeout=10s;
}

server {  
  listen 80;
  listen [::]:80;

  server_name front.local;

  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;

  location / {
    proxy_next_upstream error http_503;
    proxy_pass http://target-server;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-NginX-Proxy true;
    proxy_set_header Host $host;
    proxy_redirect off;
  }
}

Nginx 로드 밸런싱은 upstream 이라는 옵션으로 설정할 수 있는데, least_conn 은 연결이 가장 적은 서버로 트래픽을 전달하는 역할을 한다. 설정할 수 있는 옵션은 다음과 같다.

옵션 설명
p_hash 같은 방문자로부터 도착한 요청은 항상 같은 업스트림 서버가 처리 할 수 있게 한다.
weight=n 업스트림 서버의 비중을 나타낸다. 이 값을 2로 설정하면 그렇지 않은 서버에 비해 두배 더 자주 선택된다.
max_fails=n n으로 지정한 횟수만큼 실패가 일어나면 서버가 죽은 것으로 간주한다.
fail_timeout=n max_fails가 지정된 상태에서 이 값이 설정만큼 서버가 응답하지 않으면 죽은 것으로 간주한다.
down 해당 서버를 사용하지 않게 지정한다. `ip_hash;` 지시어가 설정된 상태에서만 유효하다.
backup 모든 서버가 동작하지 않을 때 backup으로 표시된 서버가 사용되고 그 전까지는 사용되지 않는다.

출처: 생활코딩

다만, Nginx 의 유료 버젼인 Nginx Plus 를 사용하지 않는 이상 헬스체크가 불가능하기 때문에 실제 서버의 상태를 체크하는 API 를 만들어서 상황에 따라 스위칭하는 고가용성을 위한 동작에는 용이하지 않다.

HAProxy Logo

HAProxy

Haproxy 는 L4, L7 과 같은 하드웨어 로드밸런서를 대체하기 위한 오픈소스 소프트에어로 이름처럼 Reverse Proxy 를 기반으로 로드밸런싱을 하기에 매우 강력하고 또 가벼운 어플리케이션이다. HA (High Availability) 라는 이름처럼 고가용성을 위하여 설계되었다. Nginx 로드밸런싱과 다른 점은 헬스체크라고 볼 수 있는데, 특정 API 에 접근하여 서버 상태를 점검하고, 문제가 있으면 다른 node 로 트래픽을 넘겨줄 수 있는 기능을 한다.

global  
  log /dev/log     local0
  log /dev/log     local1 notice
  chroot /var/lib/haproxy
  user haproxy
  group haproxy
  daemon

defaults  
  log      global
  mode     http
  option           httplog
  option           dontlognull
  timeout connect 5000
  timeout client 5000
  timeout server 5000
  errorfile 400 /etc/haproxy/errors/400.http
  errorfile 403 /etc/haproxy/errors/403.http
  errorfile 408 /etc/haproxy/errors/408.http
  errorfile 500 /etc/haproxy/errors/500.http
  errorfile 502 /etc/haproxy/errors/502.http
  errorfile 503 /etc/haproxy/errors/503.http
  errorfile 504 /etc/haproxy/errors/504.http

listen stats  
  bind *:70
  stats enable
  stats uri /?stats=this-is-stats

frontend load-balancer  
  bind *:80
  mode http
  acl my-url hdr(host) -i front.local
  http-request deny if !my-url
  default_backend server

backend server  
  mode http
  option forwardfor
  # 헬스체크
  option httpchk GET /
  http-check expect status 200
  default-server inter 1s fall 3 rise 2
  # 로드 밸런싱
  balance roundrobin
  server server-blue [서버주소1] check
  server server-green [서버주소2] check

로드밸런싱은 Nginx 와 동일하게 round-robin 으로 설정했고, health check 는 특정 url 에 http status 코드를 설정하여 간단하게 적용할 수 있다. acl 옵션을 통해 access control 도 간단하게 처리할 수 있고, nginx 의 deny 기능 또한 유사한 형태로 간단하게 처리할 수 있다. 또한 haproxy 는 stats 이라고 하는 페이지를 기본적으로 제공하는데, 어떤 서버에 접속되고 작동하고 있는지 확인하기 편리하다. 단, uri 가 공개되면 곤란하니 방화벽으로 제한하거나, .htpasswd 같은 방식을 사용할 것.

마지막으로 헬스체크에 대해 조금 더 자세하게 설명하면, default-server inter 1s fall 3 rise 2 라고 하는 것은 다음과 같이 해석할 수 있다. 1초 마다 서버에 접속하여 헬스체크를 행하되 3번 실패하면 접속 불가로 판단하고 2번 성공하면 정상 상태로 간주하여 트래픽을 연결해준다. option httpchk GET / 은 http GET 으로 [서버주소]/ 요청을 날려서 http-check expect status 200 에 따라 200 OK 에 해당하는 응답이 나올시 정상 상태라고 판단하게 된다.

결론

간단하게 Nginx 와 HAProxy 의 로드밸런싱에 대해서 알아보았다. Nginx 자체의 로드밸런싱도 훌륭하지만, 굳이 웹 서버로서의 역할이 필요가 없다면 (캐싱이라거나 캐싱, 혹은 캐싱이라거나...) HAProxy 로드 밸런싱이 헬스체크가 가능하기도 하고 좀 더 가벼우니 필요에 따라 선택하면 좋을 것이다. 단, SSL 을 사용해야 하는 경우 HAProxy 는 1.5 버젼 부터 지원하니 꼭 잊지 말자. 삽질 엄청 함

Seokjun Kim

Read more posts by this author.

Subscribe to Make It Yourself

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!
comments powered by Disqus