應用的合理部署即能提升系統的可靠性和穩定性,又能提升系統的可維護性和擴展性。本文檔詳細闡述基於Apache負載均衡和JBOSS7集羣的應用系統部署方案和配置步驟。內容涉及部署方案、環境配置、方案特性。html
介紹支持以上設計方案所需的各個相關軟件的版本信息及針對以上方案在實施時的詳細配置過程。java
功能模塊node |
版本linux |
下載web |
JAVAapache |
jdk-6u45-linux-x64.bin瀏覽器 (注:64位)緩存 |
|
負載均衡tomcat |
Apache2.2.25服務器 (依賴:apr-1.4.8.tar.gz apr-util-1.5.2.tar.gz) |
http://httpd.apache.org/download.cgi |
mod_jk-1.2.31-httpd-2.2.x.so (注:64位) |
http://archive.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/linux/jk-1.2.31/ |
|
集羣 |
jboss-eap-6.2.0.zip |
http://www.jboss.org/jbossas/downloads/ |
1) 安裝前請先確認操做系統是64位
查看命令:echo $HOSTTYPE
說明:後面是X686或X86_64則內核是64位的,i686或i386則內核是32位的
2) JDK安裝包必須爲64位
查看命令:java -version
說明:若是是64位的則會顯示Java HotSpot<TM>64-Bit 字樣,32位的則沒有相似信息
3) JBOSS使用官方推薦安裝包jboss-eap-6.2.0.zip
Linux系統自帶了jdk,但仍是1.4的老版本,因此須要先卸載,而後在安裝1.6,卸載步驟以下:
[root@localhost ~]# rpm -qa | grep jdk
[root@localhost ~]# rpm -qa | grep gcj
libgcj-4.1.2-42.el5
java-1.4.2-gcj-compat-1.4.2.0-40jpp.115
上面先確認jdk的具體版本號,而後
[root@localhost ~]# yum -y remove java-1.4.2-gcj-compat-1.4.2.0-40jpp.115
1) 解壓jdk安裝包
./
jdk-6u45-linux-x64.bin
2) etc/profile最後加入
JAVA_HOME=/prog/jdk/jdk1.6.0_45 PATH=$JAVA_HOME/bin:$PATH set CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export JAVA_HOME export PATH export CLASSPATH |
3) 測試
命令行輸入java –version,若是顯示當前版本,則JDK安裝成功。
1) 進入到安裝程序所在目錄,執行如下命令對其進行解壓縮
tar -zxvf httpd-2.2.25.tar.gz
在同級目錄下會生成 httpd-2.2.25 文件,執行如下命令建立一個新的目錄來存放將要安裝的apache軟件
mkdir –p /usr/local/web/apache2.2/
執行如下命令將生成的源碼文件移動到其餘目錄,便於管理
mv httpd-2.2.25 /usr/local/src/
進入到src目錄,再進入到httpd-2.2.25目錄執行如下命令進行安裝前的配置
./configure --prefix=/usr/local/web/apache2.2 --enable-so --enable-mods-shared=most --enable-rewrite
2) 若是上述過程報錯依賴apr與apr-util,則首先安裝apr與apr-util;若是無報錯,則忽略
[root@localhost 52lamp]# cd apr-1.4.8 [root@localhost apr-1.4.8]# ./configure [root@localhost apr-1.4.8]# make [root@localhost apr-1.4.8]# make install |
Apr-util安裝與上述徹底相同。
3) Apr與apr-util安裝完畢後從新執行configure、make、make install
#./configure --prefix=/usr/local/web/apache2.2 --enable-so --enable-mods-shared=most --enable-rewrite --with-apr=/usr/local/apr/ --with-apr-util=/usr/local/apr-util/ #make #make install |
4) 執行 service httpd start 命令,看是否可以啓動apache 若是不能啓動並提示httpd unrecognized service則是apache沒有配置成系統服務
5) 將apache配置成系統服務
cp /usr/local/web/apache/bin/apachectl /etc/rc.d/init.d/httpd
vi /etc/rc.d/init.d/httpd
當httpd文檔打開後,在#!/bin/sh 內容下面添加如下內容(含#符號的)
# chkconfig: 2345 90 90
# description: Activates/Deactivates Apache Web Server
添加完成後,保存並退出到命令模式,輸入如下命令將apache添加到系統服務
chkconfig --add httpd
chkconfig --level 345 httpd on
6) 測試
命令行輸入 service httpd start
而後打開瀏覽器訪問http://localhost出現it works.
Apache安裝結束。
Jboss-eap-6.2是基於jboss as 7的企業級版本,JBoss AS7新加入了域(domain)的概念並實現了相關功能。域的提出及實現,其目的是使得多臺JBoss AS服務器的配置能夠集中於一點,統一配置、統一部署,從而在管理多臺JBoss AS服務器時,實現集中管理。
域的目的則是將多臺服務器組成一個服務器組(Server Group),併爲一個服務器組內的多臺主機(Host)提供:
* 單點集中配置(經過一個域控制器,即Domain Controller,實現組內主機的統一配置)。
* 單點統一部署,經過域控制器將項目一次部署至組內所有主機。
簡單來說,羣集的目標是讓多臺服務器分攤壓力,當一臺或多臺服務器當機時,服務能夠繼續保持運轉;而域的目標則是提供集中配置和管理多臺服務器的能力。在沒有域的概念時,要想讓羣集內的多臺服務器或幾組服務器保持統一的配置,一個一個分別的去手工維護,是很是麻煩的事情,而域的引入解決了這一問題。
如今兩臺電腦的IP分別爲10.0.1.3及10.0.1.18,分別運行JBoss AS7,並組成一個服務器組(Server Group)。其中,使用10.0.1.3這臺機器作爲域控制器(Domain Controller):
如上圖所示,兩臺主機分別被命名爲」master「及」slave「。經過配置,將master與slave組成一個服務器組,其中master將作爲這個服務器組的域控制器。
須要說明一點的是,服務器組(Server Group)能夠由多臺服務器(Host)組成,並不必定只有兩臺,因此不要被master及slave這樣的名字給迷惑了,覺得一個服務器組僅支持一主一從兩臺hosts。本文中由於只使用兩臺服務器作實驗,所以出於方便角度將它們分別命名爲master及slave。此外,在一個服務器組中,只有一臺域控制器,在本實驗中咱們將使用master這臺機器作爲domain controller。
1) 在domain controller一段建立一個Management User,具體到JBOSS_HOME/bin目錄下執行add-user.sh
[kylin@unused bin]$ ./add-user.sh What type of user do you wish to add? a) Management User (mgmt-users.properties) b) Application User (application-users.properties) (a): Enter the details of the new user to add. Realm (ManagementRealm) : Username : admin123 Password :admin111_ Re-enter Password :admin111_ About to add user 'admin123' for realm 'ManagementRealm' Is this correct yes/no? yes Added user 'admin123' to file '/home/kylin/work/./standalone/configuration/mgmt-users.properties' Added user 'admin123' to file '/home/kylin/work/./domain/configuration/mgmt-users.properties' Is this new user going to be used for one AS process to connect to another AS process? e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls. yes/no? yes To represent the user add the following to the server-identities definition <secret value="YWRtaW4xMTFf=" /> |
2) JBOSS_HOME/domain/configuration/host.xml中,刪除servers,表示這臺主機只用來作域控制器,不用於發佈server,jboss已經爲咱們提供了對應的配置文件便於參考,即JBOSS_HOME/domain/configuration/host-master.xml
3) Domain.xml中< hornetq-server>節點加入<security-enabled>false</security-enabled>
<hornetq-server> <security-enabled>false</security-enabled> … </hornetq-server> |
4) 測試
運行/bin/domain.sh,而後瀏覽器中輸入http://localhost:9990/ ,輸入用戶、密碼(剛纔add-user.sh配置的),便可進入Domain管理界面
1) 由於Slave這臺機器不做爲域控制器而存在,刪除domain/configuration/domain.xml文件
2) 一樣jboss已經爲咱們提供了對應的配置文件便於參考,即JBOSS_HOME/domain/configuration/host-slave.xml,打開host.xml,修改<domain-controller>部份內容以下:
<domain-controller> <remote host="10.0.1.3" port="9999" username=」admin123」 security-realm="ManagementRealm"/> </domain-controller> |
3) 修改 <security-realm name="ManagementRealm">以下
<security-realm name="ManagementRealm"> <server-identities> <secret value="YWRtaW4xMTFf="/> </server-identities> <authentication> <properties path="mgmt-users.properties" relative-to="jboss.domain.config.dir"/> </authentication> </security-realm> |
注意事項:密碼值爲admin123用戶對應密碼的BASE64編碼值,同時加上’=’結尾。
編碼值可使用網上在線工具查看。
4) 確保host名字惟一
<host name="slave1" |
5) 確保server的名字惟一,並修改端口,遞增數爲150或100(這是端口偏移量,jboss默認http端口是8080,這樣之後訪問具體的server,若是server1的端口偏移量是150,則端口就是8230)
<servers> <server name="server1" group="other-server-group" auto-start="false"> <socket-bindings port-offset="150"/> </server> </servers> |
6) 運行domain.sh測試
訪問http://localhost:8230,進入JBOSS頁面即OK。啓動成功的話,應該能夠在master上面看到日誌,slave被成功的註冊進來。
1) 訪問控制檯http://10.0.1.3:9990/,在Runtime標籤頁下左側,點擊Manage Deployments, 進入部署功能頁面:
2) 此時點擊右邊的"Add "功能,將ShoppingCart.war添加進Content Repository(域控制器用於保存待部署資源的目錄)。
3) 而後點擊"Assign"將ShoppingCart.war添加至 "other-server-group",並將其enable
注意:這裏有一點值得注意的是,jboss-eap-6.2默認設置了兩個server group分別是:main-server-group和other-server-group,可是這兩個組是有區別的main-server-group使用的默認profile和socket是full,而other-server-group使用的默認profile和socket是full-ha,然而在jboss-eap-6.2的四種profile中只有ha和full-ha支持集羣的multicast協議,這一點能夠在domain/configuration/domain.xml裏面看到,並且jboss-eap-6.2官方文檔也有指出,以下圖:
因此在對應用分配組(Assign)的時候,若是該應用最終訪問方式是要經過apache服務器來分發請求訪問,那就不要分配給main-server-group,不然最終發佈的時候,經過apache默認端口訪問的結果要麼出現404,要麼503.若是非要分配給main-server-group,則須要修改它默認的profile和socket爲:ha或者full-ha.
1) 將下載的 mod_jk-1.2.31-httpd-2.2.x.so 文件更名爲mod_jk.so
2) 將mod_jk.so 文件複製到 APACHE_HOME/modules/目錄下
3) 打開APACHE_HOME/conf/httpd.conf 在文件最後添加如下內容後保存
# module mod_jk config file
Include conf/mod_jk.conf
4) 進入APACHE_HOME/conf/目錄中,新建mod_jk.conf
#load module mod_jk-1.2.31-httpd-2.2.3.so is for Apache 2.2.x. LoadModule jk_module modules/mod_jk.so #配置 mod_jk conf #加載集羣中的workers JkWorkersFile conf/workers.properties #加載workers的請求處理分配文件 JkMountFile conf/uriworkermap.properties #指定jk的日誌輸出文件 JkLogFile logs/mod_jk.log #指定日誌級別 JkLogLevel info |
5) 進入APACHE_HOME/conf/目錄,新建workers.properties
# worker列表 worker.list=node_lb,jkstatus #配置實例節點1 worker.node1.host=10.0.0.18 worker.node1.port=8009 worker.node1.type=ajp13 ----對於mod_jk,jboss僅支持ajp13協議 worker.node1.lbfactor=1 #配置實例節點2 worker.node2.host=10.0.0.18 worker.node2.port=8159 ----8009+150的偏移量 worker.node2.type=ajp13 worker.node2.lbfactor=1 worker.node_lb.type=lb worker.node_lb.retries=3 worker.node_lb.balance_workers=node1,node2 worker.node_lb.sticky_session=true ----粘性session,非粘性只需改爲false便可 #worker.node_lb.sticky_session_force=false worker.jkstatus.type=status |
6) 進入APACHE_HOME/conf/目錄中,新建uriworkermap.properties
#全部請求都由LB_worker這個worker處理 /*=node_lb #全部包含jkstatus請求的都由名稱叫jkstatus的這個worker處理 /jkstatus =jkstatus /jkstatus/* =jkstatus |
7) 測試
從新啓動apache,首先進入http://localhost:9990部署ShoppingCart.war
訪問http://localhost/ShoppingCart進行測試
給 jboss每一個host配置apache mod_jk的分發路由
<system-properties> <property name="org.apache.catalina.connector.URI_ENCODING" value="UTF-8"/> </system-properties> |
Apache mod_proxy跟mod_jk功能相似,也具備整合負載均衡的能力,當服務搭建在一臺內網機器上,經過外網機器的80端口映射內網的8080端口進行訪問。因爲可對外暴露的端口只有被映射的一個8080端口,這時可使用mod_proxy進行反向代理配置。
1) 首先httpd.conf配置中須要啓用Apache的幾個模塊
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule proxy_http_module modules/mod_proxy_http.so |
2) httpd.conf中打開httpd-vhosts.conf註釋,這是反向代理配置文件,若是沒有,須要自行添加以下:
# Virtual hosts
Include conf/httpd-vhosts.conf
3) 修改apache80監聽端口爲8080
在httpd.conf配置文件中查找listen 80 改爲8080 便可。
4) 編輯httpd-vhosts.conf
# # Virtual Hosts # # If you want to maintain multiple domains/hostnames on your # machine you can setup VirtualHost containers for them. Most configurations # use only name-based virtual hosts so the server doesn't need to worry about # IP addresses. This is indicated by the asterisks in the directives below. # # Please see the documentation at # <URL:http://httpd.apache.org/docs/2.2/vhosts/> # for further details before you try to setup virtual hosts. # # You may use the command line option '-S' to verify your virtual host # configuration. # # Use name-based virtual hosting. # NameVirtualHost *:8080 # # VirtualHost example: # Almost any Apache directive may go into a VirtualHost container. # The first VirtualHost section is used for all requests that do not # match a ServerName or ServerAlias in any <VirtualHost> block. # RewriteEngine On Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; " env=BALANCER_ROUTE_CHANGED #創建虛擬主機來做爲負載均衡 <Proxy balancer://main_cluster> Order deny,allow Allow from all BalancerMember ajp://172.16.3.136:8109 route=slave1:cks-main ProxySet stickysession=ROUTEID </Proxy> <Proxy balancer://report_cluster> Order deny,allow Allow from all BalancerMember ajp://172.16.3.136:8209 route=slave1:WebReport ProxySet stickysession=ROUTEID </Proxy> <VirtualHost *:8080> Timeout 7200 ProxyRequests Off # ProxyPassReverseCookiePath / / ProxyPass /cks-main balancer://main_cluster/cks-main ProxyPassReverse /cks-main balancer://main_cluster/cks-main ProxyPass /WebReport balancer://report_cluster/WebReport ProxyPassReverse /WebReport balancer://report_cluster/WebReport ProxyPreserveHost On #KeepAliveTimeout 500 #MaxKeepAliveRequests 200 </VirtualHost> |
5) 最後重啓apache
service httpd restart
6) 測試
http://172.16.3.136:8080/cks-main
http://172.16.3.136:8080/WebReport/ReportServer
session同步除了上述的sticky模式,還能夠經過session複製實現。要實現session複製只須要在項目的web.xml裏面加入<distributable />標籤便可。不過session複製會致使應用服務器性能降低,因此要慎用。
官方文檔:
如何經過一種session管理策略,確保集羣某一個結點失效後,其session數據能由其餘結點獲取以便其餘結點接替失效結點,實現集羣的容錯(failover),對於這個問題,多數的應該服務器(包括Tomcat在內)使用的是session複製(session replication)機制,即結點之間經過組播方式將各自的session發到其餘全部結點上,若是其中一個訪問出錯,則另外結點仍然具備有效的session內容,從而能正常接管其session。因爲服務器內置了session複製機制的實現,於是使用這種方案很是簡單,只須要作簡單的配置便可完成,可是其缺點也是很明顯的,因爲大量的session信息須要複製,在用戶數量和集羣數量達到必定規模後,session複製就有可能成爲性能瓶頸。
session共享的另外一種思路就是採用memcached。使用memcached來存儲session能夠經過本身編寫filter實現.
主要思路:
(1)繼承重構HttpServletRequestWrapper,HttpSessionWrapper類,覆蓋原來和session存取相關的方法呢,都經過SessionService類來實現.
(2)使用filter攔截cookie中的sessionId,經過sessionId構造新的HttpServletRequestWrapper對象,傳給後面的應用.
(3)SessionService鏈接memcached服務,以sessionId做爲key,存取的對象是一個map.map的內容即爲session的內容.
Demo請看:附件
使用過程注意幾個問題和改進思路:
一、memcache的內存應該足夠大,這樣不會出現用戶session從Cache中被清除的問題(能夠關閉memcached的對象退出機制)。
二、若是session的讀取比寫入要多不少,能夠在memcache前再加一個Oscache等本地緩存,減小對memcache的讀操做,從而減少網絡開銷,提升性能。
三、若是用戶很是多,可使用memcached組,經過set方法中帶hashCode,插入到某個memcached服務器
對於session的清除有幾種方案:
(1)能夠在凌晨人最少的時候,對memcached作一次清空。(簡單)
(2)保存在緩存中的對象設置一個失效時間,經過過濾器獲取sessionId的值,按期刷新memcached中的對象.長時間沒有被刷新的對象自動被清除.(相對複雜,消耗資源)
nohup ./domain.sh &
運行日誌能夠查看domain.sh對應目錄下的nohup.out
正常退出可使用jboss提供的./jboss-cli.sh來鏈接後臺裕興的domain.sh,步驟:
./jboss-cli.sh
connect
:shutdown
能夠參考官方文檔,以下:
固然,若是以上方法沒法奏效,那隻能使用強行殺進程了:
ps aux | grep java 查PID
kill –s 9 PID
重啓跟關閉採用一樣的方式命令爲:
:reload
設置位置:bin/domain.conf
參考大小:
bin\domain.conf中
if [ "x$JAVA_OPTS" = "x" ]; then
JAVA_OPTS="-Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true
或者:
能夠對具體的server進行內存設置,以下:
GC文件名爲日期+時間,以便進行GC性能跟蹤。
bin\domain.conf中
if [ "x$JAVA_OPTS" = "x" ]; then
JAVA_OPTS="-Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -verbose:gc -Xloggc:/prog/gc/`date +%Y%m%d__%H%M%S`.out -XX:+PrintGCTimeStamps -XX:+PrintGCDetails
"
\domain\configuration\domain.xml
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" max-connections="1000"/>
\domain\configuration\domain.xml中
<subsystem xmlns="urn:jboss:domain:web:1.4" default-virtual-server="default-host" native="false"> <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" max-connections="1000"/> <virtual-server name="default-host" enable-welcome-root="true"> <alias name="localhost"/> <alias name="example.com"/> <access-log pattern="%a %t %H %p %U %s %T" > <directory relative-to="jboss.server.log.dir" /> </access-log> </virtual-server> </subsystem> |
pattern的詳細說明
%a 遠端IP
%A 本地IP
%b 發送的字節數,不包含HTTP頭,若是爲0,使用」-」
%B 發送的字節數,不包含HTTP頭
%h 遠端主機名(若是resolveHosts=false),遠端的IP
%H 請求協議
%l 從identd返回的遠端邏輯用戶名,老是返回’-’
%m 請求的方法
%p 收到請求的本地端口號
%q 查詢字符串
%r 請求的第一行
%s 響應的狀態碼
%S 用戶的sessionID
%t 日誌和時間,使用一般的log格式
%u 認證之後的遠端用戶(若是存在的話,不然爲’-’)
%U 請求的URI路徑
%v 本地服務器的名稱
%D 處理請求的時間,以毫秒爲單位
%T 處理請求的時間,以秒爲單位
默認響應超時時間爲60秒
注:7.1.1不支持此設置,7.1.2支持此設置
\domain\configuration\domain.xml中
org.apache.coyote.http11.DEFAULT_CONNECTION_TIMEOUT system property. <system-properties> <property name="org.apache.coyote.http11.DEFAULT_CONNECTION_TIMEOUT" value="600000"> </system-properties> |
Ø 基於負載均衡的請求分發,快速響應客戶端請求
Ø 物理主機硬件隔離,提供穩定可靠的服務
Ø 應用軟件部署隔離,便可獨立服務又可集羣共享
Ø 應用負載均衡,下降應用系統故障頻率及宕機風險
Ø 單個應用故障,其餘應用可接管服務
Ø 可方便擴充硬件設備,知足業務擴展需求
Ø 可方便應用實例擴充、部署等變動需求
https://docs.jboss.org/author/display/AS71/AS7+Cluster+Howto
https://docs.jboss.org/author/display/AS71/Using+mod_jk+with+JBoss+AS7
http://www.jbossauthority.com/jboss-eap-6-extensions-subsystems-and-profiles/