(2). Apache의 부하분산 및 세션공유 설정 상세(mod_jk + mod_cluster)
1. Apache 설정 전체 플로우
2. 가상 호스트 설정(/etc/httpd/conf/httpd.conf)
#
# [ Env ]
#
# favicon.ico : 404 Not log
SetEnvIf Request_URl "favicon.ico" dontlog=1
#
# If mod_headers module is included, we will disable the Server response header totally
#
ServerSignature Off
# 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', or 'Full'
ServerTokens ProductOnly
<IfModule mod_headers.c>
#Header set ProcessingTime "%D"
Header unset X-Powered-By
Header unset Server
#Header set Server MYWEB-WS
</IfModule>
<IfModule security2_module>
SecRuleEngine on
ServerTokens Full
ServerSignature Off
SecServerSignature "MyTest-WS"
</IfModule>
#
# Supplemental configuration
# Load config files in the "/etc/httpd/conf.d" directory, if any.
#
IncludeOptional conf.d/*.conf
<VirtualHost *:80>
ServerName myweb.co.kr
ServerAlias www.myweb.co.kr
DocumentRoot /var/www/html
Directoryindex index.do index.html index.htm index.jsp index.php
ServerAdmin webmaster@myweb.co.kr
JkMountFile conf.d/uriworkermap.properties
JkMount /* wlb_common
KeepAliveTimeout 80
MaxKeepAliveRequests 0
Redirect 404 /favicon.ico
<Location /favicon.ico>
ErrorDocument 404 "No favicon"
</Location>
#----------------------------------------------
# JkStatus
#----------------------------------------------
<Location /jkstatus>
JkMount jkstatus
<RequireAll>
Require all granted
Require env MY_APP_NO_AUTH
</RequireAll>
</Location>
# ---------------------------------------------
# [ LOG ]
# ---------------------------------------------
ErrorLog logs/myweb.co.kr-error_log
CustomLog logs/myweb.co.kr-access_log common env=!dontlog
</VirtualHost>
- mod_jk관리 페이지 : http://192.168.10.1/jkstatus
- HTTP Header 서버정보 숨김(보안) : SecServerSignature "MyTest-WS"
3. 모듈 로드(/etc/httpd/conf.d/mod_jk.conf)
LoadModule jk_module modules/mod_jk.so
JkWorkersFile conf.d/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories
JkRequestLogFormat "%w %V %T"
JkShmFile run/jk.shm
4. 모듈 로드 및 관리자 설정(/etc/httpd/conf.d/mod_cluster.conf)
LoadModule advertise_module modules/mod_advertise.so
LoadModule manager_module modules/mod_manager.so
LoadModule cluster_slotmem_module modules/mod_cluster_slotmem.so
MemManagerFile /var/cache/httpd
<IfModule manager_module>
Listen 192.168.10.1:18847
LogLevel info
Maxhost 80
ManagerBalancerName mycluster
<VirtualHost 192.168.10.1:18847>
ServerAlias 192.168.10.1
KeepAliveTimeout 300
MaxKeepAliveRequests 0
ServerAdvertise on
AdvertiseFrequency 5
AdvertiseGroup 224.0.1.105:23364
ProxyPassMatch ^/static/ !
ProxyPass / balancer:
ProxyPassReverse / balancer:
ProxyPreserveHost on
EnableMCPMReceive
<Location /mcm>
SetHandler mod_cluster-manager
</Location>
</VirtualHost>
</IfModule>
- mod_cluster 관리 페이지 : http://192.168.10.1/mcm
5. URI 매핑 설정(/etc/httpd/conf.d/uriworkermap.properties)
#
# 01. My App모듈 이름
#
/common/ =wlb_common
/common/* =wlb_common
#
# 04. (*.*) 확장자로(*.*) 매핑
#
/jkstatus =jkstatus
/jkstatus/* =jkstatus
#Common
/common/*.js =wlb_common
/common/*.jsp =wlb_common
/common/*.do =wlb_common
/common/*.so =wlb_common
/common/*.html =wlb_common
/common/*.htm =wlb_common
6. load balance 및 node 구성 설정(/etc/httpd/conf.d/workers.properties)
worker.list =jkstatus, wlb_common
worker.template.lbfactor =10
worker.template.type =ajp13
worker.template.ping_mode =A
worker.template.ping_timeout =100000
worker.template.socket_keepalive =1
worker.template.socket_timeout =600
worker.template.connect_timeout =600000
worker.template.prepost_timeout =600000
worker.template.recovery_options =4
worker.template.reply_timeout =30000
worker.template.fail_on_status =-404,-500,503,504
worker.S01-Node01.reference =worker.template
worker.S01-Node01.host =192.168.20.1
worker.S01-Node01.port =8009
worker.S01-Node01.lbfactor =1
worker.S01-Node02.reference =worker.template
worker.S01-Node02.host =192.168.20.1
worker.S01-Node02.port =8109
worker.S01-Node02.lbfactor =1
worker.S02-Node01.reference =worker.template
worker.S02-Node01.host =192.168.20.2
worker.S02-Node01.port =8009
worker.S02-Node01.lbfactor =1
worker.S02-Node02.reference =worker.template
worker.S02-Node02.host =192.168.20.2
worker.S02-Node02.port =8109
worker.S02-Node02.lbfactor =1
worker.jkstatus.type=status
worker.wlb_common.type =lb
worker.wlb_common.retries =0
worker.wlb_common.max_reply_timeouts =5000
worker.wlb_common.method =S
worker.wlb_common.session_cookie =JSESSIONID
worker.wlb_common.sticky_session =True
worker.wlb_common.sticky_session_force =False
worker.wlb_common.balance_workers =S01-Node01, S01-Node02, S02-Node01, S02-Node02
- worker.template.ping_timeout : CPong default wait시간에 사용되는 값 -> (기본값은 10000(milliseconds)이다, JAVA의 GC의 타임이 길게 발생하는 경우라면 짧지 안도록한다, C와 P모드를 사용할 경우에는 너무 짧은 값을 사용하지 말것)
- worker.template.connect_timeout : 커넥션이 연결되는 동안 Cpong default wait에 사용되는 값 -> (연결 커넥션을 영구적계속 사용, 새로운 커넥 을 연결하는 경우는 거의 없음, (C모드를 active해 CPing을 사용권고))
- worker.template.prepost_timeout : WAS로 요청이 전달되기 전에 사용되는 값 -> 지연에 민감한 어플리케이션은 사용하지 않는다(네트워크 대기와 안정성을 고려해서 5000 ~ 10000 사이로 적용), arj13 protocol에서의 cping request에 대한 cpong respone timeout
- worker.template.reply_timeout : [Client로 부터 응답] jk와 WAS Instance 간의 의미있는 요청과 응답간의 시간에 대해서 1000ms timeout으로 지정
- worker.template.socket_timeout : [Server로 부터 응답] jk와 WAS Instance간의 응답 대기 시간이 3초 되면, timeout이 된다. 이 응답대기 시간은 TCP socket 내부적인 상태에 대한 timeout을 의미한다
- [인스턴스 상태확인(CPing/CPong)] : worker.template.ping_mode= A
- C (Connect) : WAS에 연결한 후 CPing/CPong시 connect_timeout만큼 기다리며, 지정되지 않은 경우 ping_timeout 을 기다린다.
- P (Preport) : WAS에 요청을 보내기 전 CPing/CPong하여 연결을 확인한다. prepost_timeout만큼 기다리며, 지정되지 않은 경우 ping_timeout 만큼 기다린다.
- I (Interval) : 주기적으로 connect_ping_interval만큼 CPing/CPong하여 연결을 확인한다.
- A (All) : 위의 모든 방법을 사용한다.
- [WAS 문제 감지처리] : worker.template.recovery_options = 4
- 1 : WAS가 요청을 방은후 실패 할 경우 복구하지 않음
- 2 : WAS가 클라이언트에 헤더를 보낸후 실패 할 경우 복구하지 않음
- 4 : 우리가 오류를 감지하면 클라이언트에 대한 답을 다시 작성할 때 (브라우저), WAS에 대한 연결을 닫습니다
- 8 : 항상 HTTP HEAD 메소드에 대한 요청 (하나 또는 두 비트가 설정되는 경우에도) 복구
-16 : 항상 HTTP GET 메소드에 대한 요청 (하나 또는 두 비트가 설정되는 경우에도) 복구
- [세션쿠키 변수] (중요함) : worker.wlb_common.session_cookie =JSESSIONID
- 세션 공유가 정상 작동 하려면 필수 설정 되어야 합니다.
- jvmRoute에서 어느서버로 라우팅 할지를 결정 할때 JSESSIONID 변수를 읽어서 처리 하기 때문에 설정이 안되거나 잘못 설정 되어 있으면 세션공유(Session Clustering)가 정상 작동 되지 않습니다.
- session cookie name 정의 규칙 : [ JSESSIONID(기본), JSESSIONID_INTL(세계공용), JSESSIONID_US(미국), JSESSIONID_CUSTOM(사용자정의) ]
- session_cookie=JSESSIONID_CUSTOM : Round-Robin으로만 작동됨
- session_cookie=JSESSIONID : 최초접속 서버로 유지됨
- [세션 라우트 유지] : worker.wlb_common.sticky_session =True
- sticky session은 mod_jk에서 세션을 생성할 때 사용자 쿠키에 기록되는 세션 아이디를 이용하여 구분하여 보내며 기존의 세션 아이디 뒤에 jvmRoute ID를 붙혀 어느서버로 갈지 결정을 한다
- JSESSIONID 예시 : 4TXeLtQq3FRQGKEwnSZ3_1sqgd1lxKWMK8NO2CM2.S01-Node01 (세션ID.노드ID)
- [부하분산 가중치] : worker.S01-Node01.lbfactor=1
- 모든 노드를 균등하게 분산
worker.S01-Node01.lbfactor=1
worker.S01-Node02.lbfactor=1
worker.S02-Node01.lbfactor=1
worker.S02-Node02.lbfactor=1
- 서버1, 서버2를 2:1비율로 부하 분산
worker.S01-Node01.lbfactor=20
worker.S01-Node02.lbfactor=20
worker.S02-Node01.lbfactor=10
worker.S02-Node02.lbfactor=10
- [부하분산 기준] : worker.wlb_common.method = S
- S (Session) : 연결세션에따라 분산
- B (Busyness) : 서버부하에 따른분산
- R (Requests) : 기본으로 설정되었으며 요청에 따른분산
- T (Traffic) : 발생되는 트래픽에따라 분산
7. 관리도구/기타 보안사항
- jkstatus : http://192.168.10.1/jkstatus
- mod cluster manager : http://192.168.10.1/mcm
- HTTP Header 서버정보 숨김(보안) : SecServerSignature "MyTest-WS"
1. 방법1 : /etc/httpd/conf/httpd.conf
<IfModule security2_module>
SecRuleEngine on
ServerTokens Full
ServerSignature Off
SecServerSignature "MyTest-WS"
</IfModule>
- Server: Apache/2.4.7 -> MyTest-WS 로 변경
- HTTP Header (Server) 정보 숨김 (변경)
2. 방법2 : /home/jboss/EAP-7.1.0/SERVER11/env.properties
org.apache.coyote.http11.Http11Protocol.SERVER="MyTest-WS"
- X-Powered-By: Servlet 2.x; JBoss-7.x (숨김)
- HTTP Header (X-Powered-By) 정보 숨김