HAProxy Architecture


HAProxy Architecture

HAProxy Architecture Guide

version 1.1.34
willy tarreau
2006/01/29

This document provides real world examples with working configurations. Please note that except stated otherwise, global configuration parameters such as logging, chrooting, limits and time-outs are not described here.

이 문서는 작업 구성과 함께 실제 사례를 제공합니다. 달리 명시되지 않는 한 로깅, chrooting, 제한 및 시간 초과와 같은 전역 구성 매개변수는 여기에 설명되지 않습니다.

architecture.txt (TXT 문서)


1. Simple HTTP load-balancing with cookie insertion

쿠키 삽입으로 간단한 HTTP 로드 밸런싱

A web application often saturates the front-end server with high CPU loads, due to the scripting language involved. It also relies on a back-end database which is not much loaded. User contexts are stored on the server itself, and not in the database, so that simply adding another server with simple IP/TCP load-balancing would not work.

웹 애플리케이션은 관련된 스크립팅 언어로 인해 종종 높은 CPU 로드로 프런트 엔드 서버를 포화시킵니다. 또한 로드가 많지 않은 백엔드 데이터베이스에 의존합니다. 사용자 컨텍스트는 데이터베이스가 아닌 서버 자체에 저장되므로 단순한 IP/TCP 로드 밸런싱으로 다른 서버를 추가하는 것만으로는 작동하지 않습니다.

                +-------+
                |clients|  clients and/or reverse-proxy
                +---+---+
                    |
                   -+-----+--------+----
                          |       _|_db
                        +--+--+  (___)
                        | web |  (___)
                        +-----+  (___)
                    192.168.1.1  192.168.1.2

Replacing the web server with a bigger SMP system would cost much more than adding low-cost pizza boxes. The solution is to buy N cheap boxes and install the application on them. Install haproxy on the old one which will spread the load across the new boxes.

웹 서버를 더 큰 SMP 시스템으로 교체하는 것은 저렴한 피자 상자를 추가하는 것보다 훨씬 많은 비용이 듭니다. 해결책은 N개의 저렴한 서버를 구입하고 그 위에 응용 프로그램을 설치하는 것입니다. 새 서버에 부하를 분산시킬 이전 항목에 haproxy를 설치합니다.

  192.168.1.1    192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----------+-----+-----+-----+--------+----
        |           |     |     |     |       _|_db
     +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | A | | B | | C | | D |    (___)
     +-----+      +---+ +---+ +---+ +---+    (___)
     haproxy        4 cheap web servers

Config on haproxy (LB1) :

    listen webfarm 192.168.1.1:80
       mode http
       balance roundrobin
       cookie SERVERID insert indirect
       option httpchk HEAD /index.html HTTP/1.0
       server webA 192.168.1.11:80 cookie A check
       server webB 192.168.1.12:80 cookie B check
       server webC 192.168.1.13:80 cookie C check
       server webD 192.168.1.14:80 cookie D check

Description :

  • LB1 will receive clients requests.
    LB1은 클라이언트 요청을 수신합니다.
  • if a request does not contain a cookie, it will be forwarded to a valid server
    요청에 쿠키가 포함되어 있지 않으면 유효한 서버로 전달됩니다.
  • in return, a cookie "SERVERID" will be inserted in the response holding the server name (eg: "A").
    반환 시 쿠키 "SERVERID"가 서버 이름(예: "A")을 포함하는 응답에 삽입됩니다.
  • when the client comes again with the cookie "SERVERID=A", LB1 will know that it must be forwarded to server A. The cookie will be removed so that the server does not see it.
    클라이언트가 "SERVERID=A" 쿠키와 함께 다시 오면 LB1은 서버 A로 전달되어야 함을 알게 됩니다. 쿠키는 서버에서 볼 수 없도록 제거됩니다.
  • if server "webA" dies, the requests will be sent to another valid server and a cookie will be reassigned.
    서버 "webA"가 죽으면 요청이 다른 유효한 서버로 전송되고 쿠키가 재할당됩니다.

Flows :

(client)                           (haproxy)                         (server A)
  >-- GET /URI1 HTTP/1.0 ------------> |
               ( no cookie, haproxy forwards in load-balancing mode. )
                                       | >-- GET /URI1 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
               ( the proxy now adds the server cookie in return )
  <-- HTTP/1.0 200 OK ---------------< |
      Set-Cookie: SERVERID=A           |
  >-- GET /URI2 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
      ( the proxy sees the cookie. it forwards to server A and deletes it )
                                       | >-- GET /URI2 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
   ( the proxy does not add the cookie in return because the client knows it )
  <-- HTTP/1.0 200 OK ---------------< |
  >-- GET /URI3 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
                                    ( ... )

Limits :

  • if clients use keep-alive (HTTP/1.1), only the first response will have a cookie inserted, and only the first request of each session will be analyzed. This does not cause trouble in insertion mode because the cookie is put immediately in the first response, and the session is maintained to the same server for all subsequent requests in the same session. However, the cookie will not be removed from the requests forwarded to the servers, so the server must not be sensitive to unknown cookies. If this causes trouble, you can disable keep-alive by adding the following option :
    클라이언트가 연결 유지(HTTP/1.1)를 사용하는 경우 첫 번째 응답에만 쿠키가 삽입되고 각 세션의 첫 번째 요청만 분석됩니다. 쿠키가 첫 번째 응답에 즉시 배치되고 세션이 동일한 세션의 모든 후속 요청에 대해 동일한 서버에 유지되기 때문에 삽입 모드에서는 문제가 발생하지 않습니다. 하지만, 쿠키는 서버로 전달되는 요청에서 제거되지 않으므로 서버는 알 수 없는 쿠키에 민감하지 않아야 합니다. 이로 인해 문제가 발생하면 다음 옵션을 추가하여 연결 유지를 비활성화할 수 있습니다.
         option httpclose
  • if for some reason the clients cannot learn more than one cookie (eg: the clients are indeed some home-made applications or gateways), and the application already produces a cookie, you can use the "prefix" mode (see below).
    어떤 이유로 클라이언트가 하나 이상의 쿠키를 학습할 수 없고(예: 클라이언트가 실제로 일부 집에서 만든 응용 프로그램 또는 게이트웨이인 경우) 응용 프로그램이 이미 쿠키를 생성하는 경우 "접두사" 모드를 사용할 수 있습니다 (아래 참조).
  • LB1 becomes a very sensible server. If LB1 dies, nothing works anymore.
    => you can back it up using keepalived (see below)
    LB1은 매우 민감한 서버가 됩니다. LB1이 죽으면 아무 것도 더 이상 작동하지 않습니다.
    => keepalived를 사용하여 백업할 수 있습니다 (아래 참조).
  • if the application needs to log the original client's IP, use the "forwardfor" option which will add an "X-Forwarded-For" header with the original client's IP address. You must also use "httpclose" to ensure that you will rewrite every requests and not only the first one of each session :
    응용 프로그램이 원래 클라이언트의 IP를 기록해야 하는 경우 원래 클라이언트의 IP 주소와 함께 "X-Forwarded-For" 헤더를 추가하는 "forwardfor" 옵션을 사용하십시오. 또한 "httpclose"를 사용하여 각 세션의 첫 번째 요청뿐만 아니라 모든 요청을 다시 작성해야 합니다.
         option httpclose
         option forwardfor	
  • if the application needs to log the original destination IP, use the "originalto" option which will add an "X-Original-To" header with the original destination IP address. You must also use "httpclose" to ensure that you will rewrite every requests and not only the first one of each session :
    응용 프로그램이 원래 대상 IP를 기록해야 하는 경우 원래 대상 IP 주소와 함께 "X-Original-To" 헤더를 추가하는 "originalto" 옵션을 사용하십시오. 또한 "httpclose"를 사용하여 각 세션의 첫 번째 요청뿐만 아니라 모든 요청을 다시 작성해야 합니다.
         option httpclose
         option originalto 
    The web server will have to be configured to use this header instead. For example, on apache, you can use LogFormat for this :
    대신 이 헤더를 사용하도록 웹 서버를 구성해야 합니다. 예를 들어 Apache에서는 다음과 같이 LogFormat을 사용할 수 있습니다.
         LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b " combined
         CustomLog /var/log/httpd/access_log combined

Hints :

Sometimes on the internet, you will find a few percent of the clients which disable cookies on their browser. Obviously they have troubles everywhere on the web, but you can still help them access your site by using the "source" balancing algorithm instead of the "roundrobin". It ensures that a given IP address always reaches the same server as long as the number of servers remains unchanged. Never use this behind a proxy or in a small network, because the distribution will be unfair. However, in large internal networks, and on the internet, it works quite well. Clients which have a dynamic address will not be affected as long as they accept the cookie, because the cookie always has precedence over load balancing :
때때로 인터넷에서 브라우저에서 쿠키를 비활성화하는 클라이언트의 몇 퍼센트를 찾을 수 있습니다. 분명히 그들은 웹의 모든 곳에서 문제가 있지만 "라운드 로빈" 대신 "소스" 균형 알고리즘을 사용하여 여전히 사이트에 액세스하도록 도울 수 있습니다. 서버 수가 변경되지 않는 한 주어진 IP 주소가 항상 동일한 서버에 도달하도록 합니다. 배포가 불공평하기 때문에 프록시 뒤에서 또는 소규모 네트워크에서 이것을 사용하지 마십시오. 그러나 대규모 내부 네트워크와 인터넷에서는 꽤 잘 작동합니다. 쿠키가 항상 로드 밸런싱보다 우선하기 때문에 동적 주소가 있는 클라이언트는 쿠키를 수락하는 한 영향을 받지 않습니다.

    listen webfarm 192.168.1.1:80
       mode http
       balance source
       cookie SERVERID insert indirect
       option httpchk HEAD /index.html HTTP/1.0
       server webA 192.168.1.11:80 cookie A check
       server webB 192.168.1.12:80 cookie B check
       server webC 192.168.1.13:80 cookie C check
       server webD 192.168.1.14:80 cookie D check       

2. HTTP load-balancing with cookie prefixing and high availability

쿠키 프리픽스 및 고가용성을 통한 HTTP 로드 밸런싱

Now you don't want to add more cookies, but rather use existing ones. The application already generates a "JSESSIONID" cookie which is enough to track sessions, so we'll prefix this cookie with the server name when we see it. Since the load-balancer becomes critical, it will be backed up with a second one in VRRP mode using keepalived under Linux.

이제 더 많은 쿠키를 추가하지 않고 기존 쿠키를 사용합니다. 응용 프로그램은 세션을 추적하기에 충분한 "JSESSIONID" 쿠키를 이미 생성하므로 이 쿠키를 볼 때 서버 이름을 앞에 붙입니다. 로드 밸런서가 중요해지기 때문에 Linux에서 keepalived를 사용하여 VRRP 모드에서 두 번째 로드 밸런서로 백업됩니다.

Download the latest version of keepalived from this site and install it on each load-balancer LB1 and LB2 :
이 사이트에서 최신 버전의 keepalived를 다운로드하여 각 로드 밸런서 LB1 및 LB2에 설치하십시오.

http://www.keepalived.org/

You then have a shared IP between the two load-balancers (we will still use the original IP). It is active only on one of them at any moment. To allow the proxy to bind to the shared IP on Linux 2.4, you must enable it in /proc :

그러면 두 로드 밸런서 간에 공유 IP가 생깁니다(여전히 원래 IP를 사용함). 언제든지 그 중 하나에서만 활성화됩니다. Linux 2.4에서 프록시가 공유 IP에 바인딩되도록 하려면 /proc에서 프록시를 활성화해야 합니다.

# echo 1 >/proc/sys/net/ipv4/ip_nonlocal_bind

    shared IP=192.168.1.1
  192.168.1.3  192.168.1.4    192.168.1.11-192.168.1.14   192.168.1.2
 -------+------------+-----------+-----+-----+-----+--------+----
        |            |           |     |     |     |       _|_db
     +--+--+      +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | LB2 |      | A | | B | | C | | D |    (___)
     +-----+      +-----+      +---+ +---+ +---+ +---+    (___)
     haproxy      haproxy        4 cheap web servers
     keepalived   keepalived

Config on both proxies (LB1 and LB2) :

    listen webfarm 192.168.1.1:80
       mode http
       balance roundrobin
       cookie JSESSIONID prefix
       option httpclose
       option forwardfor
       option httpchk HEAD /index.html HTTP/1.0
       server webA 192.168.1.11:80 cookie A check
       server webB 192.168.1.12:80 cookie B check
       server webC 192.168.1.13:80 cookie C check
       server webD 192.168.1.14:80 cookie D check

Notes: the proxy will modify EVERY cookie sent by the client and the server, so it is important that it can access to ALL cookies in ALL requests for each session. This implies that there is no keep-alive (HTTP/1.1), thus the "httpclose" option. Only if you know for sure that the client(s) will never use keep-alive (eg: Apache 1.3 in reverse-proxy mode), you can remove this option.

참고: 프록시는 클라이언트와 서버가 보낸 모든 쿠키를 수정하므로 각 세션에 대한 모든 요청의 모든 쿠키에 액세스할 수 있어야 합니다. 이는 keep-alive(HTTP/1.1)가 없으므로 "httpclose" 옵션이 있음을 의미합니다. 클라이언트가 keep-alive를 사용하지 않는다는 것을 확실히 아는 경우에만 이 옵션을 제거할 수 있습니다 (예: 리버스 프록시 모드의 Apache 1.3).

Configuration for keepalived on LB1/LB2 :

    vrrp_script chk_haproxy {           # Requires keepalived-1.1.13
        script "killall -0 haproxy"     # cheaper than pidof
        interval 2                      # check every 2 seconds
	weight 2                        # add 2 points of prio if OK
    }

    vrrp_instance VI_1 {
        interface eth0
        state MASTER
        virtual_router_id 51
        priority 101                    # 101 on master, 100 on backup
        virtual_ipaddress {
            192.168.1.1
        }
        track_script {
            chk_haproxy
        }
    }

Description :

  • LB1 is VRRP master (keepalived), LB2 is backup. Both monitor the haproxy process, and lower their prio if it fails, leading to a failover to the other node.
    LB1은 VRRP 마스터(keepalived)이고 LB2는 백업입니다. 둘 다 haproxy 프로세스를 모니터링하고 실패하면 prio를 낮추어 다른 노드로 장애 조치합니다.
  • LB1 will receive clients requests on IP 192.168.1.1.
    LB1은 IP 192.168.1.1에서 클라이언트 요청을 수신합니다.
  • both load-balancers send their checks from their native IP.
    두 로드 밸런서 모두 기본 IP에서 검사를 보냅니다.
  • if a request does not contain a cookie, it will be forwarded to a valid server.
    요청에 쿠키가 포함되어 있지 않으면 유효한 서버로 전달됩니다.
  • in return, if a JESSIONID cookie is seen, the server name will be prefixed into it, followed by a delimiter ('~')
    반환 시 JESSIONID 쿠키가 표시되면 서버 이름이 앞에 붙고 그 뒤에 구분 기호('~')가 붙습니다.
  • when the client comes again with the cookie "JSESSIONID=A~xxx", LB1 will know that it must be forwarded to server A. The server name will then be extracted from cookie before it is sent to the server.
    클라이언트가 "JSESSIONID=A~xxx" 쿠키와 함께 다시 오면 LB1은 서버 A로 전달되어야 함을 알게 됩니다. 서버 이름은 서버로 전송되기 전에 쿠키에서 추출됩니다.
  • if server "webA" dies, the requests will be sent to another valid server and a cookie will be reassigned.
    서버 "webA"가 죽으면 요청이 다른 유효한 서버로 전송되고 쿠키가 재할당됩니다.

Flows :

(client)                           (haproxy)                         (server A)
  >-- GET /URI1 HTTP/1.0 ------------> |
               ( no cookie, haproxy forwards in load-balancing mode. )
                                       | >-- GET /URI1 HTTP/1.0 ---------->
                                       |     X-Forwarded-For: 10.1.2.3
                                       | <-- HTTP/1.0 200 OK -------------<
                        ( no cookie, nothing changed )
  <-- HTTP/1.0 200 OK ---------------< |
  >-- GET /URI2 HTTP/1.0 ------------> |
    ( no cookie, haproxy forwards in lb mode, possibly to another server. )
                                       | >-- GET /URI2 HTTP/1.0 ---------->
                                       |     X-Forwarded-For: 10.1.2.3
                                       | <-- HTTP/1.0 200 OK -------------<
                                       |     Set-Cookie: JSESSIONID=123
    ( the cookie is identified, it will be prefixed with the server name )
  <-- HTTP/1.0 200 OK ---------------< |
      Set-Cookie: JSESSIONID=A~123     |
  >-- GET /URI3 HTTP/1.0 ------------> |
      Cookie: JSESSIONID=A~123         |
       ( the proxy sees the cookie, removes the server name and forwards
          to server A which sees the same cookie as it previously sent )
                                       | >-- GET /URI3 HTTP/1.0 ---------->
                                       |     Cookie: JSESSIONID=123
                                       |     X-Forwarded-For: 10.1.2.3
                                       | <-- HTTP/1.0 200 OK -------------<
                        ( no cookie, nothing changed )
  <-- HTTP/1.0 200 OK ---------------< |
                                    ( ... )

Hints :

Sometimes, there will be some powerful servers in the farm, and some smaller ones. In this situation, it may be desirable to tell haproxy to respect the difference in performance. Let's consider that WebA and WebB are two old P3-1.2 GHz while WebC and WebD are shiny new Opteron-2.6 GHz. If your application scales with CPU, you may assume a very rough 2.6/1.2 performance ratio between the servers. You can inform haproxy about this using the "weight" keyword, with values between 1 and 256. It will then spread the load the most smoothly possible respecting those ratios :

경우에 따라 팜에 강력한 서버와 소규모 서버가 있을 수 있습니다. 이 상황에서 haproxy에게 성능 차이를 존중하도록 지시하는 것이 바람직할 수 있습니다. WebA와 WebB는 두 개의 오래된 P3-1.2GHz이고 WebC와 WebD는 반짝이는 새로운 Opteron-2.6GHz라고 가정해 보겠습니다. 애플리케이션이 CPU와 함께 확장되는 경우 서버 간 성능 비율이 대략 2.6/1.2라고 가정할 수 있습니다. 값이 1에서 256 사이인 "weight" 키워드를 사용하여 haproxy에 이에 대해 알릴 수 있습니다. 그런 다음 해당 비율과 관련하여 가장 원활하게 로드를 분산합니다.

       server webA 192.168.1.11:80 cookie A weight 12 check
       server webB 192.168.1.12:80 cookie B weight 12 check
       server webC 192.168.1.13:80 cookie C weight 26 check
       server webD 192.168.1.14:80 cookie D weight 26 check

2.1 Variations involving external layer 4 load-balancers

외부 레이어 4 로드 밸런서와 관련된 변형

Instead of using a VRRP-based active/backup solution for the proxies, they can also be load-balanced by a layer4 load-balancer (eg: Alteon) which will also check that the services run fine on both proxies :

프록시에 VRRP 기반 활성/백업 솔루션을 사용하는 대신 두 프록시에서 서비스가 제대로 실행되는지 확인하는 레이어4 로드 밸런서(예: Alteon 알테온)에 의해 로드 밸런싱될 수도 있습니다.

              | VIP=192.168.1.1
         +----+----+
         | Alteon  |
         +----+----+
              |
 192.168.1.3  |  192.168.1.4  192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----+------+-----------+-----+-----+-----+--------+----
        |            |           |     |     |     |       _|_db
     +--+--+      +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | LB2 |      | A | | B | | C | | D |    (___)
     +-----+      +-----+      +---+ +---+ +---+ +---+    (___)
     haproxy      haproxy        4 cheap web servers

Config on both proxies (LB1 and LB2) :

    listen webfarm 0.0.0.0:80
       mode http
       balance roundrobin
       cookie JSESSIONID prefix
       option httpclose
       option forwardfor
       option httplog
       option dontlognull
       option httpchk HEAD /index.html HTTP/1.0
       server webA 192.168.1.11:80 cookie A check
       server webB 192.168.1.12:80 cookie B check
       server webC 192.168.1.13:80 cookie C check
       server webD 192.168.1.14:80 cookie D check

The "dontlognull" option is used to prevent the proxy from logging the health checks from the Alteon. If a session exchanges no data, then it will not be logged.
"dontlognull" 옵션은 프록시가 Alteon에서 상태 검사를 기록하지 못하도록 하는 데 사용됩니다. 세션에서 데이터를 교환하지 않으면 기록되지 않습니다.

Config on the Alteon :

    /c/slb/real  11
           ena
           name "LB1"
           rip 192.168.1.3
    /c/slb/real  12
           ena
           name "LB2"
           rip 192.168.1.4
    /c/slb/group 10
           name "LB1-2"
           metric roundrobin
           health tcp
           add 11
           add 12
    /c/slb/virt 10
           ena
           vip 192.168.1.1
    /c/slb/virt 10/service http
           group 10

Note: the health-check on the Alteon is set to "tcp" to prevent the proxy from forwarding the connections. It can also be set to "http", but for this the proxy must specify a "monitor-net" with the Alteons' addresses, so that the Alteon can really check that the proxies can talk HTTP but without forwarding the connections to the end servers. Check next section for an example on how to use monitor-net.
참고: Alteon의 상태 확인은 프록시가 연결을 전달하지 못하도록 "tcp"로 설정됩니다. 또한 "http"로 설정할 수 있지만 이를 위해 프록시는 Alteons의 주소로 "monitor-net"을 지정해야 합니다. 그래야 Alteon이 실제로 프록시가 HTTP와 통신할 수 있지만 연결을 끝 서버까지 전달하지 않고 확인할 수 있습니다. 모니터넷(monitor-net) 사용 방법에 대한 예는 다음 섹션을 확인하십시오.

2.2 Generic TCP relaying and external layer 4 load-balancers

일반 TCP 릴레이 및 외부 레이어 4 로드 밸런서

Sometimes it's useful to be able to relay generic TCP protocols (SMTP, TSE, VNC, etc...), for example to interconnect private networks. The problem comes when you use external load-balancers which need to send periodic health-checks to the proxies, because these health-checks get forwarded to the end servers. The solution is to specify a network which will be dedicated to monitoring systems and must not lead to a forwarding connection nor to any log, using the "monitor-net" keyword. Note: this feature expects a version of haproxy greater than or equal to 1.1.32 or 1.2.6.

예를 들어 개인 네트워크를 상호 연결하기 위해 일반 TCP 프로토콜(SMTP, TSE, VNC 등)을 릴레이할 수 있는 것이 때때로 유용합니다. 이러한 상태 확인이 최종 서버로 전달되기 때문에 정기적인 상태 확인을 프록시로 보내야 하는 외부 로드 밸런서를 사용할 때 문제가 발생합니다. 해결 방법은 "monitor-net" 키워드를 사용하여 모니터링 시스템 전용 네트워크를 지정하고 전달 연결이나 로그로 연결되어서는 안 되는 네트워크를 지정하는 것입니다. 참고: 이 기능은 haproxy 버전 1.1.32 또는 1.2.6 이상이 필요합니다.

                |  VIP=172.16.1.1   |
           +----+----+         +----+----+
           | Alteon1 |         | Alteon2 |
           +----+----+         +----+----+
 192.168.1.252  |  GW=192.168.1.254 |  192.168.1.253
                |                   |
          ------+---+------------+--+-----------------> TSE farm : 192.168.1.10
       192.168.1.1  |            | 192.168.1.2
                 +--+--+      +--+--+
                 | LB1 |      | LB2 |
                 +-----+      +-----+
                 haproxy      haproxy

Config on both proxies (LB1 and LB2) :

    listen tse-proxy
       bind :3389,:1494,:5900  # TSE, ICA and VNC at once.
       mode tcp
       balance roundrobin
       server tse-farm 192.168.1.10
       monitor-net 192.168.1.252/31

The "monitor-net" option instructs the proxies that any connection coming from 192.168.1.252 or 192.168.1.253 will not be logged nor forwarded and will be closed immediately. The Alteon load-balancers will then see the proxies alive without perturbating the service.

"monitor-net" 옵션은 192.168.1.252 또는 192.168.1.253에서 오는 모든 연결이 기록되거나 전달되지 않고 즉시 닫히도록 프록시에 지시합니다. Alteon 로드 밸런서는 서비스를 방해하지 않고 프록시가 활성 상태임을 확인합니다.

Config on the Alteon :

    /c/l3/if 1
           ena
           addr 192.168.1.252
           mask 255.255.255.0
    /c/slb/real  11
           ena
           name "LB1"
           rip 192.168.1.1
    /c/slb/real  12
           ena
           name "LB2"
           rip 192.168.1.2
    /c/slb/group 10
           name "LB1-2"
           metric roundrobin
           health tcp
           add 11
           add 12
    /c/slb/virt 10
           ena
           vip 172.16.1.1
    /c/slb/virt 10/service 1494
           group 10
    /c/slb/virt 10/service 3389
           group 10
    /c/slb/virt 10/service 5900
           group 10

Special handling of SSL :

Sometimes, you want to send health-checks to remote systems, even in TCP mode, in order to be able to failover to a backup server in case the first one is dead. Of course, you can simply enable TCP health-checks, but it sometimes happens that intermediate firewalls between the proxies and the remote servers acknowledge the TCP connection themselves, showing an always-up server. Since this is generally encountered on long-distance communications, which often involve SSL, an SSL health-check has been implemented to work around this issue. It sends SSL Hello messages to the remote server, which in turns replies with SSL Hello messages. Setting it up is very easy :

경우에 따라 첫 번째 서버가 죽은 경우 백업 서버로 장애 조치할 수 있도록 TCP 모드에서도 원격 시스템에 상태 검사를 보내야 합니다. 물론 단순히 TCP 상태 확인을 활성화할 수 있지만 프록시와 원격 서버 사이의 중간 방화벽이 TCP 연결 자체를 승인하여 상시 가동 서버를 표시하는 경우가 가끔 발생합니다. 이것은 일반적으로 SSL과 관련된 장거리 통신에서 발생하므로 이 문제를 해결하기 위해 SSL 상태 검사가 구현되었습니다. 원격 서버에 SSL Hello 메시지를 보내고 SSL Hello 메시지로 응답합니다. 설정은 매우 쉽습니다.

    listen tcp-syslog-proxy
       bind :1514      # listen to TCP syslog traffic on this port (SSL)
       mode tcp
       balance roundrobin
       option ssl-hello-chk
       server syslog-prod-site 192.168.1.10 check
       server syslog-back-site 192.168.2.10 check backup

3. Simple HTTP/HTTPS load-balancing with cookie insertion

쿠키 삽입을 통한 간단한 HTTP/HTTPS 로드 밸런싱

This is the same context as in example 1 above, but the web server uses HTTPS.
위의 예제 1과 같은 컨텍스트이지만 웹 서버는 HTTPS를 사용합니다.

                +-------+
                |clients|  clients
                +---+---+
                    |
                   -+-----+--------+----
                          |       _|_db
                       +--+--+   (___)
                       | SSL |   (___)
                       | web |   (___)
                       +-----+
                   192.168.1.1   192.168.1.2

Since haproxy does not handle SSL, this part will have to be extracted from the servers (freeing even more resources) and installed on the load-balancer itself. Install haproxy and apache+mod_ssl on the old box which will spread the load between the new boxes. Apache will work in SSL reverse-proxy-cache. If the application is correctly developed, it might even lower its load. However, since there now is a cache between the clients and haproxy, some security measures must be taken to ensure that inserted cookies will not be cached.

haproxy는 SSL을 처리하지 않기 때문에 이 부분을 서버에서 추출하여(더 많은 리소스 확보) 로드 밸런서 자체에 설치해야 합니다. 이전 상자에 haproxy 및 apache+mod_ssl을 설치하면 새 상자 간에 부하가 분산됩니다. Apache는 SSL 역방향 프록시 캐시에서 작동합니다. 응용 프로그램이 올바르게 개발되면 부하를 낮출 수도 있습니다. 그러나 이제 클라이언트와 haproxy 사이에 캐시가 있으므로 삽입된 쿠키가 캐시되지 않도록 몇 가지 보안 조치를 취해야 합니다.

  192.168.1.1    192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----------+-----+-----+-----+--------+----
        |           |     |     |     |       _|_db
     +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | A | | B | | C | | D |    (___)
     +-----+      +---+ +---+ +---+ +---+    (___)
     apache         4 cheap web servers
     mod_ssl
     haproxy 

Config on haproxy (LB1) :

    listen 127.0.0.1:8000
       mode http
       balance roundrobin
       cookie SERVERID insert indirect nocache
       option httpchk HEAD /index.html HTTP/1.0
       server webA 192.168.1.11:80 cookie A check
       server webB 192.168.1.12:80 cookie B check
       server webC 192.168.1.13:80 cookie C check
       server webD 192.168.1.14:80 cookie D check

Description(설명) :

  • apache on LB1 will receive clients requests on port 443.
    LB1의 Apache는 포트 443에서 클라이언트 요청을 수신합니다.
  • it forwards it to haproxy bound to 127.0.0.1:8000
    127.0.0.1:8000에 연결된 haproxy로 전달합니다.
  • if a request does not contain a cookie, it will be forwarded to a valid server.
    요청에 쿠키가 포함되어 있지 않으면 유효한 서버로 전달됩니다.
  • in return, a cookie "SERVERID" will be inserted in the response holding the server name (eg: "A"), and a "Cache-control: private" header will be added so that the apache does not cache any page containing such cookie.
    반환 시 "SERVERID" 쿠키가 서버 이름(예: "A")을 포함하는 응답에 삽입되고 "Cache-control: private" 헤더가 추가되어 Apache가 그러한 쿠키 정보를 포함하는 페이지를 캐시하지 않도록 합니다.
  • when the client comes again with the cookie "SERVERID=A", LB1 will know that it must be forwarded to server A. The cookie will be removed so that the server does not see it.
    클라이언트가 "SERVERID=A" 쿠키와 함께 다시 오면 LB1은 서버 A로 전달되어야 함을 알게 됩니다. 쿠키는 서버에서 볼 수 없도록 제거됩니다.
  • if server "webA" dies, the requests will be sent to another valid server and a cookie will be reassigned.
    서버 "webA"가 죽으면 요청이 다른 유효한 서버로 전송되고 쿠키가 재할당됩니다.

Notes(참고) :

  • if the cookie works in "prefix" mode, there is no need to add the "nocache" option because it is an application cookie which will be modified, and the application flags will be preserved.
    쿠키가 "접두사" 모드에서 작동하는 경우 "nocache" 옵션을 추가할 필요가 없습니다. 수정될 응용 프로그램 쿠키이고 응용 프로그램 플래그가 보존되기 때문입니다.
  • if apache 1.3 is used as a front-end before haproxy, it always disables HTTP keep-alive on the back-end, so there is no need for the "httpclose" option on haproxy.
    Apache 1.3이 haproxy 이전에 프런트 엔드로 사용되는 경우 항상 백엔드에서 HTTP keep-alive를 비활성화하므로 haproxy에서 "httpclose" 옵션이 필요하지 않습니다.
  • configure apache to set the X-Forwarded-For header itself, and do not do it on haproxy if you need the application to know about the client's IP.
    X-Forwarded-For 헤더 자체를 설정하도록 Apache를 구성하고 응용 프로그램이 클라이언트의 IP에 대해 알아야 하는 경우 haproxy에서 수행하지 마십시오.

Flows(흐름) :

(apache)                           (haproxy)                         (server A)
  >-- GET /URI1 HTTP/1.0 ------------> |
               ( no cookie, haproxy forwards in load-balancing mode. )
                                       | >-- GET /URI1 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
               ( the proxy now adds the server cookie in return )
  <-- HTTP/1.0 200 OK ---------------< |
      Set-Cookie: SERVERID=A           |
      Cache-Control: private           |
  >-- GET /URI2 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
      ( the proxy sees the cookie. it forwards to server A and deletes it )
                                       | >-- GET /URI2 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
   ( the proxy does not add the cookie in return because the client knows it )
  <-- HTTP/1.0 200 OK ---------------< |
  >-- GET /URI3 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
                                    ( ... )

3.1. Alternate solution using Stunnel

When only SSL is required and cache is not needed, stunnel is a cheaper solution than Apache+mod_ssl. By default, stunnel does not process HTTP and does not add any X-Forwarded-For header, but there is a patch on the official haproxy site to provide this feature to recent stunnel versions.

SSL만 필요하고 캐시가 필요하지 않은 경우 stunnel은 Apache+mod_ssl보다 저렴한 솔루션입니다. 기본적으로 stunnel은 HTTP를 처리하지 않으며 X-Forwarded-For 헤더를 추가하지 않지만 공식 haproxy 사이트에는 최신 stunnel 버전에 이 기능을 제공하는 패치가 있습니다.

This time, stunnel will only process HTTPS and not HTTP. This means that haproxy will get all HTTP traffic, so haproxy will have to add the X-Forwarded-For header for HTTP traffic, but not for HTTPS traffic since stunnel will already have done it. We will use the "except" keyword to tell haproxy that connections from local host already have a valid header.

이번에는 stunnel이 HTTP가 아닌 HTTPS만 처리합니다. 즉, haproxy가 모든 HTTP 트래픽을 가져오므로 haproxy는 HTTP 트래픽에 대해 X-Forwarded-For 헤더를 추가해야 하지만 stunnel이 이미 수행했기 때문에 HTTPS 트래픽에 대해서는 그렇지 않습니다. 로컬 호스트의 연결에 이미 유효한 헤더가 있음을 haproxy에 알리기 위해 "except" 키워드를 사용합니다.

  192.168.1.1    192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----------+-----+-----+-----+--------+----
        |           |     |     |     |       _|_db
     +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | A | | B | | C | | D |    (___)
     +-----+      +---+ +---+ +---+ +---+    (___)
     stunnel        4 cheap web servers
     haproxy 

Config on stunnel (LB1) stunnel 구성:

    cert=/etc/stunnel/stunnel.pem
    setuid=stunnel
    setgid=proxy

    socket=l:TCP_NODELAY=1
    socket=r:TCP_NODELAY=1

    [https]
    accept=192.168.1.1:443
    connect=192.168.1.1:80
    xforwardedfor=yes

Config on haproxy (LB1) haproxy 구성:

    listen 192.168.1.1:80
       mode http
       balance roundrobin
       option forwardfor except 192.168.1.1
       cookie SERVERID insert indirect nocache
       option httpchk HEAD /index.html HTTP/1.0
       server webA 192.168.1.11:80 cookie A check
       server webB 192.168.1.12:80 cookie B check
       server webC 192.168.1.13:80 cookie C check
       server webD 192.168.1.14:80 cookie D check

Description(설명) :

  • stunnel on LB1 will receive clients requests on port 443
    LB1의 stunnel은 포트 443에서 클라이언트 요청을 수신합니다.
  • it forwards them to haproxy bound to port 80.
    stunnel은 haproxy 포트 80로 전달합니다.
  • haproxy will receive HTTP client requests on port 80 and decrypted SSL requests from Stunnel on the same port.
    haproxy는 포트 80에서 HTTP 클라이언트 요청을 수신하고 동일한 포트에서 Stunnel로부터 해독된 SSL 요청을 수신합니다.
  • stunnel will add the X-Forwarded-For header.
    stunnel은 X-Forwarded-For 헤더를 추가합니다.
  • haproxy will add the X-Forwarded-For header for everyone except the local address (stunnel).
    haproxy는 로컬 주소(stunnel)를 제외한 모든 것에 X-Forwarded-For 헤더를 추가합니다.

4. Soft-stop for application maintenance

애플리케이션 유지 관리를 위한 소프트 스톱

When an application is spread across several servers, the time to update all instances increases, so the application seems jerky for a longer period.

응용 프로그램이 여러 서버에 분산되어 있으면 모든 인스턴스를 업데이트하는 시간이 늘어나므로 응용 프로그램이 더 오랫동안 불안정하게 보입니다.

HAProxy offers several solutions for this. Although it cannot be reconfigured without being stopped, nor does it offer any external command, there are other working solutions.

HAProxy는 이를 위한 몇 가지 솔루션을 제공합니다. 중지하지 않고는 재구성할 수 없고 외부 명령을 제공하지 않지만 다른 작업 솔루션이 있습니다.

4.1 Soft-stop using a file on the servers

서버의 파일을 사용하여 소프트 스톱

This trick is quite common and very simple: put a file on the server which will be checked by the proxy. When you want to stop the server, first remove this file. The proxy will see the server as failed, and will not send it any new session, only the old ones if the "persist" option is used. Wait a bit then stop the server when it does not receive anymore connections.

이 트릭은 매우 일반적이고 매우 간단합니다. 프록시에서 확인할 파일을 서버에 저장합니다. 서버를 중지하려면 먼저 이 파일을 제거하십시오. 프록시는 서버가 실패한 것으로 보고 새 세션을 보내지 않고 "지속(persist)" 옵션이 사용된 경우 이전 세션만 보냅니다. 조금 기다린 다음 더 이상 연결을 수신하지 않으면 서버를 중지하십시오.

       
    listen 192.168.1.1:80
       mode http
       balance roundrobin
       cookie SERVERID insert indirect
       option httpchk HEAD /running HTTP/1.0
       server webA 192.168.1.11:80 cookie A check inter 2000 rise 2 fall 2
       server webB 192.168.1.12:80 cookie B check inter 2000 rise 2 fall 2
       server webC 192.168.1.13:80 cookie C check inter 2000 rise 2 fall 2
       server webD 192.168.1.14:80 cookie D check inter 2000 rise 2 fall 2
       option persist
       redispatch
       contimeout 5000

Description(설명) :

  • every 2 seconds, haproxy will try to access the file "/running" on the servers, and declare the server as down after 2 attempts (4 seconds).
    2초마다 haproxy는 서버의 "/running" 파일에 액세스를 시도하고 2번의 시도(4초) 후에 서버가 다운된 것으로 선언합니다.
  • only the servers which respond with a 200 or 3XX response will be used.
    200 또는 3XX 응답으로 응답하는 서버만 사용됩니다.
  • if a request does not contain a cookie, it will be forwarded to a valid server.
    요청에 쿠키가 포함되어 있지 않으면 유효한 서버로 전달됩니다.
  • if a request contains a cookie for a failed server, haproxy will insist on trying to reach the server anyway, to let the user finish what they were doing. ("persist" option)
    요청에 실패한 서버에 대한 쿠키가 포함되어 있으면 haproxy는 사용자가 하던 작업을 완료할 수 있도록 어쨌든 서버에 도달하려고 시도할 것입니다("지속 persist" 옵션).
  • if the server is totally stopped, the connection will fail and the proxy will rebalance the client to another server ("redispatch")
    서버가 완전히 중지되면 연결이 실패하고 프록시가 클라이언트를 다른 서버로 재조정합니다("redispatch").

Usage on the web servers :

  • to start the server :
    # /etc/init.d/httpd start
    # touch /home/httpd/www/running
  • to soft-stop the server
    # rm -f /home/httpd/www/running
  • to completely stop the server :
    # /etc/init.d/httpd stop

Limits(제한)

If the server is totally powered down, the proxy will still try to reach it for those clients who still have a cookie referencing it, and the connection attempt will expire after 5 seconds ("contimeout"), and only after that, the client will be redispatched to another server. So this mode is only useful for software updates where the server will suddenly refuse the connection because the process is stopped. The problem is the same if the server suddenly crashes. All of its users will be fairly perturbated.

서버의 전원이 완전히 꺼진 경우에도 프록시는 여전히 프록시를 참조하는 쿠키가 있는 클라이언트에 대해 연결을 시도하고 연결 시도는 5초 후에 만료됩니다("contimeout"). 다른 서버로 재전송됩니다. 따라서 이 모드는 프로세스가 중지되어 서버가 갑자기 연결을 거부하는 소프트웨어 업데이트에만 유용합니다. 서버가 갑자기 다운되더라도 문제는 동일합니다. 모든 사용자는 상당히 동요할 것입니다.

4.2 Soft-stop using backup servers

백업 서버를 사용한 소프트 스톱

A better solution which covers every situation is to use backup servers. Version 1.1.30 fixed a bug which prevented a backup server from sharing the same cookie as a standard server.

모든 상황을 다루는 더 나은 솔루션은 백업 서버를 사용하는 것입니다. 버전 1.1.30은 백업 서버가 표준 서버와 동일한 쿠키를 공유하지 못하게 하는 버그를 수정했습니다.

       
    listen 192.168.1.1:80
       mode http
       balance roundrobin
       redispatch
       cookie SERVERID insert indirect
       option httpchk HEAD / HTTP/1.0
       server webA 192.168.1.11:80 cookie A check port 81 inter 2000
       server webB 192.168.1.12:80 cookie B check port 81 inter 2000
       server webC 192.168.1.13:80 cookie C check port 81 inter 2000
       server webD 192.168.1.14:80 cookie D check port 81 inter 2000

       server bkpA 192.168.1.11:80 cookie A check port 80 inter 2000 backup
       server bkpB 192.168.1.12:80 cookie B check port 80 inter 2000 backup
       server bkpC 192.168.1.13:80 cookie C check port 80 inter 2000 backup
       server bkpD 192.168.1.14:80 cookie D check port 80 inter 2000 backup

Description(설명)

Four servers webA..D are checked on their port 81 every 2 seconds. The same servers named bkpA..D are checked on the port 80, and share the exact same cookies. Those servers will only be used when no other server is available for the same cookie.

4개의 서버 webA..D가 2초마다 포트 81에서 확인됩니다. bkpA..D라는 동일한 서버가 포트 80에서 확인되고 정확히 동일한 쿠키를 공유합니다. 이러한 서버는 동일한 쿠키에 사용할 수 있는 다른 서버가 없을 때만 사용됩니다.

When the web servers are started, only the backup servers are seen as available. On the web servers, you need to redirect port 81 to local port 80, either with a local proxy (eg: a simple haproxy tcp instance), or with iptables (linux) or pf (openbsd). This is because we want the real web server to reply on this port, and not a fake one. Eg, with iptables :

웹 서버가 시작되면 백업 서버만 사용 가능한 것으로 표시됩니다. 웹 서버에서 로컬 프록시(예: 간단한 haproxy tcp 인스턴스) 또는 iptables(linux) 또는 pf(openbsd)를 사용하여 포트 81을 로컬 포트 80으로 리디렉션해야 합니다. 이것은 실제 웹 서버가 가짜 포트(예를 들어, iptables)가 아닌 이 포트에서 응답하기를 원하기 때문입니다.

# /etc/init.d/httpd start
# iptables -t nat -A PREROUTING -p tcp --dport 81 -j REDIRECT --to-port 80

A few seconds later, the standard server is seen up and haproxy starts to send it new requests on its real port 80 (only new users with no cookie, of course).
몇 초 후 표준 서버가 표시되고 haproxy가 실제 포트 80에서 새 요청을 보내기 시작합니다(물론 쿠키가 없는 새 사용자만 해당).

If a server completely crashes (even if it does not respond at the IP level), both the standard and backup servers will fail, so clients associated to this server will be redispatched to other live servers and will lose their sessions.

서버가 완전히 충돌하면(IP 수준에서 응답하지 않더라도) 표준 서버와 백업 서버 모두 실패하므로 이 서버에 연결된 클라이언트는 다른 라이브 서버로 다시 파견되고 세션이 손실됩니다.

Now if you want to enter a server into maintenance, simply stop it from responding on port 81 so that its standard instance will be seen as failed, but the backup will still work. Users will not notice anything since the service is still operational :

이제 서버를 유지 관리에 들어가려면 포트 81에서 서버가 응답하지 않도록 하여 표준 인스턴스가 실패한 것으로 표시되지만 백업은 계속 작동합니다. 서비스가 계속 운영 중이므로 사용자는 아무 것도 알아차리지 못할 것입니다.

# iptables -t nat -D PREROUTING -p tcp --dport 81 -j REDIRECT --to-port 80

The health checks on port 81 for this server will quickly fail, and the standard server will be seen as failed. No new session will be sent to this server, and existing clients with a valid cookie will still reach it because the backup server will still be up.

이 서버에 대한 포트 81의 상태 검사는 빠르게 실패하고 표준 서버는 실패한 것으로 표시됩니다. 새 세션이 이 서버로 전송되지 않으며 백업 서버가 계속 작동하기 때문에 유효한 쿠키가 있는 기존 클라이언트는 여전히 세션에 도달합니다.

Now wait as long as you want for the old users to stop using the service, and once you see that the server does not receive any traffic, simply stop it :

이제 이전 사용자가 서비스 사용을 중지할 때까지 기다렸다가 서버에 트래픽이 수신되지 않는 것을 확인하면 중지하면 됩니다.

# /etc/init.d/httpd stop

The associated backup server will in turn fail, and if any client still tries to access this particular server, they will be redispatched to any other valid server because of the "redispatch" option.

그러면 연결된 백업 서버가 실패하고 클라이언트가 여전히 이 특정 서버에 액세스하려고 하면 "redispatch" 옵션으로 인해 다른 유효한 서버로 다시 디스패치됩니다.

This method has an advantage : you never touch the proxy when doing server maintenance. The people managing the servers can make them disappear smoothly.

이 방법에는 장점이 있습니다. 서버 유지 관리를 수행할 때 프록시를 건드리지 않습니다. 서버를 관리하는 사람들은 서버를 원활하게 사라지게 할 수 있습니다.

4.2.1 Variations for operating systems without any firewall software

방화벽 소프트웨어가 없는 운영 체제의 변형

The downside is that you need a redirection solution on the server just for the health-checks. If the server OS does not support any firewall software, this redirection can also be handled by a simple haproxy in tcp mode :

단점은 상태 확인을 위해서만 서버에 리디렉션 솔루션이 필요하다는 것입니다. 서버 OS가 방화벽 소프트웨어를 지원하지 않는 경우 이 리디렉션은 tcp 모드에서 간단한 haproxy로 처리할 수도 있습니다.

    global
        daemon
        quiet
        pidfile /var/run/haproxy-checks.pid
    listen 0.0.0.0:81
        mode tcp
        dispatch 127.0.0.1:80
        contimeout 1000
        clitimeout 10000
        srvtimeout 10000
To start the web service :
웹 서비스를 시작하려면:

# /etc/init.d/httpd start
# haproxy -f /etc/haproxy/haproxy-checks.cfg

To soft-stop the service :

# kill $(</var/run/haproxy-checks.pid)

The port 81 will stop responding and the load-balancer will notice the failure.
포트 81이 응답을 중지하고 로드 밸런서가 오류를 인식합니다.

4.2.2 Centralizing the server management

서버 관리 중앙 집중화

If one finds it preferable to manage the servers from the load-balancer itself, the port redirector can be installed on the load-balancer itself. See the example with iptables below.

로드 밸런서 자체에서 서버를 관리하는 것이 바람직하다고 생각되면 포트 리디렉터를 로드 밸런서 자체에 설치할 수 있습니다. 아래 iptables의 예를 참조하십시오.

Make the servers appear as operational :
서버가 작동 중인 것처럼 보이게 합니다.
# iptables -t nat -A OUTPUT -d 192.168.1.11 -p tcp --dport 81 -j DNAT --to-dest :80
# iptables -t nat -A OUTPUT -d 192.168.1.12 -p tcp --dport 81 -j DNAT --to-dest :80
# iptables -t nat -A OUTPUT -d 192.168.1.13 -p tcp --dport 81 -j DNAT --to-dest :80
# iptables -t nat -A OUTPUT -d 192.168.1.14 -p tcp --dport 81 -j DNAT --to-dest :80

Soft stop one server :
# iptables -t nat -D OUTPUT -d 192.168.1.12 -p tcp --dport 81 -j DNAT --to-dest :80

Another solution is to use the "COMAFILE" patch provided by Alexander Lazic, which is available for download here :
또 다른 해결책은 Alexander Lazic이 제공하는 "COMAFILE" 패치를 사용하는 것입니다. 이 패치는 여기에서 다운로드할 수 있습니다.

http://w.ods.org/tools/haproxy/contrib/

4.2.3 Notes :

  • Never, ever, start a fake service on port 81 for the health-checks, because a real web service failure will not be detected as long as the fake service runs. You must really forward the check port to the real application.
    가짜 서비스가 실행되는 동안에는 실제 웹 서비스 장애가 감지되지 않으므로 상태 확인을 위해 포트 81에서 가짜 서비스를 시작하지 마십시오. 체크 포트를 실제 애플리케이션으로 전달해야 합니다.
  • health-checks will be sent twice as often, once for each standard server, and once for each backup server. All this will be multiplicated by the number of processes if you use multi-process mode. You will have to ensure that all the checks sent to the server do not overload it.
    상태 확인은 각 표준 서버에 대해 한 번, 각 백업 서버에 대해 한 번씩 두 번 더 자주 전송됩니다. 다중 프로세스 모드를 사용하는 경우 이 모든 것이 프로세스 수로 곱해집니다. 서버로 전송되는 모든 수표가 서버에 과부하가 걸리지 않도록 해야 합니다.

4.3 Hot reconfiguration

There are two types of haproxy users :
두 가지 유형의 haproxy 사용자 :

  • those who can never do anything in production out of maintenance periods ;
    유지 보수 기간 외에는 프로덕션에서 아무 것도 할 수 없는 사람
  • those who can do anything at any time provided that the consequences are limited.
    결과가 제한적이라면 언제든지 무엇이든 할 수 있는 사람.

The first ones have no problem stopping the server to change configuration because they got some maintenance periods during which they can break anything. So they will even prefer doing a clean stop/start sequence to ensure everything will work fine upon next reload. Since those have represented the majority of haproxy uses, there has been little effort trying to improve this.

첫 번째 서버는 구성을 변경하기 위해 서버를 중지하는 데 아무런 문제가 없습니다. 어떤 것이든 중단될 수 있는 유지 관리 기간이 있기 때문입니다. 따라서 그들은 다음에 다시 로드할 때 모든 것이 제대로 작동하도록 깨끗한 중지/시작 시퀀스를 수행하는 것을 선호할 것입니다. 그것들이 haproxy 사용의 대부분을 대표했기 때문에 이를 개선하려는 노력은 거의 없었습니다.

However, the second category is a bit different. They like to be able to fix an error in a configuration file without anyone noticing. This can sometimes also be the case for the first category because humans are not failsafe.

그러나 두 번째 범주는 약간 다릅니다. 그들은 아무도 모르게 구성 파일의 오류를 수정할 수 있기를 원합니다. 사람은 절대 안전 장치가 아니기 때문에 첫 번째 카테고리의 경우도 마찬가지입니다.

For this reason, a new hot reconfiguration mechanism has been introduced in version 1.1.34. Its usage is very simple and works even in chrooted environments with lowered privileges. The principle is very simple : upon reception of a SIGTTOU signal, the proxy will stop listening to all the ports. This will release the ports so that a new instance can be started. Existing connections will not be broken at all. If the new instance fails to start, then sending a SIGTTIN signal back to the original processes will restore the listening ports. This is possible without any special privileges because the sockets will not have been closed, so the bind() is still valid. Otherwise, if the new process starts successfully, then sending a SIGUSR1 signal to the old one ensures that it will exit as soon as its last session ends.

이러한 이유로 새로운 핫 재구성 메커니즘이 버전 1.1.34에 도입되었습니다. 사용법은 매우 간단하며 권한이 낮은 chrooted 환경에서도 작동합니다. 원칙은 매우 간단합니다. SIGTTOU 신호를 수신하면 프록시가 모든 포트 수신을 중지합니다. 이렇게 하면 새 인스턴스를 시작할 수 있도록 포트가 해제됩니다. 기존 연결은 전혀 끊어지지 않습니다. 새 인스턴스가 시작되지 않으면 SIGTTIN 신호를 원래 프로세스로 다시 보내면 수신 포트가 복원됩니다. 소켓이 닫히지 않아 bind()가 여전히 유효하기 때문에 특별한 권한 없이 가능합니다. 그렇지 않으면 새 프로세스가 성공적으로 시작되면 이전 프로세스에 SIGUSR1 신호를 보내면 마지막 세션이 종료되는 즉시 종료됩니다.

A hot reconfiguration script would look like this :
핫 재구성 스크립트는 다음과 같습니다 :

  # save previous state
  mv /etc/haproxy/config /etc/haproxy/config.old
  mv /var/run/haproxy.pid /var/run/haproxy.pid.old

  mv /etc/haproxy/config.new /etc/haproxy/config
  kill -TTOU $(cat /var/run/haproxy.pid.old)
  if haproxy -p /var/run/haproxy.pid -f /etc/haproxy/config; then
    echo "New instance successfully loaded, stopping previous one."
    kill -USR1 $(cat /var/run/haproxy.pid.old)
    rm -f /var/run/haproxy.pid.old
    exit 1
  else
    echo "New instance failed to start, resuming previous one."
    kill -TTIN $(cat /var/run/haproxy.pid.old)
    rm -f /var/run/haproxy.pid
    mv /var/run/haproxy.pid.old /var/run/haproxy.pid
    mv /etc/haproxy/config /etc/haproxy/config.new
    mv /etc/haproxy/config.old /etc/haproxy/config
    exit 0
  fi

After this, you can still force old connections to end by sending a SIGTERM to the old process if it still exists :
그런 다음 여전히 존재하는 경우 이전 프로세스에 SIGTERM을 전송하여 이전 연결을 강제로 종료할 수 있습니다.

    kill $(cat /var/run/haproxy.pid.old)
    rm -f /var/run/haproxy.pid.old

Be careful with this as in multi-process mode, some pids might already have been reallocated to completely different processes.
다중 프로세스 모드에서와 같이 주의하십시오. 일부 pid는 이미 완전히 다른 프로세스에 재할당되었을 수 있습니다.


5. Multi-site load-balancing with local preference

로컬 환경 설정을 통한 다중 사이트 로드 밸런싱

5.1 Description of the problem

문제에 대한 설명

Consider a world-wide company with sites on several continents. There are two production sites SITE1 and SITE2 which host identical applications. There are many offices around the world. For speed and communication cost reasons, each office uses the nearest site by default, but can switch to the backup site in the event of a site or application failure. There also are users on the production sites, which use their local sites by default, but can switch to the other site in case of a local application failure.

여러 대륙에 사이트가 있는 세계적인 회사를 생각해 보십시오. 동일한 애플리케이션을 호스팅하는 두 개의 프로덕션 사이트 SITE1 및 SITE2가 있습니다. 전 세계에 많은 사무실이 있습니다. 속도와 통신비 등의 이유로 각 사무실은 기본적으로 가장 가까운 사이트를 사용하지만, 사이트나 애플리케이션 장애 시 백업 사이트로 전환할 수 있습니다. 프로덕션 사이트에도 기본적으로 로컬 사이트를 사용하지만 로컬 애플리케이션 오류가 발생할 경우 다른 사이트로 전환할 수 있는 사용자가 있습니다.
The main constraints are :
주요 제약 조건은 다음과 같습니다 :

  • application persistence : although the application is the same on both sites, there is no session synchronisation between the sites. A failure of one server or one site can cause a user to switch to another server or site, but when the server or site comes back, the user must not switch again.
    응용 프로그램 지속성: 두 사이트에서 응용 프로그램이 동일하더라도 사이트 간에 세션 동기화가 없습니다. 하나의 서버나 사이트의 장애로 인해 사용자는 다른 서버나 사이트로 전환할 수 있지만 서버나 사이트가 다시 돌아오면 사용자는 다시 전환해서는 안 됩니다.
  • communication costs : inter-site communication should be reduced to the minimum. Specifically, in case of a local application failure, every office should be able to switch to the other site without continuing to use the default site.
    통신 비용 : 사이트 간 통신을 최소한으로 줄여야 합니다. 특히, 로컬 애플리케이션 장애가 발생할 경우 모든 사무실은 기본 사이트를 계속 사용하지 않고 다른 사이트로 전환할 수 있어야 합니다.

5.2 Solution 해결책

  • Each production site will have two haproxy load-balancers in front of its application servers to balance the load across them and provide local HA. We will call them "S1L1" and "S1L2" on site 1, and "S2L1" and "S2L2" on site 2. These proxies will extend the application's JSESSIONID cookie to put the server name as a prefix.

    각 프로덕션 사이트에는 응용 프로그램 서버 앞에 두 개의 haproxy 로드 밸런서가 있어 로드 밸런싱을 수행하고 로컬 HA를 제공합니다. 사이트 1에서는 "S1L1" 및 "S1L2", 사이트 2에서는 "S2L1" 및 "S2L2"라고 합니다. 이러한 프록시는 응용 프로그램의 JSESSIONID 쿠키를 확장하여 서버 이름을 접두사로 넣습니다.

  • Each production site will have one front-end haproxy director to provide the service to local users and to remote offices. It will load-balance across the two local load-balancers, and will use the other site's load-balancers as backup servers. It will insert the local site identifier in a SITE cookie for the local load-balancers, and the remote site identifier for the remote load-balancers. These front-end directors will be called "SD1" and "SD2" for "Site Director".

    각 프로덕션 사이트에는 로컬 사용자와 원격 사무실에 서비스를 제공하기 위해 하나의 프런트 엔드 haproxy 디렉터가 있습니다. 두 개의 로컬 로드 밸런서 간에 로드 밸런싱을 수행하고 다른 사이트의 로드 밸런서를 백업 서버로 사용합니다. 로컬 로드 밸런서용 SITE 쿠키에 로컬 사이트 식별자를 삽입하고 원격 로드 밸런서용 원격 사이트 식별자를 삽입합니다. 이러한 프런트 엔드 디렉터는 "사이트 디렉터"의 경우 "SD1" 및 "SD2"라고 합니다.

  • Each office will have one haproxy near the border gateway which will direct local users to their preference site by default, or to the backup site in the event of a previous failure. It will also analyze the SITE cookie, and direct the users to the site referenced in the cookie. Thus, the preferred site will be declared as a normal server, and the backup site will be declared as a backup server only, which will only be used when the primary site is unreachable, or when the primary site's director has forwarded traffic to the second site. These proxies will be called "OP1".."OPXX" for "Office Proxy #XX".

    각 사무실에는 경계 관문 근처에 하나의 haproxy가 있어 기본적으로 로컬 사용자를 기본 설정 사이트로 안내하거나 이전 장애 발생 시 백업 사이트로 안내합니다. 또한 SITE 쿠키를 분석하고 쿠키에서 참조하는 사이트로 사용자를 안내합니다. 따라서 기본 사이트는 일반 서버로 선언하고 백업 사이트는 백업 서버 전용으로 선언하여 기본 사이트에 연결할 수 없거나 기본 사이트의 디렉터가 트래픽을 두 번째 사이트로 전달한 경우에만 사용됩니다. 이러한 프록시는 "Office Proxy #XX"에 대해 "OP1".."OPXX"라고 합니다.

5.3 Network diagram

Note : offices 1 and 2 are on the same continent as site 1, while office 3 is on the same continent as site 3. Each production site can reach the second one either through the WAN or through a dedicated link.
사무실 1과 2는 사이트 1과 같은 대륙에 있고 사무실 3은 사이트 3과 같은 대륙에 있습니다. 각 프로덕션 사이트는 WAN 또는 전용 링크를 통해 두 번째 사이트에 도달할 수 있습니다.

        Office1         Office2                          Office3
         users           users                            users
192.168  # # #   192.168 # # #                            # # #
.1.0/24  | | |   .2.0/24 | | |             192.168.3.0/24 | | |	  
  --+----+-+-+-   --+----+-+-+-                   ---+----+-+-+- 
    |      | .1     |      | .1                      |      | .1
    |    +-+-+      |    +-+-+                       |    +-+-+
    |    |OP1|      |    |OP2|                       |    |OP3|  ...
  ,-:-.  +---+    ,-:-.  +---+                     ,-:-.  +---+
 (  X  )         (  X  )                          (  X  )        
  `-:-'           `-:-'             ,---.          `-:-'         
  --+---------------+------+----~~~(  X  )~~~~-------+---------+-
                           |        `---'                      |    
                           |                                   |    
                 +---+   ,-:-.                       +---+   ,-:-.  
                 |SD1|  (  X  )                      |SD2|  (  X  )
   ( SITE 1 )    +-+-+   `-:-'         ( SITE 2 )    +-+-+   `-:-'
                   |.1     |                           |.1     |    
   10.1.1.0/24     |       |     ,---. 10.2.1.0/24     |       |    
        -+-+-+-+-+-+-+-----+-+--(  X  )------+-+-+-+-+-+-+-----+-+--
         | | | | |   |       |   `---'       | | | | |   |       |
      ...# # # # #   |.11    |.12         ...# # # # #   |.11    |.12
          Site 1   +-+--+  +-+--+              Site 2  +-+--+  +-+--+   
          Local    |S1L1|  |S1L2|              Local   |S2L1|  |S2L2|   
          users    +-+--+  +--+-+              users   +-+--+  +--+-+   
                     |        |	                         |        |     
   10.1.2.0/24    -+-+-+--+--++--      10.2.2.0/24    -+-+-+--+--++--   
                   |.1       |.4                       |.1       |.4
                 +-+-+     +-+-+                     +-+-+     +-+-+    
                 |W11| ~~~ |W14|                     |W21| ~~~ |W24|    
                 +---+     +---+                     +---+     +---+    
              4 application servers               4 application servers
                    on site 1                           on site 2

5.4 Description

5.4.1 Local users

- Office 1 users connect to OP1 = 192.168.1.1
- Office 2 users connect to OP2 = 192.168.2.1
- Office 3 users connect to OP3 = 192.168.3.1
- Site 1 users connect to SD1 = 10.1.1.1
- Site 2 users connect to SD2 = 10.2.1.1

5.4.2 Office proxies

- Office 1 connects to site 1 by default and uses site 2 as a backup.
- Office 2 connects to site 1 by default and uses site 2 as a backup.
- Office 3 connects to site 2 by default and uses site 1 as a backup.

The offices check the local site's SD proxy every 30 seconds, and the remote one every 60 seconds.
사무실에서는 로컬 사이트의 SD 프록시를 30초마다, 원격 사이트는 60초마다 확인합니다.

Configuration for Office Proxy OP1

    listen 192.168.1.1:80
       mode http
       balance roundrobin
       redispatch
       cookie SITE
       option httpchk HEAD / HTTP/1.0
       server SD1 10.1.1.1:80 cookie SITE1 check inter 30000
       server SD2 10.2.1.1:80 cookie SITE2 check inter 60000 backup

Configuration for Office Proxy OP2

    listen 192.168.2.1:80
       mode http
       balance roundrobin
       redispatch
       cookie SITE
       option httpchk HEAD / HTTP/1.0
       server SD1 10.1.1.1:80 cookie SITE1 check inter 30000
       server SD2 10.2.1.1:80 cookie SITE2 check inter 60000 backup

Configuration for Office Proxy OP3

    listen 192.168.3.1:80
       mode http
       balance roundrobin
       redispatch
       cookie SITE
       option httpchk HEAD / HTTP/1.0
       server SD2 10.2.1.1:80 cookie SITE2 check inter 30000
       server SD1 10.1.1.1:80 cookie SITE1 check inter 60000 backup

5.4.3 Site directors ( SD1 and SD2 )

The site directors forward traffic to the local load-balancers, and set a cookie to identify the site. If no local load-balancer is available, or if the local application servers are all down, it will redirect traffic to the remote site, and report this in the SITE cookie. In order not to uselessly load each site's WAN link, each SD will check the other site at a lower rate. The site directors will also insert their client's address so that the application server knows which local user or remote site accesses it.

사이트 디렉터는 트래픽을 로컬 로드 밸런서로 전달하고 쿠키를 설정하여 사이트를 식별합니다. 사용 가능한 로컬 로드 밸런서가 없거나 로컬 애플리케이션 서버가 모두 다운된 경우 트래픽을 원격 사이트로 리디렉션하고 SITE 쿠키에 이를 보고합니다. 각 사이트의 WAN 링크를 쓸데없이 로드하지 않기 위해 각 SD는 낮은 속도로 다른 사이트를 확인합니다. 사이트 디렉터는 클라이언트의 주소도 삽입하여 응용 프로그램 서버가 액세스하는 로컬 사용자 또는 원격 사이트를 알 수 있도록 합니다.

The SITE cookie which is set by these directors will also be understood by the office proxies. This is important because if SD1 decides to forward traffic to site 2, it will write "SITE2" in the "SITE" cookie, and on next request, the office proxy will automatically and directly talk to SITE2 if it can reach it. If it cannot, it will still send the traffic to SITE1 where SD1 will in turn try to reach SITE2.

이러한 디렉터가 설정한 SITE 쿠키는 사무실 프록시에서도 이해합니다. 이것은 SD1이 트래픽을 사이트 2로 전달하기로 결정하면 "SITE" 쿠키에 "SITE2"를 기록하고 다음 요청 시 사무실 프록시가 SITE2에 도달할 수 있는 경우 자동으로 직접 SITE2와 통신하기 때문에 중요합니다. 그렇지 않은 경우 SITE1로 트래픽을 보내고 SD1은 SITE2에 도달하려고 시도합니다.

The load-balancers checks are performed on port 81. As we'll see further, the load-balancers provide a health monitoring port 81 which reroutes to port 80 but which allows them to tell the SD that they are going down soon and that the SD must not use them anymore.

로드 밸런서 검사는 포트 81에서 수행됩니다. 자세히 살펴보겠지만 로드 밸런서는 포트 80으로 다시 라우팅하지만 SD에 곧 다운될 예정이며 SD는 더 이상 사용해서는 안됩니다.

Configuration for SD1

    listen 10.1.1.1:80
       mode http
       balance roundrobin
       redispatch
       cookie SITE insert indirect
       option httpchk HEAD / HTTP/1.0
       option forwardfor
       server S1L1 10.1.1.11:80 cookie SITE1 check port 81 inter 4000
       server S1L2 10.1.1.12:80 cookie SITE1 check port 81 inter 4000
       server S2L1 10.2.1.11:80 cookie SITE2 check port 81 inter 8000 backup
       server S2L2 10.2.1.12:80 cookie SITE2 check port 81 inter 8000 backup

Configuration for SD2

    listen 10.2.1.1:80
       mode http
       balance roundrobin
       redispatch
       cookie SITE insert indirect
       option httpchk HEAD / HTTP/1.0
       option forwardfor
       server S2L1 10.2.1.11:80 cookie SITE2 check port 81 inter 4000
       server S2L2 10.2.1.12:80 cookie SITE2 check port 81 inter 4000
       server S1L1 10.1.1.11:80 cookie SITE1 check port 81 inter 8000 backup
       server S1L2 10.1.1.12:80 cookie SITE1 check port 81 inter 8000 backup

5.4.4 Local load-balancers S1L1, S1L2, S2L1, S2L2

Please first note that because SD1 and SD2 use the same cookie for both servers on a same site, the second load-balancer of each site will only receive load-balanced requests, but as soon as the SITE cookie will be set, only the first LB will receive the requests because it will be the first one to match the cookie.

먼저 SD1과 SD2가 동일한 사이트의 두 서버에 대해 동일한 쿠키를 사용하기 때문에 각 사이트의 두 번째 로드 밸런서는 로드 밸런싱된 요청만 수신하지만 SITE 쿠키가 설정되는 즉시 첫 번째 로드 밸런서만 수신됩니다. LB는 쿠키와 일치하는 첫 번째 요청이기 때문에 요청을 받습니다.

The load-balancers will spread the load across 4 local web servers, and use the JSESSIONID provided by the application to provide server persistence using the new 'prefix' method. Soft-stop will also be implemented as described in section 4 above. Moreover, these proxies will provide their own maintenance soft-stop. Port 80 will be used for application traffic, while port 81 will only be used for health-checks and locally rerouted to port 80. A grace time will be specified to service on port 80, but not on port 81. This way, a soft kill (kill -USR1) on the proxy will only kill the health-check forwarder so that the site director knows it must not use this load-balancer anymore. But the service will still work for 20 seconds and as long as there are established sessions.

로드 밸런서는 4개의 로컬 웹 서버에 로드를 분산하고 애플리케이션에서 제공하는 JSESSIONID를 사용하여 새로운 '접두사' 방법을 사용하여 서버 지속성을 제공합니다. 위의 섹션 4에 설명된 대로 소프트 스톱도 구현됩니다. 또한 이러한 프록시는 자체 유지 관리 소프트 스톱을 제공합니다. 포트 80은 애플리케이션 트래픽에 사용되고 포트 81은 상태 확인에만 사용되며 로컬에서 포트 80으로 다시 라우팅됩니다. 유예 시간은 포트 80에서 서비스하도록 지정되지만 포트 81에서는 지정되지 않습니다. 이런 식으로 프록시의 소프트 킬(kill -USR1)은 사이트 디렉터가 이 로드 밸런서를 더 이상 사용하지 않아야 한다는 것을 알 수 있도록 상태 확인 전달자만 종료합니다. 그러나 서비스는 설정된 세션이 있는 한 20초 동안 계속 작동합니다.

These proxies will also be the only ones to disable HTTP keep-alive in the chain, because it is enough to do it at one place, and it's necessary to do it with 'prefix' cookies.

이러한 프록시는 체인에서 HTTP 연결 유지를 비활성화하는 유일한 프록시이기도 합니다. 한 곳에서 수행하는 것으로 충분하고 '접두사' 쿠키를 사용하여 수행해야 하기 때문입니다.

Configuration for S1L1/S1L2

    listen 10.1.1.11:80 # 10.1.1.12:80 for S1L2
       grace 20000  # don't kill us until 20 seconds have elapsed
       mode http
       balance roundrobin
       cookie JSESSIONID prefix
       option httpclose
       option forwardfor
       option httpchk HEAD / HTTP/1.0
       server W11 10.1.2.1:80 cookie W11 check port 81 inter 2000
       server W12 10.1.2.2:80 cookie W12 check port 81 inter 2000
       server W13 10.1.2.3:80 cookie W13 check port 81 inter 2000
       server W14 10.1.2.4:80 cookie W14 check port 81 inter 2000

       server B11 10.1.2.1:80 cookie W11 check port 80 inter 4000 backup
       server B12 10.1.2.2:80 cookie W12 check port 80 inter 4000 backup
       server B13 10.1.2.3:80 cookie W13 check port 80 inter 4000 backup
       server B14 10.1.2.4:80 cookie W14 check port 80 inter 4000 backup

    listen 10.1.1.11:81 # 10.1.1.12:81 for S1L2
       mode tcp
       dispatch 10.1.1.11:80  # 10.1.1.12:80 for S1L2

Configuration for S2L1/S2L2

    listen 10.2.1.11:80 # 10.2.1.12:80 for S2L2
       grace 20000  # don't kill us until 20 seconds have elapsed
       mode http
       balance roundrobin
       cookie JSESSIONID prefix
       option httpclose
       option forwardfor
       option httpchk HEAD / HTTP/1.0
       server W21 10.2.2.1:80 cookie W21 check port 81 inter 2000
       server W22 10.2.2.2:80 cookie W22 check port 81 inter 2000
       server W23 10.2.2.3:80 cookie W23 check port 81 inter 2000
       server W24 10.2.2.4:80 cookie W24 check port 81 inter 2000

       server B21 10.2.2.1:80 cookie W21 check port 80 inter 4000 backup
       server B22 10.2.2.2:80 cookie W22 check port 80 inter 4000 backup
       server B23 10.2.2.3:80 cookie W23 check port 80 inter 4000 backup
       server B24 10.2.2.4:80 cookie W24 check port 80 inter 4000 backup

    listen 10.2.1.11:81 # 10.2.1.12:81 for S2L2
       mode tcp
       dispatch 10.2.1.11:80  # 10.2.1.12:80 for S2L2

5.5 Comments

Since each site director sets a cookie identifying the site, remote office users will have their office proxies direct them to the right site and stick to this site as long as the user still uses the application and the site is available. Users on production sites will be directed to the right site by the site directors depending on the SITE cookie.

각 사이트 디렉터는 사이트를 식별하는 쿠키를 설정하기 때문에 원격 사무실 사용자는 사무실 프록시가 사용자를 올바른 사이트로 안내하고 사용자가 애플리케이션을 계속 사용하고 사이트를 사용할 수 있는 한 이 사이트를 고수하게 됩니다. 프로덕션 사이트의 사용자는 SITE 쿠키에 따라 사이트 관리자가 올바른 사이트로 안내합니다.

If the WAN link dies on a production site, the remote office users will not see their site anymore, so they will redirect the traffic to the second site. If there are dedicated inter-site links as on the diagram above, the second SD will see the cookie and still be able to reach the original site. For example :

프로덕션 사이트에서 WAN 링크가 끊어지면 원격 사무실 사용자는 자신의 사이트를 더 이상 볼 수 없으므로 트래픽을 두 번째 사이트로 리디렉션합니다. 위의 다이어그램과 같이 전용 사이트 간 링크가 있는 경우 두 번째 SD는 쿠키를 보고 여전히 원래 사이트에 연결할 수 있습니다. 예를 들면 :

Office 1 user sends the following to OP1 :

  GET / HTTP/1.0
  Cookie: SITE=SITE1; JSESSIONID=W14~123;

OP1 cannot reach site 1 because its external router is dead. So the SD1 server is seen as dead, and OP1 will then forward the request to SD2 on site 2, regardless of the SITE cookie.

OP1은 외부 라우터가 작동하지 않기 때문에 사이트 1에 연결할 수 없습니다. 따라서 SD1 서버는 죽은 것으로 간주되고 OP1은 SITE 쿠키에 관계없이 요청을 사이트 2의 SD2로 전달합니다.

SD2 on site 2 receives a SITE cookie containing "SITE1". Fortunately, it can reach Site 1's load balancers S1L1 and S1L2. So it forwards the request so S1L1 (the first one with the same cookie).

사이트 2의 SD2는 "SITE1"이 포함된 SITE 쿠키를 수신합니다. 다행히 사이트 1의 로드 밸런서 S1L1 및 S1L2에 도달할 수 있습니다. 따라서 요청을 S1L1(동일한 쿠키가 있는 첫 번째 요청)로 전달합니다.

S1L1 (on site 1) finds "W14" in the JSESSIONID cookie, so it can forward the request to the right server, and the user session will continue to work. Once the Site 1's WAN link comes back, OP1 will see SD1 again, and will not route through SITE 2 anymore.

S1L1(사이트 1)은 JSESSIONID 쿠키에서 "W14"를 찾아 올바른 서버로 요청을 전달할 수 있으며 사용자 세션은 계속 작동합니다. 사이트 1의 WAN 링크가 복구되면 OP1은 SD1을 다시 보게 되며 더 이상 사이트 2를 통해 라우팅되지 않습니다.

However, when a new user on Office 1 connects to the application during a site 1 failure, it does not contain any cookie. Since OP1 does not see SD1 because of the network failure, it will direct the request to SD2 on site 2, which will by default direct the traffic to the local load-balancers, S2L1 and S2L2. So only initial users will load the inter-site link, not the new ones.

그러나 Office 1의 새 사용자가 사이트 1 장애 중에 애플리케이션에 연결하면 쿠키가 포함되지 않습니다. OP1은 네트워크 장애로 인해 SD1을 보지 못하므로 사이트 2의 SD2로 요청을 보내며 기본적으로 로컬 로드 밸런서인 S2L1 및 S2L2로 트래픽을 보냅니다. 따라서 신규 사용자가 아닌 초기 사용자만 사이트 간 링크를 로드합니다.


6. Source balancing

Sometimes it may reveal useful to access servers from a pool of IP addresses instead of only one or two. Some equipment (NAT firewalls, load-balancers) are sensible to source address, and often need many sources to distribute the load evenly amongst their internal hash buckets.

때로는 하나 또는 두 개가 아닌 IP 주소 풀에서 서버에 액세스하는 것이 유용할 수 있습니다. 일부 장비(NAT 방화벽, 로드 밸런서)는 소스 주소에 민감하며 종종 내부 해시 버킷 간에 부하를 고르게 분산하기 위해 많은 소스가 필요합니다.

To do this, you simply have to use several times the same server with a different source. Example :
이렇게 하려면 소스가 다른 동일한 서버를 여러 번 사용하기만 하면 됩니다. 예 :

    listen 0.0.0.0:80
       mode tcp
       balance roundrobin
       server from1to1 10.1.1.1:80 source 10.1.2.1
       server from2to1 10.1.1.1:80 source 10.1.2.2
       server from3to1 10.1.1.1:80 source 10.1.2.3
       server from4to1 10.1.1.1:80 source 10.1.2.4
       server from5to1 10.1.1.1:80 source 10.1.2.5
       server from6to1 10.1.1.1:80 source 10.1.2.6
       server from7to1 10.1.1.1:80 source 10.1.2.7
       server from8to1 10.1.1.1:80 source 10.1.2.8

7. Managing high loads on application servers

애플리케이션 서버의 높은 부하(負荷) 관리

One of the roles often expected from a load balancer is to mitigate the load on the servers during traffic peaks. More and more often, we see heavy frameworks used to deliver flexible and evolutive web designs, at the cost of high loads on the servers, or very low concurrency. Sometimes, response times are also rather high. People developing web sites relying on such frameworks very often look for a load balancer which is able to distribute the load in the most evenly fashion and which will be nice with the servers.

로드 밸런서에서 종종 기대되는 역할 중 하나는 트래픽 피크 동안 서버의 로드를 완화하는 것입니다. 점점 더 자주 우리는 유연하고 발전적인 웹 디자인을 제공하기 위해 서버의 부하가 높거나 동시성이 매우 낮은 대가로 무거운 프레임워크를 사용하는 것을 봅니다. 때로는 응답 시간도 다소 높습니다. 이러한 프레임워크에 의존하는 웹사이트를 개발하는 사람들은 로드를 가장 고르게 분산할 수 있고 서버에 적합한 로드 밸런서를 찾는 경우가 많습니다.

There is a powerful feature in haproxy which achieves exactly this : request queueing associated with concurrent connections limit.

정확히 이것을 달성하는 haproxy의 강력한 기능이 있습니다: 동시 연결 제한과 관련된 요청 대기열.

Let's say you have an application server which supports at most 20 concurrent requests. You have 3 servers, so you can accept up to 60 concurrent HTTP connections, which often means 30 concurrent users in case of keep-alive (2 persistent connections per user).

최대 20개의 동시 요청을 지원하는 애플리케이션 서버가 있다고 가정해 보겠습니다. 3개의 서버가 있으므로 최대 60개의 동시 HTTP 연결을 허용할 수 있습니다. 이는 연결 유지(keep-alive)의 경우 동시 사용자가 30명인 경우가 많습니다 (사용자당 2개의 영구 연결).

Even if you disable keep-alive, if the server takes a long time to respond, you still have a high risk of multiple users clicking at the same time and having their requests unserved because of server saturation. To work around the problem, you increase the concurrent connection limit on the servers, but their performance stalls under higher loads.

연결 유지를 비활성화하더라도 서버가 응답하는 데 시간이 오래 걸리면 서버 포화로 인해 여러 사용자가 동시에 클릭하고 요청을 처리하지 못할 위험이 여전히 높습니다. 이 문제를 해결하려면 서버의 동시 연결 제한을 늘리지만, 부하가 높을 경우 성능이 저하됩니다.

The solution is to limit the number of connections between the clients and the servers. You set haproxy to limit the number of connections on a per-server basis, and you let all the users you want connect to it. It will then fill all the servers up to the configured connection limit, and will put the remaining connections in a queue, waiting for a connection to be released on a server.

해결 방법은 클라이언트와 서버 간의 연결 수를 제한하는 것입니다. 서버별로 연결 수를 제한하도록 haproxy를 설정하고 원하는 모든 사용자가 연결할 수 있도록 합니다. 그런 다음 구성된 연결 제한까지 모든 서버를 채우고 나머지 연결을 대기열에 넣고 서버에서 연결이 해제되기를 기다립니다.

This ensures five essential principles :
이것은 다섯 가지 필수 원칙을 보장합니다.

  • all clients can be served whatever their number without crashing the servers, the only impact it that the response time can be delayed.
    모든 클라이언트는 서버 충돌(crashing) 없이 번호에 상관없이 서비스를 받을 수 있으며, 유일한 영향은 응답 시간이 지연될 수 있습니다.
  • the servers can be used at full throttle without the risk of stalling, and fine tuning can lead to optimal performance.
    정지 위험 없이 서버를 최대 속도로 사용할 수 있으며 미세 조정을 통해 최적의 성능을 얻을 수 있습니다.
  • response times can be reduced by making the servers work below the congestion point, effectively leading to shorter response times even under moderate loads.
    서버가 정체 지점 아래에서 작동하도록 하여 응답 시간을 줄일 수 있으며 중간 정도의 부하에서도 효과적으로 응답 시간을 단축할 수 있습니다.
  • no domino effect when a server goes down or starts up. Requests will be queued more or less, always respecting servers limits.
    서버가 다운되거나 시작될 때 도미노 효과가 없습니다. 요청은 항상 서버 제한을 준수하면서 어느 정도 대기열에 추가됩니다.
  • it's easy to achieve high performance even on memory-limited hardware. Indeed, heavy frameworks often consume huge amounts of RAM and not always all the CPU available. In case of wrong sizing, reducing the number of concurrent connections will protect against memory shortages while still ensuring optimal CPU usage.
    메모리가 제한된 하드웨어에서도 쉽게 고성능을 달성할 수 있습니다. 실제로 무거운 프레임워크는 종종 엄청난 양의 RAM을 사용하며 항상 모든 CPU를 사용할 수 있는 것은 아닙니다. 크기 조정이 잘못된 경우 동시 연결 수를 줄이면 최적의 CPU 사용을 보장하면서 메모리 부족을 방지할 수 있습니다.

Example :

HAProxy is installed in front of an application servers farm. It will limit the concurrent connections to 4 per server (one thread per CPU), thus ensuring very fast response times.
HAProxy는 애플리케이션 서버 팜 앞에 설치됩니다. 동시 연결을 서버당 4개(CPU당 스레드 1개)로 제한하여 매우 빠른 응답 시간을 보장합니다.

  192.168.1.1   192.168.1.11-192.168.1.13   192.168.1.2
 -------+-------------+-----+-----+------------+----
        |             |     |     |           _|_db
     +--+--+        +-+-+ +-+-+ +-+-+        (___)
     | LB1 |        | A | | B | | C |        (___)
     +-----+        +---+ +---+ +---+        (___)
     haproxy       3 application servers
                   with heavy frameworks

Config on haproxy (LB1) :

    listen appfarm 192.168.1.1:80
       mode http
       maxconn 10000
       option httpclose
       option forwardfor
       balance roundrobin
       cookie SERVERID insert indirect
       option httpchk HEAD /index.html HTTP/1.0
       server railsA 192.168.1.11:80 cookie A maxconn 4 check
       server railsB 192.168.1.12:80 cookie B maxconn 4 check
       server railsC 192.168.1.13:80 cookie C maxconn 4 check
       contimeout 60000

Description :

The proxy listens on IP 192.168.1.1, port 80, and expects HTTP requests. It can accept up to 10000 concurrent connections on this socket. It follows the roundrobin algorithm to assign servers to connections as long as servers are not saturated.

프록시는 IP 192.168.1.1, 포트 80에서 수신하고 HTTP 요청을 예상합니다. 이 소켓에서 최대 10000개의 동시 연결을 허용할 수 있습니다. 서버가 포화되지 않는 한 서버를 연결에 할당하는 라운드 로빈 알고리즘을 따릅니다.

It allows up to 4 concurrent connections per server, and will queue the requests above this value. The "contimeout" parameter is used to set the maximum time a connection may take to establish on a server, but here it is also used to set the maximum time a connection may stay unserved in the queue (1 minute here).

서버당 최대 4개의 동시 연결을 허용하고, 이 값 이상의 요청을 대기열에 넣습니다. "contimeout" 매개변수는 서버에서 연결을 설정하는 데 걸릴 수 있는 최대 시간을 설정하는 데 사용되지만 여기서는 연결이 대기열에서 제공되지 않는 최대 시간을 설정하는 데도 사용됩니다(여기서는 1분).

If the servers can each process 4 requests in 10 ms on average, then at 3000 connections, response times will be delayed by at most :
서버가 각각 평균 10ms에 4개의 요청을 처리할 수 있는 경우 3000개의 연결에서 응답 시간은 최대 지연됩니다.

3000 / 3 servers / 4 conns * 10 ms = 2.5 seconds

Which is not that dramatic considering the huge number of users for such a low number of servers.
그렇게 적은 수의 서버에 엄청난 수의 사용자를 고려하면 그렇게 극적인 것은 아닙니다.

When connection queues fill up and application servers are starving, response times will grow and users might abort by clicking on the "Stop" button. It is very undesirable to send aborted requests to servers, because they will eat CPU cycles for nothing.

연결 대기열이 가득 차고 응용 프로그램 서버가 부족하면 응답 시간이 길어지고 사용자는 "중지" 버튼을 클릭하여 중단할 수 있습니다. 중단된 요청을 서버에 보내는 것은 CPU 주기를 공짜로 잡아먹기 때문에 매우 바람직하지 않습니다.

An option has been added to handle this specific case : "option abortonclose". By specifying it, you tell haproxy that if an input channel is closed on the client side AND the request is still waiting in the queue, then it is highly likely that the user has stopped, so we remove the request from the queue before it will get served.

이 특정 사례를 처리하기 위해 "option abortonclose" 옵션이 추가되었습니다. 이를 지정함으로써 haproxy에게 입력 채널이 클라이언트 측에서 닫히고 요청이 여전히 대기열에서 대기 중인 경우 사용자가 중지했을 가능성이 높으므로, 요청이 처리되기 전에 대기열에서 요청을 제거합니다.

Managing unfair response times

불공정한 응답 시간 관리

Sometimes, the application server will be very slow for some requests (eg: login page) and faster for other requests. This may cause excessive queueing of expectedly fast requests when all threads on the server are blocked on a request to the database. Then the only solution is to increase the number of concurrent connections, so that the server can handle a large average number of slow connections with threads left to handle faster connections.

때때로 응용 프로그램 서버는 일부 요청(예: 로그인 페이지)에 대해서는 매우 느리고 다른 요청에 대해서는 더 빠릅니다. 이로 인해 데이터베이스에 대한 요청에서 서버의 모든 스레드가 차단될 때 예상되는 빠른 요청의 과도한 대기열이 발생할 수 있습니다. 그런 다음 유일한 해결책은 동시 연결 수를 늘리는 것입니다. 그러면 서버는 더 빠른 연결을 처리하기 위해 남아 있는 스레드를 사용하여 평균적으로 많은 수의 느린 연결을 처리할 수 있습니다.

But as we have seen, increasing the number of connections on the servers can be detrimental to performance (eg: Apache processes fighting for the accept() lock). To improve this situation, the "minconn" parameter has been introduced. When it is set, the maximum connection concurrency on the server will be bound by this value, and the limit will increase with the number of clients waiting in queue, till the clients connected to haproxy reach the proxy's maxconn, in which case the connections per server will reach the server's maxconn. It means that during low-to-medium loads, the minconn will be applied, and during surges the maxconn will be applied. It ensures both optimal response times under normal loads, and availability under very high loads.

그러나 우리가 본 것처럼 서버의 연결 수를 늘리면 성능이 저하될 수 있습니다 (예: Apache 프로세스가 accept()를 잠그려고 싸우는 경우). 이 상황을 개선하기 위해 "minconn" 매개변수가 도입되었습니다. 설정되면 서버의 최대 연결 동시성은 이 값에 의해 제한되며 haproxy에 연결된 클라이언트가 프록시의 maxconn에 도달할 때까지 대기열에서 대기 중인 클라이언트 수에 따라 제한이 증가합니다. 서버는 서버의 maxconn에 도달합니다. 즉, 중저부하에서는 minconn이 적용되고 높은 부하(surges)에서는 maxconn이 적용됩니다. 일반 부하에서 최적의 응답 시간과 매우 높은 부하에서 가용성을 모두 보장합니다.

Example :

    listen appfarm 192.168.1.1:80
       mode http
       maxconn 10000
       option httpclose
       option abortonclose
       option forwardfor
       balance roundrobin
       # The servers will get 4 concurrent connections under low
       # loads, and 12 when there will be 10000 clients.
       server railsA 192.168.1.11:80 minconn 4 maxconn 12 check
       server railsB 192.168.1.12:80 minconn 4 maxconn 12 check
       server railsC 192.168.1.13:80 minconn 4 maxconn 12 check
       contimeout 60000

Email 답글이 올라오면 이메일로 알려드리겠습니다.