天天看點

解說Apache+Tomcat+JK實作Tomcat的負載和叢集 解說Apache+Tomcat+JK實作Tomcat的負載和叢集

  好長時間沒更新部落格了,今天終于把Apache與Tomcat的結合研究出來了,不多說了還是把過程寫出來吧。

實作環境

  虛拟機上實作的: 作業系統:Cetnost 5.4 核心:2.6.18-194.el5 

server1: ip 192.168.1.107  255.255.255.0

server2:ip 192.168.1.139   255.255.255.0

 2. 所用的到軟體

httpd-2.2.22.tar.gz

apache-tomcat-6.0.35.tar.gz

tomcat-connectors-1.2.37-src.tar.gz(apache與Tocmat的連接配接器)

jdk-6u33-linux-i586-rpm.bin

 3. 安裝前的準備

安裝需要的編譯程式

# yum -y install gcc gcc-c++ gcc-gfortran ncurses-devel 

 4. 下面開始準備安裝

  安裝JDK

因為Cetnos系統會自帶一個java版本,要把自帶的java版本卸掉。

檢視版本: 

# java -version  

java version "1.6.0_18"  

Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0_18-b02)  

Java HotSpot(TM) Client VM (build 1.6.0_18-b02, mixed mode, sharing)  

檢視JDK軟體包名稱: 

# rpm -qa | grep jdk  

java-1.6.0-openjdk-1.6.0.0-1.7.b09.el5  

解除安裝: 

# yum -y remove java-1.6.0-openjdk-1.6.0.0-1.7.b09.el5  

# rpm -qa | grep gcj  

libgcj-4.1.2-48.el5     

java-1.4.2-gcj-compat-1.4.2.0-40jpp.115  

# yum -y remove libgcj-4.1.2-48.el5 java-1.4.2-gcj-compat-1.4.2.0-40jpp.115  

解除安裝完成 

完成之後,再來檢視java的版本 

# java -version 

-bash: java: command not found 

說明解除安裝完成。 

下面開始安裝JDK

我把有的軟體都放在了/setup/這個目錄下了,下面來安裝吧

# cd /setup/jdk/  

# chmod +x jdk-6u33-linux-i586-rpm.bin   

要執行這個檔案要用到root使用者

#./jdk-6u33-linux-i586-rpm.bin  

根據所顯示的提示資訊很順利就能安裝完成。

預設安裝在 /usr/java 目錄下,我們做一個軟連接配接

# ln -s /usr/java/jdk1.6.0_33/ /usr/local/java  

設定環境變量 

# vi /etc/profile  

安"i"進入編輯模式  

在最後加入:  

export JAVA_HOME=/usr/java/jdk1.6.0_33  

export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar  

export PATH=$PATH:$JAVA_HOME/bin  

儲存退出 !  

使生效: # source /etc/profile  

完成後再來檢視版本資訊

java version "1.6.0_33"  

Java(TM) SE Runtime Environment (build 1.6.0_24-b07)  

Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)  

Apache的安裝

# cd /setup/apache  

# tar zxvf httpd-2.2.22.tar.gz  

# cd httpd-2.2.22  

# ./configure --prefix=/usr/local/apache  

# make  

# make install  

這裡的apche隻指定了安裝目錄其他的都是預設。 

下面來啟動一下

# /usr/local/apache/bin/apachectl start  

接着就要檢視80端口是否啟動。

Apache與Tomcat的連接配接器的安裝

開始安裝apache與Tomcat的連接配接器 tomcat-connectors-1.2.37-src.tar.gz

# cd /setup/tomcat  

# tar zxvf tomcat-connectors-1.2.37-src.tar.gz  

# cd tomcat-connectors-1.2.37-src/native/  

# ./configure --with-apxs=/home/fisuser/FIS/apache/bin/apxs  

安裝完成之後就會在 /usr/local/apache/modules/目錄中有一個mod_jk.so

# ls 

httpd.exp  mod_jk.so 

這樣Apache與Tomcat的連接配接器安裝成功了。

下面來安裝一下Tocmat

這個軟體不用編譯的,解壓後就可以用了。

# cd /setup/tomcat   

# tar zxvf apache-tomcat-6.0.35.tar.gz   

# mv apache-tomcat-6.0.35 app1  

# echo "JAVA_HOME=/usr/java/jdk1.6.0_33" >> /app1/bin/catalina.sh  

接下來,就可以試着啟動一下。

# /setup/tomcat/app1/bin/catalina.sh start 

檢視端口是否啟動起來

# netstat -tlnp  

tcp        0      0 ::ffff:127.0.0.1:8005       :::*                        LISTEN      26633/java            

tcp        0      0 :::8009                     :::*                        LISTEN      26633/java            

tcp        0      0 :::8080                     :::*                        LISTEN      26633/java     

有這三個端口,說明Topmcat啟動正常,你可以用浏覽器來打開,一定能看到那個“貓”。

在第二台虛拟中隻要有個Tomcat就行了,所有要在第二台虛拟中安裝上JDK,Tomcat就可以了。

到此,Tomcat JDK Apache JK 安裝完成,下面開始核心部分連接配接Apache與Tomcat,并實作Tomcat的負載和叢集。

 5. 配置Apache與Tomcat

配置Apache

編輯Apache的httpd.conf檔案

所要做工作就是開啟虛拟主機,并加上mod_jk.conf這個子產品,如下所示:

# cp httpd.conf httpd.conf.bak (改變之前要備份一下) 

# vim httpd.conf  

在httpd.conf檔案中找到:“Include conf/extra/httpd-vhosts.conf”把前的#号去掉即可。  

接着在後面加入一行:  

Include conf/mod_jk.conf  

完成之後,首來做虛拟主機吧。

# cd /usr/local/apache/conf/extra  

# vim httpd-vhosts  

把原有的虛拟主機注釋掉,加入如下所示的行:  

<VirtualHost *:80>  

    ServerName www.zhou.com  

    JkMountFile conf/uriworkermap_app1.properties  

</VirtualHost>  

在這裡我們看到有兩個我們不明白的一個就是mod_jk.conf, 一個就是:

uriworkermap_app1.properties

這兩個檔案中做什麼的,接着看下面:

先來建立mod_jk.conf這個檔案,這個檔案當然是在/usr/local/apache/conf/這個目錄下建立了,在httpd.conf中你指定的目錄,我指定的是這個目錄,是以我在這個目錄下建立。内容如下:

# vim mod_jk.conf  

LoadModule jk_module modules/mod_jk.so    

JkWorkersFile conf/workers.properties    

JkLogFile "logs/mod_jk.log"    

JkLogLevel info    

JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"    

JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories    

JkRequestLogFormat "%w %V %T"    

JkShmFile logs/jk.shm    

HostnameLookups Off   

在這裡說明一下檔案的内容:

第一句是加載mod_jk.so這個子產品的。

第二名是JKWorkersFile 指定負載均衡伺服器的配置檔案,檔案名為相對于apache伺服器所在目錄的

第三句是JKLogFile 指定JK連接配接器的日志輸出檔案,檔案為相對于apache伺服器所在目錄的logs/mod_jk.log檔案

第四句:JKLogLevel 是指的日志級别。級别為warn以上的日志将被輸出到日志檔案中,可選的值級别由低到高分别為:TRACE DEBUG INFO WARN ERROR FATAL

下面的幾句我也不知道是什麼意思,這個是在網上找的某大神的作品,

好了,下面再來說一下,workers.properties這個檔案

同樣在/usr/local/apache/conf/目錄下建立,内容如下:

worker.list=tomcat,jkstatus    

#107     

worker.server107.port=8009   

worker.server107.host=192.168.1.107    

worker.server107.type=ajp13   

worker.server107.lbfactor=10    

worker.server107.cachesize=5   

#139    

worker.server139.port=8009   

worker.server139.host=192.168.1.139    

worker.server139.type=ajp13   

worker.server139.lbfactor=10   

worker.server139.cachesize=5   

worker.tomcat.type=lb   

worker.tomcat.balance_workers=server107, server139  

worker.tomcat.sticky_session_force=false  

worker.jkstatus.type=status 

worker.jkstatus.mount=/admin/jk  

worker.retries=3  

解釋一下:

worker.list 是定義了兩個工作清單:一個是tomcat,一個是jkstatus 。在tomcat清單中定義了兩個tomcat_server,一個是:server107,一個是:server139。

worker.server107.port=8009 是定義了端口号,一定是tomcat中server.xml中的8009 。這裡我是在兩台不同機器上的虛拟機做的,是以端口号沒有改變。如果是在一台虛拟上做的兩個Tomcat,那麼隻需要第二個Tomcat的端口号設定的與第一個Tomcat的端口号不同就行了,具體随意,隻要能用就行。

worker.server107.host 這個是定義主機。

worker.server107.type=ajp13 JK子產品實作負載均衡采用的是AJP協定1.3版本,是以第一台負載均衡伺服器的類型配置為ajp13

worker.server107.lbfactor 第一台負載均衡伺服器在整個負載均衡系統中所占的權重,這裡配置為10,權重越大,越有可能處理更多的請求,建議給性能好的機器配置更高的權重。

worker.s1.cachesize:apache伺服器是多線程的,tomcat能夠利用這一優勢來維持一定數量的連接配接作為緩存。根據使用者的多少來配置一個合适緩存連接配接數量有助于提高性能。這裡配置為5

下面的都相同了,如果有多個Tomcat同樣一樣的配置,所用的參數自己來調即可。

worker.tomcat.type=lb  這個是配置tomcat的類型為“lb”也就是Load Balance負載均衡。

worker.tomcat.balance_workers=server107,server139 這個是負載均衡的兩個tomat的server名稱。

worker.tomcat.sticky_session_force=flase 

  設定負載均衡是否采用粘性會話。如果該屬性設定為true,假設一個請求被server107處理了,下次來源于同一個用戶端的請求也将被server107處理。直到server107已經達到最大連接配接數,JK才會将會話切換到其他伺服器上。但是如果恰巧一直負責處理該會話的伺服器down掉了,則會話将會丢失,明顯的故障現象就是關于session的操作會出現莫名其妙的錯誤(例如你所運作的應用中使用者可能已經登入了,但突然在一次通路後莫名其妙地提示沒有登入)。這裡配置為false,不啟用粘性會話,讓伺服器都有機會處理請求,提高了系統的穩定性。

worker.jk_watcher.type=status 這裡配置為status,用于監視各個負載均衡伺服器執行個體的運作狀态

worker.jk_watcher.mount=/tomcat/jk 設定名稱為“jk_watcher”的worker(負載均衡伺服器執行個體螢幕)的挂載路徑,這裡配置為/tomcat/jk

worker.retries=5 這是worker全局的重試次數。在apache伺服器啟動後,會最多嘗試若幹次去連接配接這些負載均衡伺服器,若連接配接不上就認為是down掉了,這裡配置為3

下面再來說一下 uriworkermap_app1.properties 這個檔案

這個檔案的作用是告訴apache伺服器哪些請求由負載均衡伺服器處理,檔案内容如下:

/*=tomcat 

/jkstatus=jk_watcher 

!/*.gif=tomcat 

!/*.jpg=tomcat 

!/*.tif=tomcat 

!/*.png=tomcat 

說明一下,在配置檔案中,以“!”開頭的條件表示“不要”,“=”表示交給。

/*=tomcat

其中“/*”表示所有的請求都給tomcat(就是在worker.properties中定義的那個worker.list中的tomcat)

/jkstatus=jk_watcher

!/*.gif=tomcat

!/*.jpg=tomcat

!/*.tif=tomcat

!/*.png=tomcat

這些表示以“.gif”等結尾的不交于tomcat處理。

以上完成了在Apache上的配置,下面先來配置Tocmat中的sever.xml檔案來實作簡單的負載均衡。

下面來配置tomcat的負載均衡。在server1=192.168.1.107上完成

在apache中完成了配置後,就來配置Tomcat

# cd /setup/tomcat/app1/conf/

編輯server.xml這個檔案

所要做的工作是,如果是在同一台機器上做的,就要改端口了,所要改的端口如下:

<Server port="8005" shutdown="SHUTDOWN">

<Connector port="8080" protocol="HTTP/1.1" redirectPort="8443" />

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

這裡顯示的是檔案中原始的端口,隻要改這三個端口就可行了。

下面來配置來實作tomcat的負載,在配置檔案中找到:

<Engine name="Catalina" defaultHost="localhost">

改變為:

<Engine name="Catalina" defaultHost="localhost" jvmRoute="server139">

這裡說明一下,句主要是jvmRoute這個參數,這個參數配置為server139,這個是在worker.properties定義的一個server,配置後就會實作107上的請求會轉發到139上去,來實作負載,同樣在server2=192.168.1.139的上配置也是相同的,隻是jvmRoute的參數變為“server107”.這樣完成後,就可以測試一下了,這裡有個測試的檔案,index.jsp 檔案内容如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 

<html> 

  <head>     

    <title>My JSP 'index.jsp' starting page</title> 

    <meta http-equiv="pragma" content="no-cache"> 

    <meta http-equiv="cache-control" content="no-cache"> 

    <meta http-equiv="expires" content="0">     

    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 

    <meta http-equiv="description" content="This is my page"> 

    <!-- 

    <link rel="stylesheet" type="text/css" href="styles.css"> 

    --> 

  </head> 

  <body> 

    This is my JSP page. <br> 

  </body> 

</html> 

把這個檔案放到webapps目錄下的test目錄當然要先建立這個目錄。要兩tomcat中都要放入。

下面是測試的結果:

<a href="http://blog.51cto.com/attachment/201209/104346892.jpg" target="_blank"></a>

重新整理後結果:

<a href="http://blog.51cto.com/attachment/201209/104402773.jpg" target="_blank"></a>

結果不同,是因為我放的網頁不相同,使得結果更加清楚的顯示出來。

這樣就簡單的實作的Tomcat的負載均衡。

下面來配置叢集:

同樣是編輯server.xml檔案

改變後的檔案如下所示:

&lt;?xml version='1.0' encoding='utf-8'?&gt; 

&lt;Server port="8005" shutdown="SHUTDOWN"&gt; 

  &lt;Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /&gt;  

  &lt;Listener className="org.apache.catalina.core.JasperListener" /&gt; 

  &lt;Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /&gt; 

  &lt;Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" /&gt; 

  &lt;Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /&gt; 

  &lt;GlobalNamingResources&gt; 

    &lt;Resource name="UserDatabase" auth="Container" 

              type="org.apache.catalina.UserDatabase" 

              description="User database that can be updated and saved"             factory="org.apache.catalina.users.MemoryUserDatabaseFactory" 

              pathname="conf/tomcat-users.xml" /&gt; 

  &lt;/GlobalNamingResources&gt; 

  &lt;Service name="Catalina"&gt;  

    &lt;Connector port="8080" protocol="HTTP/1.1" minProcessors="10" maxProcessors="1024" enableLookups="false" acceptCount="1024"  

               connectionTimeout="20000" useBodyEncodingForURI="true" URIEncoding="utf-8" compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla,traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 

               redirectPort="8443" /&gt; 

    &lt;Connector port="8009" protocol="AJP/1.3" redirectPort="8443" useBodyEncodingForURI="true" URIEncoding="utf-8"/&gt; 

    &lt;Engine name="Catalina" defaultHost="localhost" jvmRoute="server107"&gt; 

      &lt;Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"&gt; 

      &lt;Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" 

                     notifyListenersOnReplication="true"/&gt; 

      &lt;Channel className="org.apache.catalina.tribes.group.GroupChannel"&gt; 

           &lt;MemberShip className="org.apache.catalina.tribes.membership.McastService" 

                       bind="192.168.1.139" 

                       address="228.0.0.4" 

                       port="45564" 

                       frequency="500" 

                       droptTime="3000"/&gt; 

           &lt;Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" 

                     address="192.168.1.139" 

                     port="4000" 

                     autoBind="100" 

                     selectorTimeout="5000" 

                     maxThreads="6"/&gt; 

           &lt;Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"&gt; 

               &lt;Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/&gt; 

           &lt;/Sender&gt; 

           &lt;Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/&gt; 

           &lt;Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/&gt; 

      &lt;/Channel&gt; 

      &lt;Valve className="org.apache.catalina.ha.tcp.ReplicationValve"        filter=".*\.gif;.*\.js;.*\.jpg;.*\.htm;.*\.html;.*\.txt;"/&gt; 

      &lt;Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/&gt; 

      &lt;ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/&gt; 

      &lt;ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/&gt; 

      &lt;/Cluster&gt;              

      &lt;Realm className="org.apache.catalina.realm.UserDatabaseRealm" 

             resourceName="UserDatabase"/&gt; 

      &lt;Host name="localhost"  appBase="webapps" 

            unpackWARs="true" autoDeploy="true" 

            xmlValidation="false" xmlNamespaceAware="false"&gt; 

      &lt;/Host&gt; 

    &lt;/Engine&gt; 

  &lt;/Service&gt; 

&lt;/Server&gt; 

這個是去掉注釋的部分後的檔案内容,其中橙色部分是配置叢集的部分這些要手動寫進去的。其中“bind="192.168.1.139" ”這個server2=192.168.1.139上的叢集配置。在107上要寫成107的ip位址。如果是在同一台機器上的兩個tomcat,這個ip可以一樣,隻是下面的端口要改變一下。也就是這相要變一下port="45564“

這裡的配置還能實作session同享。這裡也有個測試的網頁。test.jsp

内容如下:

&lt;%@ page contentType="text/html; charset=utf-8" %&gt; 

&lt;%@ page import="java.util.*" %&gt; 

&lt;html&gt;&lt;head&gt;&lt;title&gt;Cluster App Test&lt;/title&gt;&lt;/head&gt; 

&lt;body&gt; 

Server Info: 

&lt;% 

out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"&lt;br&gt;");%&gt; 

  out.println("&lt;br&gt; ID " + session.getId()+"&lt;br&gt;"); 

  // 如果有新的 Session 屬性設定 

  String dataName = request.getParameter("dataName"); 

  if (dataName != null &amp;&amp; dataName.length() &gt; 0) { 

     String dataValue = request.getParameter("dataValue"); 

     session.setAttribute(dataName, dataValue); 

  } 

  out.println("&lt;b&gt;Session 清單&lt;/b&gt;&lt;br&gt;"); 

  System.out.println("============================"); 

  Enumeration e = session.getAttributeNames(); 

  while (e.hasMoreElements()) { 

     String name = (String)e.nextElement(); 

     String value = session.getAttribute(name).toString(); 

     out.println( name + " = " + value+"&lt;br&gt;"); 

         System.out.println( name + " = " + value); 

   } 

%&gt; 

  &lt;form action="test.jsp" method="POST"&gt; 

    名稱:&lt;input type=text size=20 name="dataName"&gt; 

     &lt;br&gt; 

    值:&lt;input type=text size=20 name="dataValue"&gt; 

    &lt;input type=submit&gt; 

   &lt;/form&gt; 

&lt;/body&gt; 

也是放在test那個目錄下

測試結果如下:

<a href="http://blog.51cto.com/attachment/201209/110559715.jpg" target="_blank"></a>

重新整理後的結果:

<a href="http://blog.51cto.com/attachment/201209/110623240.jpg" target="_blank"></a>

這樣就看的很清楚兩個tomcat的負載

下面來看是否session同步

名稱和值中輸入:1,1、2,2、3,3

結果如下所示:

<a href="http://blog.51cto.com/attachment/201209/110958919.jpg" target="_blank"></a>

<a href="http://blog.51cto.com/attachment/201209/111015555.jpg" target="_blank"></a>

這樣可以清楚的看到session共享成功。

以上就是整個Apache與Tomcat的結合的整個過程,還有許多地方可能不是太正确,希望高人來指定一下。

 本文轉自 ZhouLS 51CTO部落格,原文連結:http://blog.51cto.com/zhou123/981560