HTTP 로드밸런싱: upstream으로 트래픽 분산하기
HTTP 로드밸런싱: upstream으로 트래픽 분산하기
여러 애플리케이션 인스턴스에 요청을 고르게 나눠주는 기법을 로드밸런싱(load balancing)이라고 해요. 리소스 활용을 최적화하고, 처리량을 높이고, 지연을 줄이며, 장애에도 견디는 구성을 만들 수 있죠. NGINX를 HTTP 로드밸런서로 쓰면 upstream 블록 하나로 라운드로빈부터 세션 유지, 헬스체크까지 손쉽게 구성할 수 있어요.
로드밸런싱 방식
NGINX가 지원하는 기본 로드밸런싱 방식은 다음 세 가지예요.
- round-robin — 애플리케이션 서버에 요청을 순서대로 고르게 분배해요.
- least-connected — 다음 요청을 활성 연결 수가 가장 적은 서버에 배정해요.
- ip-hash — 클라이언트 IP 주소를 기반으로 해시 함수를 써서 다음 요청을 처리할 서버를 결정해요.
기본 로드밸런싱 설정
아래 예시는 srv1 ~ srv3 에 같은 애플리케이션의 인스턴스 3개가 떠 있는 상황이에요.
http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
}
로드밸런싱 방식을 명시하지 않으면 기본값은 round-robin 이에요. 모든 요청은 서버 그룹 myapp1 로 프록시되고, NGINX가 HTTP 로드밸런싱으로 요청을 분배해요.
NGINX의 리버스 프록시 구현은 HTTP뿐 아니라 HTTPS, FastCGI, uwsgi, SCGI, memcached, gRPC까지 로드밸런싱을 지원해요. HTTPS로 구성하려면 프로토콜만 https 로 바꾸면 되고, FastCGI·uwsgi·SCGI·memcached·gRPC를 쓸 때는 각각 fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, grpc_pass 지시어를 사용해요.
최소 연결(least connected) 로드밸런싱
서버마다 처리 중인 요청 수가 제각각일 때, 연결이 가장 적은 서버에 다음 요청을 보내면 부하가 더 균등하게 분산돼요. 서버 그룹 구성에 least_conn 지시어를 넣으면 활성화돼요.
upstream myapp1 {
least_conn;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
최소 시간(least time) 로드밸런싱
응답 시간까지 고려해 가장 빠른 서버를 골라주는 방식도 있어요. least_time 지시어를 사용해요.
upstream myapp1 {
least_time header;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
세션 유지 (ip-hash)
round-robin 이나 least-connected 방식에서는 같은 클라이언트의 요청이 매번 다른 서버로 분산될 수 있어요. 같은 클라이언트가 항상 같은 서버로 향하도록 "고정(sticky)"하는 게 필요하면 ip_hash 지시어를 써요. 클라이언트 IP 주소를 해싱 키로 사용해 서버를 결정하므로, 같은 클라이언트의 요청은 그 서버가 다운되지 않는 한 항상 같은 서버로 향해요.
upstream myapp1 {
ip_hash;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
가중치(weight)를 둔 로드밸런싱
round-robin 은 요청이 충분하고 처리가 균일하게 빠를 때 서버 간에 거의 동등하게 분배돼요. 여기에 가중치를 주고 싶다면 server 지시어에 weight 파라미터를 붙이면 이 값이 분배 결정에 반영돼요.
upstream myapp1 {
server srv1.example.com weight=3;
server srv2.example.com;
server srv3.example.com;
}
이 설정에서는 새 요청 5개마다 srv1로 3개, srv2로 1개, srv3로 1개가 분배돼요.
헬스체크 (health check)
NGINX의 리버스 프록시는 인밴드(수동) 헬스체크를 지원해요. 특정 서버의 응답이 에러로 실패하면 NGINX는 그 서버를 실패로 표시하고, 일정 시간 동안 이후 요청에서 그 서버를 선택하지 않으려고 해요.
max_fails 지시어는 fail_timeout 동안 서버와 통신에 연속 실패한 횟수를 설정해요. 기본값은 1이고, 0으로 두면 이 서버에 대한 헬스체크가 비활성화돼요. fail_timeout 은 서버가 실패로 표시되는 시간을 정하며, 이 시간이 지나면 NGINX는 실제 클라이언트 요청으로 서버를 조심스럽게 다시 시험해요. 시험이 성공하면 서버는 정상(live)으로 표시됩니다.
이 밖에도 로드밸런싱을 제어하는 지시어가 더 있는데, proxy_next_upstream, backup, down, keepalive 등을 함께 알아두면 좋아요.