목표: apache mod_proxy를 통한 부드러운 failover 


검색해봐도 마땅히 참고할 만한게 없었다.

graceful failover

seamless failover


느낀점은

L4처럼 부드럽게 넘어가는 failover를 하기에는 apache로는 무리가 있다. 

failover는 HAproxy사용하는 것이 좋은것 같다.


failover를 위해 몇가지 load balancing  옵션을 가지고 테스트를 해보았다.


apache의 failover 방식


health check 를 통해 failover 하는 방법을 찾았지만 apache에는 아직 없다. 


apache는 connection 을 만들때 마다 node를 확인하여 failover 하도록 되어있다. 

그래서 아래와 같은 옵션들과 설정도 통하지 않는다. 


BalancerMember의 ping 옵션

mod_proxy_hcheck 사용

https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html

https://httpd.apache.org/docs/2.4/mod/mod_proxy_hcheck.html


기본적으로 load balnacing을 구성하고 한쪽 서버를 down시키면 어떻게 될까?

(Apache mod_proxy를 이용한 reverse proxy와 로드밸런싱 참고)



1번 서버를 죽인다. 

2번 서버에 붙었던 사용자들은 계속 서비스가 된다.

1번 서버에 붙었던 사용자들은 한참을 기다리게 되고 (60초 이상) 2번 서버로 연결되게 된다.

 

failover가 되기 위해서는 down된 node를 알고 요청을 보내지 않아야 한다. 

위에 쓴것 처럼 apache는 connection 마다 node의 status를 확인한다. 


사용중에 서버가 내려가면 서버의 요청을 계속 기다리게 되고 기본 timeout 시간 60초 후에 500, 503 응답을 주고 해당 node는 error status가 된다. 


mod_proxy.c

if (access_status == OK

                || apr_table_get(r->notes, "proxy-error-override"))

            break;

        else if (access_status == HTTP_INTERNAL_SERVER_ERROR) {

            /* Unrecoverable server error.

             * We can not failover to another worker.

             * Mark the worker as unusable if member of load balancer

             */

            if (balancer

                && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {

                worker->s->status |= PROXY_WORKER_IN_ERROR;

                worker->s->error_time = apr_time_now();

            }

            break;

        }

        else if (access_status == HTTP_SERVICE_UNAVAILABLE) {

            /* Recoverable server error.

             * We can failover to another worker

             * Mark the worker as unusable if member of load balancer

             */

            if (balancer

                && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {

                worker->s->status |= PROXY_WORKER_IN_ERROR;

                worker->s->error_time = apr_time_now();

            }

        }


서비스할 수 없는 서버의 상태는 다음과 같다.

 

서비스중지: connection 실패 

어플리케이션 에러 : 500 번대 에러

인증실패 등 client 문제 : 400 번대 에러


httpd 에서는 500, 502 에러는 서비스할 수 없는 상태로 보고 node의 status를 error 상태로 바꾼다.


문제는 connection이 이미 연결된 worker들이 error status 의 node로 request를 보내는데 있다. 

timeout(기본 60초) 시간까지 응답을 기다리고 해당 node는 error status 가 된다.

이후에 error상태의 node로는 retry시간 까지 요청을 보내지 않고 다른 서버로 요청을 보낸다.


사용자는 서버가 내려갔는지도 느낄수 없게 부드러운 failover를 apache httpd를 통해 하고 싶었다. 

apache 문서에는 session복제가 안되는 환경에서 sticky 세션을 사용하려면 failover 하지 않도록 권장하고 있다. ProxySet nofailover=On


If set to On, the session will break if the worker is in error state or disabled. Set this value to On if backend servers do not support session replication.



그러기 위해서는 성능을 생각하지 않고 worker들이 요청할 때마다 connection을 생성하도록 하고 그때 connectiontimeout으로 체크하게 하면 될것이라고 생각했다.


prefork를 사용하고 있었다. ({APACHE_HOME}/bin/httpd -V 로 확인할 수 있다.)


conf/extra/httpd-mpm.conf 

<IfModule mpm_prefork_module>

    StartServers                 1

    MinSpareServers           1

    MaxSpareServers           1

    MaxRequestWorkers      250

    MaxConnectionsPerChild   0

</IfModule>

 

아래 값을 모두 1로 주면 요청할 때마다 프로세스가 생기고 그때 connection을 생성하면서 node의 연결상태를 체크하여 failover가 될것이라고 기대 했다.

 

MinSpareServers

MaxSpareServers


잘 안된다. 

(추가)

prefork 방식은 아래 설정을 추가한다. (connection 유지안되도록 하는 설정값)

SetEnv force-proxy-request-1.0 1 SetEnv proxy-nokeepalive 1



mpm을 worker로 다시 컴파일 해보기로 했다.

./configure --prefix=/usr/local/apache2-lb --enable-proxy --enable-proxy-balancer --with-mpm=worker --with-pcre=/usr/local/pcre --with-apr=/usr/local/apr


conf/extra/http-mpm.conf

<IfModule mpm_worker_module>

    StartServers             3

    MinSpareThreads          1

    MaxSpareThreads          1

    ThreadsPerChild         25

    MaxRequestWorkers      400

    MaxConnectionsPerChild   0

</IfModule>


min, max를 1로 설정


httpd.conf

<Proxy balancer://mycluster>

    # WAS1

    BalancerMember http://211.63.24.75:19090 route=1 connectiontimeout=1


    # WAS2

    BalancerMember http://211.63.24.75:29090 route=2 connectiontimeout=1


    ProxySet lbmethod=byrequests

    ProxySet stickysession=ROUTEID


</Proxy>


1번 서버를 내리면 1~2 초 후에 다른 서버로 이동 되는것을 확인할 수 있다. 

session clustinrg 환경을 구성했다면 stateless 한 서비스라면 사용자는 모르고 지나갈 수 있다. 


위에 설정에서 timeout을 넣지않고 connectiontimeout 을 넣은 이유는 응답이 오래 걸리는 서비스가 있을 수 있기 때문이다. 


해당 설정을 timeout=1 로 해도 똑같이 동작하는 것으로 보일수 있다. 

connectiontimeout의 기본값은 timeout 값을 사용하기 때문이다. 


하지만 두가지 옵션의 차이가 있다.

1. connectiontimeout 는 connection이 생성될 때 timeout시간을 설정한다. 1초이상 연결되지 않으면 node를 error status로 바꾼다.

2. timeout은 webserver에서 WAS로 요청이 간 후에 timeout 설정 이다. 

응답이 오래 걸리는 서비스도 timeout 옵션으로 인해 응답은 실패하고 해당 node는 error status가 된다.


1번 설정을 하고 5초 sleep하는 서비스를 호출했을때 다른서버로 요청이 가지 않고 원래 서버로 요청되는것을 확인할 수 있다.

 

부족하지만 apache로도 어느정도 만족할 만한 failover를 할수 있었다. 


 하지만 실제로 서비스 하기위해서는 connection 생성의 오버헤드를 고려해야 한다. 

- apache 에서 권장하는 방법은 아니므로 서비스 구조와 결함 발생 가능성은 없는지 검토가 필요하다.

- 이중화 하는 이유는 크게 성능과 고가용성(유지보수) 인데 성능테스트를 통해 검증을 해봐야 한다.


'webserver' 카테고리의 다른 글

Apache mod_proxy를 이용한 reverse proxy와 로드밸런싱  (0) 2016.11.30
Posted by 마법수정화살
,

목표 apache를 이용한 로드밸런싱


Apache 최신버전 컴파일 (2.4.23 released 2016-07-05)


./configure --prefix=/usr/local/apache2-lb --enable-proxy --enable-proxy-balancer --with-pcre=/usr/local/pcre --with-apr=/usr/local/apr


--enable-proxy 가 있으면 proxy_http로 추가된다.

--enable-proxy-balancer 있어야 loadbalancer를 사용할 수 있다.


http.conf 

## 주석해제 


LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so

LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so

## 추가

ProxyRequests Off [각주:1]

# proxy 권한 설정 - 필요한 경우 수정
<Proxy *>
Order deny,allow
Allow from all
</Proxy>

#sticky session을 위한 cookie 설정  
Header add Set-Cookie "ROUTEID=route.%{BALANCER_WORKER_ROUTE}e; path=/;" env=BALANCER_ROUTE_CHANGED[각주:2]

#balancer 정의 이름은 mycluster
<Proxy balancer://mycluster>
# WAS1
BalancerMember http://192.168.0.2:8080 route=1
# WAS2
BalancerMember http://192.168.0.3:8080 route=2

ProxySet lbmethod=byrequests[각주:3]
ProxySet stickysession=ROUTEID

</Proxy>

ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
ProxyPreserveHost On[각주:4]

# balancer 모니터링 페이지
ProxyPass /balancer-manager !

<Location /balancer-manager>
    SetHandler balancer-manager
</Location>


1번 서버 : 192.168.0.2

2번 서버 : 192.168.0.3


요청 순서대로 각서버로 연결되며 한번 연결되어 ROUTEID 쿠키가 set 되면 해당 서버로만 요청을 하게 된다. 

session을 사용하는 어플리케이션도 처음 접속한 서버로 계속 접속하게 되어 세션을 유지 할 수 있다. 

request header를 보면 어느쪽 서버로 요청이 가는지 알 수 있다. 아래 header를 보면 2번 서버로 요청이 가는것을 볼 수 있다.


  1. GET /error.html HTTP/1.1 Host: 192.168.0.5 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Referer: http://192.168.0.5/ Accept-Encoding: gzip, deflate, sdch Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.6,en;q=0.4 Cookie: ROUTEID=route.2 If-Modified-Since: Fri, 11 Nov 2016 07:07:11 GMT


http://[IP]/balancer-manager 페이지로 접근하면 상태페이지를 확인할 수 있다.

실제 사용하려면 접근권한을 반드시 주어 관리자만 확인할 수 있도록 한다. - (설정을 바꿔 서비스를 중단시킬수 있음. )



  1. reverse proxy를 사용하면 Off 로 설정해야 한다. [본문으로]
  2. BALANCER_WORKER_ROUTE -> 각 멤버의 route 번호를 저장한다. env=BALANCER_ROUTE_CHANGED -> 현재 요청된 route번호와 BALANCER_WORKER_ROUTE가 다른경우 1을 넣는다. [본문으로]
  3. 로드밸런싱 방법, byrequests (요청별 분배), bytraffic (byte 트래픽 가중치 분배) bybusyness (보류중 요청 분배) [본문으로]
  4. Use incoming Host HTTP request header for proxy request 웹서버에 요청된 header를 proxy request에 사용 [본문으로]

'webserver' 카테고리의 다른 글

apache mod_proxy를 이용한 부드러운 failover  (0) 2016.11.30
Posted by 마법수정화살
,

windows를 새로 설치 했는데 

바탕화면에서 우클릭이 느리다. 폴더에서도 느리다. 

우클릭을 습관처럼 하다보니 답답하다.. 


여러가지 원인이 있을수 있지만 느릴만한 환경이 아닌데 느리다면 2가지 원인이 있을수 있다.


1. context메뉴에 연결된 어플리케이션의 문제

2. context메뉴에 연결된 어플리케이션과 관련된 네트워크 문제


ShellExView 라는 프로그램으로 context메뉴를 관리해 보자.


옵션 항목을 아래와 같이 설정



그래픽 카드, 카스처퍼스키 등등 필요없는 메뉴를 disable 했다. 



그리고 재부팅...

빠르다 굿




참고

http://www.winhelponline.com/xp/slowrightclick.htm

Posted by 마법수정화살
,