안녕하세요, 수요일에 뜬금포 한번 날립니다.
오늘 upstream 기능 관련하여 테스트를 해야 할 일이 있어서 테스트를 진행하다가 알게 된 내용입니다.
upstream의 기본적인 LoadBalancing 알고리즘이 round robin 이라는 것!!!
일말의 여지도 없이 round robin 이라는 것!!!
어찌 생각하면 당연한 일이지만,
upstream과 proxy_pass를 설정한 후 원하는 결과가 나오지 않으니 조금 당황스럽더군요...
아래와 같은 테스트 환경에서,
저는 1번 pc에서 요청하면 www.a.com 페이지가 표시되고,
2번 pc에서 요청하면 www.b.com 페이지가 표시될 줄 알았습니다.
순진한 생각이었나요??
결과는 뒤죽박죽이었습니다.
해당 페이지에 로딩되는 content의 수(turn 수) 만큼 backend 서버 간에 round robin 이 이루어지고 있었습니다.
응답코드로 보면 200 과 404 의 아비규환
- 테스트 환경
http {
upstream backend {
server www.a.com;
server www.b.com;
}
server {
listen 80:
sever_name localhost;
location / {
proxy_pass http://backend;
}
}
}
- 특정 request에 대응하는 backend 서버 확인 (access_log 설정)
log_format main ' $remote_addr - $remote_user [$time_local] "$request" '
' $status $body_bytes_sent "$http_referer" '
' "$http_user_agent" "$http_x_forwarded_for" "$upstream_addr" ';
우리는 Apache/Jboss 연동이나, Apache/Tomcat 또는 iPlanet/WebLogic 연동을 통해서
학습과 경험한 바와 같이, WEB과 WAS가 2:2 이상으로 연결되어 있는 환경이라도
(장애가 없는 상황이라면) 동일 사용자의 request는 동일한 WEB과 동일한 WAS에서 처리되는 것으로
알고 있습니다.
이런 이유는 mod_jk 나 wl_proxy와 같이 WAS에서 제공하는 plugin 모듈에서는 StickySession 기능을
기본적으로 제공하기 때문입니다.
이 외에, Apache 자체적으로도 mod_proxy_balancer 를 통하여 proxy 서버들 간에 StickySession 기능을 제공 하더군요.
하지만, nginx의 proxy_pass는 StickySession을 지원하지 않네요. (적어도 1.4.2 버전에서는)
저는 적어도 동일한 사용자의 요청에 대해서는 기본적으로 StickySession이 적용될 줄로 알았습니다.
o 관련 내용은 미할님의 글 "Advanced load balancing" 게시물 참고
o http://sarc.io/index.php/nginx/98-advanced-load-balancing
오늘의 Lessons Learned 입니다.
o upstream을 이용한 load balancing 구성 시 주의사항
- nginx 버전이 plus 이상이 아닌 경우 (걍 nginx 버전 사용 시)
- session을 이용 하지만, backend 서버들이 session cluster가 되어 있지 않은 경우
- backend 서버들이 session cluster가 되어 있어도 session replication 지연이 있는 경우
o 위와 같은 경우에는 반드시 ip_hash 지시어을 사용해야 함
o 그렇지 않은 경우, 서비스가 비정상이라는 end-user의 claim을 받을 수 있음
- 개선 환경
http {
upstream backend {
ip_hash;
server www.a.com;
server www.b.com;
}
server {
listen 80:
sever_name localhost;
location / {
proxy_pass http://backend;
}
}
}