傳統的(de)Java Web項目是通過tomcat來運行和(hé)發布的(de)。但在實際的(de)企業應用環境中,采用單一(yī)的(de)tomcat來維持項目的(de)運行是不現實的(de)。tomcat 處理(lǐ)能力低(dī),效率低(dī),承受并發小(1000左右)。當用戶請求較少時,單一(yī)的(de)tomcat能夠快速響應用戶請求,但如(rú)果訪問量一(yī)大,tomcat處理(lǐ)能力跟不上,無法及時響應請求,就會造成用戶等待;如(rú)果訪問量過大,超出tomcat的(de)承受能力,還可(kě)能導緻tomcat超載故障。
apache 是一(yī)個 web 服務器環境程序,可(kě)以作為(wèi)web 服務器使用。Apache對并發請求的(de)處理(lǐ)能力較tomcat強,對靜态頁面(如(rú)asp,php,cgi,jsp等)的(de)處理(lǐ)上比tomcat更為(wèi)迅速,但apache不支持動态網頁(需借助tomcat)。
因此實際應用中可(kě)以搭建apache+tomcat負載均衡集群,一(yī)個apache 作為(wèi) Web 服務器,為(wèi)網站的(de)靜态頁面請求提供服務;并使用tomcat 服務器作為(wèi)一(yī)個 Servlet/JSP 插件,用于處理(lǐ)網站的(de)動态頁面。當用戶通過浏覽器發出請求時,客戶請求首先會發送到 apache,如(rú)果請求是靜态文本則由 apache 解析,并把結果返回給客戶端;如(rú)果是動态的(de)請求,如(rú) jsp,apache 會把解析工作交給 tomcat,由 tomcat 進行解析(這首先要兩者現實整合),tomcat 解析完成後,結果仍是通過 apache 返回給客戶端。這樣就可(kě)以達到分工合作,實現負載均衡,提高(gāo)系統的(de)性能!
在linux服務器上安裝CentOS之後,事先将所有軟件的(de)安裝包上傳到linux服務器上,并放置在/software目錄下。
(1)在/usr/local目錄下新建Java文件夾,并将安裝包從/software目錄拷貝到/usr/local/Java目錄下(圖形界面下直接“複制”-“粘貼”即可(kě))。
#cp /software/jdk-7u45-linux-i586.tar.gz/usr/local/Java
(2)定位到文件夾/usr/local/Java。
#cd /usr/local
(3)解壓安裝包到當前目錄。
#tar -zxvf jdk-7u45-linux-i586.tar.gz
(4)配置java的(de)環境變量。
為(wèi)了系統中所有用戶都能使用java環境,修改系統中的(de)環境配置文件/etc/profile。在文件最後添加下列語句:
export JAVA_HOME=/usr/local/Java/jdk1.7.0_45
export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
(5)修改完成以後,logout再重新登陸,或#source /etc/profile,使文件立即生效。
JDK安裝(3):查看與系統自(zì)帶open jdk有關的(de)包。
在終端中輸入“rpm -qa|grep gcj”,查看gcj的(de)版本号,在這裏得到的(de)結果如(rú)圖所示:
在終端中輸入“yum -y remove javajava-1.4.2-gcj-compat-1.4.2.0-40jpp.115”,然後等待,等待系統卸載完自(zì)帶的(de)jdk。最終在終端中顯示“Complete!”,卸載完成。
JDK安裝(5):卸載系統自(zì)帶open jdk時出現問題及解決方案。
【問題】使用yum安裝或卸載軟件,出現如(rú)圖所示的(de)提示錯誤。
原因是系統進程已經有一(yī)個yum的(de)update進程在運行了。可(kě)用ps -ef | grep update查看進程。解決辦法是在命令行輸入下面兩條命令:
#rm -f/var/run/yum.pid /sbin/service
#yum-updatesdrestart
然後重新執行yum的(de)删除命令即可(kě)。
在命令行中輸入java -version命令可(kě)查看安裝的(de)jdk版本。如(rú)果顯示出jdk安裝的(de)版本信息則說明jdk安裝成功。
如(rú)果出現如(rú)圖所示的(de)錯誤信息,則是因為(wèi)系統的(de)selinux的(de)設置問題,即開啓了selinux服務。解決辦法如(rú)下:
(1)打開/etc/selinux/config;
(2)把selinux=enforcing改為(wèi)selinux=disabled;
(3)重啓linux。
如(rú)下圖所示,使用# rpm -qa|grep httpd,查看與httpd相關軟件包。發現CentOS自(zì)帶有apache,版本為(wèi)2.2.3。因此在安裝我們需要的(de)apache之前,需要卸載CentOS自(zì)帶的(de)apache。
上一(yī)步我們已經查看了與httpd相關的(de)軟件包,這一(yī)步要删除删除httpd。在命令行中使用:# rpm -e httpd。
如(rú)果出現如(rú)圖所示錯誤,說明還有一(yī)個相關的(de)軟件包沒有删除,清除之,即:# rpm -e gnome-user-share。
可(kě)以使用參數--nodeps的(de)意思就是不管各個程序包間的(de)依賴關系。
#rpm -e --nodeps httpd //這樣不需要删除gnome-user-share了。
Apache安裝(4):重新安裝自(zì)己下載的(de)Apache
(1)将安裝包從/software目錄拷貝到/usr/local目錄下。
#cp /software/httpd-2.4.7.tar.gz /usr/local
(2)定位到文件夾/usr/local。
#cd /usr/local
(3)解壓安裝包到當前目錄。
#tar -zxvf httpd-2.4.7.tar.gz
(4)定位到文件夾/usr/local /httpd-2.4.7。
#cd httpd-2.4.7
(5)設置安裝路徑和(hé)需要編譯的(de)模塊。
# ./configure--prefix=/usr/local/apache --enable-so -enable-proxy -enable-proxy_http=shared--enable-module=so --enable-mods-shared=all --enable-proxy-ajp=shared --enable-proxy-balancer -with-mpm=worker
//備注:prefix定義apache的(de)安裝路徑
(6)編譯通過,繼續安裝apache。
#make && makeinstall
Apache安裝(5):apache安裝的(de)check過程中出錯,如(rú)圖所示:APR not found 。原因是沒有安裝apr。
在/usr/local目錄下安裝apr:
#tar -zxvf apr-1.5.0.tar.gz
#cd apr-1.5.0
#./configure --prefix=/usr/local/apr
#make
#make install
安裝完成後再來configure apache。
在/usr/local目錄下安裝apr-util:
#tar -zxvf apr-util-1.5.3.tar.gz
#cd apr-util-1.5.3
#./configure--prefix=/usr/local/apr-util --with-apr=/usr/local/apr
#make
#make install
安裝完成後,在apache的(de)./configure 最後增加--with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util,重新configure apache。
在/usr/local目錄下安裝pcre:
# tar -zxvf pcre-8.32.tar.gz
#cd pcre-8.32
#./configure--prefix=/usr/local/pcre
#make
#make install
安裝完成後,在apache的(de)./configure 最後增加./configure 時加上參數 --with-apr=/usr/local/apr/ --with-apr-util=/usr/local/apr-util/--with-pcre=/usr/local/pcre,重新configure apache。
Apache配置及測試(1):安裝完畢後,在測試啓動apache之前先修改/apache/conf /httpd.conf。
(1)查找ServerName,打開注釋,将ServerName值改為(wèi)對應的(de)IP地(dì)址。
(2)在DirectoryIndex中添加 index.jsp。
(3)以下2個注釋去(qù)掉:
#Include conf/extra/httpd-mpm.conf
#Include conf/extra/httpd-default.conf
# /usr/local/apache/bin/apachectl start
浏覽器訪問http://127.0.0.1,提示無法連接。說明apache沒有成功啓動。查看錯誤日志(/apache/logs/error_log),發現如(rú)圖錯誤信息。原因是httpd.conf裏面的(de)mod_slotmem_shm.so沒有加載。将httpd.conf 文件中的(de)“#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so”前的(de)“#”去(qù)掉即可(kě)。
Apache配置及測試(3):
(1)重新啓動apache并查看httpd是否運行。
# /usr/local/apache/bin/apachectl start
# ps -ef | grep httpd
(2)浏覽器測試apache。在浏覽器中訪問http://127.0.0.1 。頁面出現“It's Works!”字樣即為(wèi)成功。
在/usr/local/apache/bin下有可(kě)執行程序。
(1)啓動apache服務:# /usr/local/apache/bin/apachectl start
(2)關閉apache服務:# /usr/local/apache/bin/apachectlstop
(3)重啓apache服務:# /usr/local/apache/bin/apachectl restart
Tomcat安裝、測試及配置(1):安裝tomcat
(1)将安裝包從/software目錄拷貝到/usr/local目錄下(圖形界面下直接“複制”-“粘貼”即可(kě))。
#cp /software/apache-tomcat-7.0.47.tar.gz/usr/local
(2)定位到文件夾/usr/local/。
#cd /usr/local
(3)解壓安裝包到當前目錄。
#tar -zxvf apache-tomcat-7.0.47.tar.gz
(4)修改配置文件,增加java的(de)環境變量信息。在/usr/local/apache-tomcat-7.0.47/bin下有文件catalina.sh 在文件頭部增加下列信息:
exportJAVA_HOME=/usr/local//Java/jdk1.7.0_45
exportCLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
exportPATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
(5)啓動tomcat,結果如(rú)下圖所示。
#/usr/local/apache-tomcat-7.0.47/bin/startup.sh
測試tomcat。打開浏覽器訪問http://127.0.0.1:8080,可(kě)以看到tomcat的(de)啓動歡迎頁面,證明tomcat配置正确。
在/usr/local/apache-tomcat-7.0.47/bin下有可(kě)執行程序。
(1)啓動tomcat服務:
# /usr/local/apache-tomcat-7.0.47/bin/startup.sh
# /usr/local/apache-tomcat-7.0.47/bin/catalina.sh start
(2)關閉tomcat服務:
# /usr/local/apache-tomcat-7.0.47/bin/shutdown.sh
# /usr/local/apache-tomcat-7.0.47/bin/catalina.sh stop
Tomcat安裝、測試及配置(4):java web項目發布
(1)用eclipse将編譯好的(de)Java Web項目導出成war包。
(2)将war包放置到linux服務器上的(de)tomcat的(de)webapps目錄下。如(rú)本次配置放在/usr/local/apache-tomcat-7.0.47/webapps下。
(3)啓動tomcat後,tomcat會自(zì)動将war包解壓并運行Java Web項目。
(4)打開浏覽器,輸入http://127.0.0.1:8080/SessionTest(項目名),就可(kě)以訪問項目。
Tomcat安裝、測試及配置(5):設置Tomcat默認訪問項目
打開/usr/local/apache-tomcat-7.0.47/conf/server.xml,在<Host></Host>标簽之間加入下面的(de)語句:
<Contextpath="" docBase="SessionTest" debug="0"reloadable="false" />
<Context>标簽的(de)docBase值為(wèi)想要默認訪問的(de)項目名稱,此處為(wèi)SessionTest。文件修改後如(rú)圖所示。然後重新啓動tomcat,打開浏覽器,輸入http://127.0.0.1:8080,就可(kě)以訪問SessionTest項目。
mod_jk的(de)作用:連接apache和(hé)tomcat集群的(de)中間件。
mod_jk的(de)安裝包:tomcat-connectors-1.2.37-src.tar.gz。
安裝步驟如(rú)下:
(1)将安裝包從/software目錄拷貝到/usr/local目錄下(圖形界面下直接“複制”-“粘貼”即可(kě))。
#cp /software/tomcat-connectors-1.2.37-src.tar.gz /usr/local
(2)定位到文件夾/usr/local/。
#cd /usr/local
(3)解壓安裝包到當前目錄。
# tar -zxvf tomcat-connectors-1.2.37-src.tar.gz
(4)編譯安裝mod_jk。
#cd /tomcat-connectors-1. 2.37-src/native
# chmod 755buildconf.sh
# ./buildconf.sh
# ./configure--with-apxs=/usr/local/apache/bin/apxs
# make
# make install
(5)将/tomcat-connectors-1.2.37/apache-2.0下的(de)mod_jk.so文件拷貝到apache安裝目錄下的(de)modules文件夾下面。
# cp ./apache-2.0/mod_jk.so/usr/local/apache/modules/
負載均衡集群配置(1):修改Tomcat/conf 路徑下的(de)server.xml。
修改< Connector>節點值,是關于使用ajp連接apache和(hé)tomcat時的(de)配置。修改成如(rú)下形式:
<!-- Definean AJP 1.3 Connector on port 8009 -->
<Connectorport="8009"protocolhandlerclassname="org.apache.jk.server.jkcoyotehandler"protocol="AJP/1.3" redirectPort="8443" />
注意:如(rú)果一(yī)台機器上同時運行多個tomcat,一(yī)定要将每個tomcat對應的(de)Connector标簽的(de)port端口設為(wèi)不同的(de)值
負載均衡集群配置(2):修改Tomcat/conf 路徑下的(de)server.xml。
修改<Engine>的(de)配置。将<Engine>的(de)注釋打開,為(wèi)安裝的(de)tomcat命名,即修改jvmRoute的(de)值為(wèi)“tomcat實例名”(不同的(de)tomcat賦予不同值,此處安裝了兩個tomcat,分别命名為(wèi)tomcat1和(hé)tomcat2),修改結果參見下圖:
在<Engine>或<Host>元素下添加以下內(nèi)容均可(kě):
<ClusterclassName="org.apache.catalina.ha.tcp.SimpleTcpCluster">
<ManagerclassName="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
<!--
<ManagerclassName="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
-->
<ChannelclassName="org.apache.catalina.tribes.group.GroupChannel">
<MembershipclassName="org.apache.catalina.tribes.membership.McastService"
address="224.0.0.1 "
port="45564"
frequency="500"
dropTime="3000"/>
<ReceiverclassName="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto "
port="4001"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>
<SenderclassName="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<TransportclassName="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
<InterceptorclassName="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</Channel>
<ValveclassName="org.apache.catalina.ha.tcp.ReplicationValve"filter=""/>
<ValveclassName="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<DeployerclassName="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListenerclassName="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
負載均衡集群配置(4):修改Tomcat/conf 路徑下的(de)server.xml。
修改<Cluster>節點信息。
<MembershipclassName="org.apache.catalina.tribes.membership.McastService"
bind="127.0.0.1" <!—如(rú)果主機有vpn-虛拟專用網絡,需要要bind下。如(rú)果沒有的(de)話可(kě)以不用加bind,否則會導緻session無法複制-->
address="228.0.1.99" #廣播地(dì)址,同一(yī)組tomcat集群一(yī)樣
port="45564" #同一(yī)組tomcat集群一(yī)樣
frequency="500"
dropTime="3000"/>
<ReceiverclassName="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="172.**.***.201" #修改為(wèi)本機IP地(dì)址
port="5000" #(tomcat默認可(kě)以檢測到4000~4100之間的(de)端口)
<!-- 如(rú)果是在同一(yī)台電腦上配置負載,要修改這個端口,否則會因為(wèi)端口沖突不起作用的(de)。-->
selectorTimeout="100"
maxThreads="6"/>
負載均衡集群配置(5):修改待發布項目的(de)web.xml
需要發布的(de)項目放在tomcat的(de)webapps文件夾下,在每個待發布項目的(de)web.xml末尾的(de)</web-app>标簽裏添加<distributable/>,确保session能夠複制。如(rú)下圖所示。
在apache的(de)conf下的(de)httpd.conf 文件尾部追加以下內(nèi)容:
#加載mod_jk Module
LoadModule jk_module modules/mod_jk.so
<Ifmodule mod_jk.c>
#指定workers.properties文件路徑
JkWorkersFile/usr/local/apache/conf/workers.properties
#指定jk logs文件存放位置
JkLogFile/usr/local/apache/logs/mod_jk.log
#Set the jk log level [debug/error/info]
JkLogLevel info
#Select the log format
JkLogStampFormat "[%a %b %d%H:%M:%S %Y]"
#JkOptions indicate to send SSL KEYSIZE,
JkOptions +ForwardKeySize +ForwardURICompat-ForwardDirectories
#JkRequestLogFormat set the requestformat
JkRequestLogFormat "%w %V %T %q %U%R"
#JkShmFile to put logs
JkShmFile/usr/local/apache/logs/mod_jk.shm
</IfModule>
#指定哪些請求交給tomcat處理(lǐ),哪些請求交給apache處理(lǐ)
#注意:" loadbalancer "為(wèi)在workers.propertise裏指定的(de)負載分配控制器
JkMount /*.jsp loadbalancer #所有的(de)jsp都交給tomcat處理(lǐ)
負載均衡集群配置(7):Apache配置——創建workers.properties
httpd.conf的(de)最後添加的(de)配置中workers.properties文件是不存在的(de),需要我們自(zì)己在apache/conf路徑下創建。workers.properties文件用于對負載均衡的(de)負載器worker
(即tomcat)進行具體的(de)登記,此處的(de)2個tomcat就作為(wèi)2個worker被登記在這個文件中。
workers.properties具體配置如(rú)下:
#workers.properties
#
# in unix, weuse forward slashes:
ps=/
# workers 列表
worker.list=tomcat1,tomcat2, loadbalancer, status
#--------------------------------------------------------------------
# 第一(yī)個tomcat
#--------------------------------------------------------------------
worker.tomcat1.port=8009 #對應tomcat的(de)server.xml中配置的(de)ajp13端口号
worker.tomcat1.host=127.0.0.1 #tomcat1的(de)主機地(dì)址,如(rú)不為(wèi)本機,請填寫IP地(dì)址
worker.tomcat1.type=ajp13 #定向包協議
worker.tomcat1.lbfactor=1 #server的(de)負載分配權重,值越高(gāo),分得的(de)請求越多
#以下為(wèi)非必要配置,這部分配置tomcat2的(de)配置同tomcat1
#worker.tomcat1.cachesize=1000 #配置tomcat的(de)jk連接緩存大小 (非必要)
#worker.tomcat1.cachesize_timeout=600 # (非必要)
#worker.tomcat1.reclycle_timeout=300 # (非必要)
#worker.tomcat1.socket_keepalive=1 #防止防火牆切斷未激活的(de)網絡連接(非必要)
#worker.tomcat1.socket_timeout=300 #(非必要)
#worker.tomcat1.local_worker=1 # (非必要)
#worker.tomcat1.retries=3 # (非必要)
#----------------------------------------------------------------------
# 第二個tomcat
#----------------------------------------------------------------------
worker.tomcat2.port=8009
worker.tomcat2.host=172.**.***.202 #tomcat2的(de)主機IP地(dì)址
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=1
#----------------------------------------------------------------------
# load balancerworker -負載均衡控制器
# ---------------------------------------------------------------------
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tomcat1,tomcat2 #指定分擔請求的(de)tomcat
worker.loadbalancer.sticky_session=1 #設置為(wèi)粘性session
worker.loadbalancer.sticky_session_force=0 #設置當多次請求未響應,請求将轉發
worker.status.type=status
#
# end workers.properties
負載均衡集群配置(8):Apache配置——設置apache對項目的(de)訪問路徑
修改/apache/conf/目錄下的(de)httpd.conf文件中的(de)DocumentRoot和(hé)Directory值,将文件訪問路徑定位到tomcat的(de)webapps文件夾,即待發布項目的(de)存放位置,修改結果如(rú)下:
DocumentRoot"/usr/local/apache-tomcat-7.0.47/webapps"
<Directory"/usr/local/apache-tomcat-7.0.47/webapps">
Require all granted
Orderallow,deny
Allow from all
</Directory>
如(rú)此對apache的(de)修改完成,加之tomcat設置了默認訪問項目,此時就可(kě)以實現直接通過apache所在主機的(de)IP地(dì)址來訪問項目。(實際配置中,是否實現IP地(dì)址直接訪問以實際需求為(wèi)準)
負載均衡集群Session測試(1):創建測試工程SessionTest
① 新建一(yī)個Java Web工程SessionTest,在工程下新建index.jsp,文件內(nèi)容如(rú)下:
<%@ pageimport="java.util.*" %>
<html>
<head>
<title> Session Test</title>
</head>
<body bgcolor="red">
<%
out.print("session Id:"+session.getId());
%>
<formaction="index.jsp" method="post">
key<input type="text" name="key"/>
<br />
value<input type="text"name="value" />
<br />
<input type="submit"value="Submit" />
<br />
</form>
<%
String key =request.getParameter("key");
if(key!=null &&key.isEmpty()==false)
{
String value =request.getParameter("value");
session.setAttribute(key, value);
Enumeration e =session.getAttributeNames();
while (e.hasMoreElements())
{
String sKey = (String)e.nextElement();
String sValue = (String)session.getAttribute(sKey);
out.print(sKey+ " ="+sValue+"<br>");
}
}
%>
</body>
</html>
② 修改SessionTest的(de)web.xml,在web.xml末尾的(de)</web-app>标簽裏添加<distributable/>。
③ 将該項目放入同一(yī)組的(de)tomcat的(de)webapps下,并且使同一(yī)組的(de)每個tomcat的(de)項目中index.jsp的(de)<bodybgcolor="red"> 顔色選用不同的(de)顔色。(此處tomcat1為(wèi)red,tomcat2為(wèi)green)
負載均衡集群Session測試(2):session粘性測試
啓動同組tomcat以及apache。浏覽器訪問apache所在的(de)主機IP地(dì)址:http://172.18.145.201/, 顯示如(rú)圖一(yī)所示頁面。從頁面顯示的(de)session Id可(kě)以看出請求訪問的(de)是tomcat1。
如(rú)圖二所示,發現多次刷新或submit後,請求訪問的(de)一(yī)直是tomcat1,并且session Id一(yī)直保持不變,session中的(de)數據也能夠保持,說明session粘性良好。
啓動同組tomcat以及apache。浏覽器訪問apache所在的(de)主機IP地(dì)址:http://172.18.145.201/,從頁面顯示的(de)session Id可(kě)以看出請求訪問的(de)是tomcat1。提交幾組session數據,顯示結果如(rú)圖一(yī)所示。
此時停掉tomcat1,再次提交session數據,或刷新頁面,結果如(rú)圖二所示,發現請求被轉發給tomcat2,頁面訪問正常。頁面顔色改變,但Session Id保持不變,session數據也全部傳遞給tomcat2,表明session複制良好。
/usr/local/apache-tomcat-7.0.47/bin/catalina.shstart
/usr/local/apache/bin/apachectlstart