Quartz와 관련된 ORACLE RAC 구성 테스트가 필요해서 설치해 보기로 하였다.

OTN 라이선스에 동의하면 ENT 버전을 다운받아 개발용으로 설치하여 사용할 수 있다.


설치 

아래 블로그를 따라하면 누구든지 설치 할 수 있다. (감사감사)

http://oraschool.tistory.com/7

참조)

https://oracle-base.com/articles/12c/oracle-db-12cr1-rac-installation-on-oracle-linux-6-using-virtualbox


블로그 내용대로 설치를 했다면 host에서 사용하기 위해서 몇가지 작업이 필요하다. 


1. 네트워크 

 - host에서 RAC 망으로 접근할 수가 없어 appication을 구동할 수 없다.

생각나는 방법들

1. 개발환경을 위한 VM을 추가하고 같은 public ip 대역을 사용한다. 

2. NAT의 port fowarding을 이용한다. (이게 더 편해 보인다.)


각 RAC 서버 네트워크 설정을 수정한다.


pub는 1개의 instance에 접속하기 위한 것이고 

vip는 jdbc url을 사용하기 위한 값이다. 

host ip를 127.0.0.1 을 사용하면 본인 host만 접속이 가능하고 공인아이피가 있다면 다른 PC에서 접속이 가능하다. (빙화벽이 열려있는 경우)


rac1


rac2


접속 방법 (sql developer)

instance별


jdbc thin


2. encoding 처리

설치 가이드 블로그의 내용을 그대로 잘 따라서 했다면 한글데이터가 깨진다. 

instance 설치할때 encoding 설정을 하면 문제가 없지만 이미 설치 했다며 encoding을 바꿔야 한다. 


1. 인코딩 확인 

 select * from nls_database_parameters where parameter like '%CHARACTERSET%';

 select VALUE$ from sys.props$ where name='NLS_LANGUAGE';


update 

http://m.blog.naver.com/meldin/60090587605 (참고)

1. 모든 instance들을 shutdown 한다.


    - Node1 : # sqlplus "/ as sysdba"

    - Node1 : SQL> shutdown immediate

    - Node2 : # sqlplus "/ as sysdba"

    - Node2 : SQL> shutdown immediate


2. Node1에서 initNode1.ora 파일에서 CLUSTER_DATABASE 파라미터를 FALSE로 변경한다.

ALTER SYSTEM SET CLUSTER_DATABASE=FALSE SCOPE=SPFILE;


3. Node1에서 Exclusive 모드로 DB를 마운트한다.

   - SQL> startup mount exclusive


4. 다음의 명령어들을 실행한다.

   - SQL> alter system enable restricted session;

   - SQL> alter system set job_queue_processes = 0; 

   - SQL> alter system set aq_tm_processes = 0; 

   - SQL> alter database open;


5. 캐릭터 셋을 변경한다.

   - ALTER DATABASE CHARACTER SET INTERNAL_USE UTF8;

   - ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8;


6. Node1에서 initNode1.ora 파일에서 CLUSTER_DATABASE 파라미터를 다시 TRUE로 변경한다.

   - ALTER SYSTEM SET CLUSTER_DATABASE=TRUE SCOPE=SPFILE;


7. 디비를 shutdown 한다.

   - SQL> shutdown immediate


8. 모든 Node에서 DB를 startup한다.

    - srvctl start instance -d ORA12C -i ORA12C1

    - srvctl start instance -d ORA12C -i ORA12C2


변경 확인 

쿼리결과의 모든 인코딩이 동일하면 된다.

select

 distinct(nls_charset_name(charsetid)) CHARACTERSET,
 decode(type#, 1, decode(charsetform, 1, 'VARCHAR2', 2, 'NVARCHAR2','UNKOWN'),
 9, decode(charsetform, 1, 'VARCHAR', 2, 'NCHAR VARYING', 'UNKOWN'),
 96, decode(charsetform, 1, 'CHAR', 2, 'NCHAR', 'UNKOWN'),
 112, decode(charsetform, 1, 'CLOB', 2, 'NCLOB', 'UNKOWN')) TYPES_USED_IN
from sys.col$
where charsetform in (1,2) and type# in (1, 9, 96, 112);

 


Posted by 마법수정화살
,

목표: 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 마법수정화살
,