Apache + Tomcat + mod_jk實現集羣服務及session共享

實現效果:用apache 分發請求到tomcat中的對應的項目 css

原理:html

環境說明:java

操做系統:win7   64位
node

Javajdk: 1.7 
Apache:httpd-2.2.25-win32-x86-no_ssl.msi    (本地安裝路徑:D:\Program Files (x86)\Apache2.2\)
Tomcat: 7.0.42  ( http://tomcat.apache.org/download-70.cgi ),若是在同一臺機器上模擬,下載zip版本. 實例中展現了2個節點
mod_jk: mod_jk1.2.30_x64:  ( http://tomcat.apache.org/download-connectors.cgi )
linux

安裝步驟:web

1.安裝jdk
2.安裝Apache2.2,使用默認設置,而且安裝路徑中不要空格.
3.解壓tomcat
4.拷貝mod_jk.so到Apache安裝路徑的modules文件夾下
express

 

配置步驟apache

 

修改Apache配置:tomcat

 

關於修改涉及到的文件httpd.conf和workers.properties文件能夠下載一份mod_jk的源碼包參看服務器

 

   1.修改Apache配置文件httpd.conf(筆者路徑:D:\Program Files (x86)\Apache2.2\conf\httpd.conf), 在最後一行末尾添加:

 

include "D:\Program Files (x86)\Apache2.2\conf\mod_jk.conf"
2. 在httpd.conf 同目錄下新建mod_jk.conf文件
#指定模塊路徑
LoadModule jk_module modules/mod_jk-1.2.31-httpd-2.2.3.so
#指定 workers.properties文件路徑
JkWorkersFile conf/workers.properties
#指定哪些請求交給tomcat處理,"controller"爲在workers.propertise裏指定的負載分配控制器名
JkMount /* controller

#指定jk的日誌輸出文件
JkLogFile logs/mod_jk.log
#指定日誌級別,我這裏設置的警告
JkLogLevel warn
#包含標準的mod_jk行爲 (默認)
#info
#包含錯誤信息
#error
#用來配置log文件的日期/時間格式. 使用strftime()的格式化字符串,默認是[%a %b %d %H:%M:%S %Y]
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"    

#Options Description(選項的說明)
# %b 發送的字節, 不包括 HTTP headers (CLF format)
# %B 發送的字節, 不包括 HTTP headers
# %H 協議
# %m 請求方式(get/post)
# %p 服務器響應請求的規範端口.
# %q 查詢字符串 (若是存在以?開頭,不然是空串)
# %r 請求的第一行.
# %s HTTP狀態碼
# %T 請求間隔, 處理請求耗費的時間 秒.微秒
# %U 請求的url路徑,不包含查詢字符串.
# %v 響應請求的規範服務器名字
# %V 根據UseCanonicalName設置的服務器名字.
# %w Tomcat worker 名字
#JkRequestLogFormat 設置我的用戶請求的log格式.
JkRequestLogFormat "%w %V %T"

3.在httpd.conf同目錄下新建 workers.properties文件

#這裏能夠配置任意多個Tomcat,此處配置了2個Tomat服務器.
#host和port根據本身實際配置.實例配置的是本機兩個tomcat,分別使用不一樣的端口.避免衝突
#若是Tomcat再也不同一機器上,不必改端口的。


#server 列表
worker.list=controller,status,tomcat1,tomcat2 

#========tomcat1========

worker.tomcat1.port=9988  #ajp13 端口號,在tomcat下server.xml配置,默認8009
worker.tomcat1.host=192.168.0.47        #tomcat的主機地址,如不爲本機,請填寫ip地址
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor=1  #server的加權比重,值越高,分得的請求越多
  

#========tomcat2========

worker.tomcat2.port=9999        #ajp13 端口號,在tomcat下server.xml配置,默認8009
worker.tomcat2.host=192.168.0.47        #tomcat的主機地址,如不爲本機,請填寫ip地址
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=1        #server的加權比重,值越高,分得的請求越多 



#========controller,負載均衡控制器========
worker.controller.type=lb


#指定此負載平衡器負責的Tomcat應用節點。

worker.controller.balance_workers=tomcat1,tomcat2   #指定分擔請求的tomcat

#此處指定集羣是否須要會話複製,若是設爲true,則代表爲會話粘性,不進行會話複製,當某用戶的請求第一次分發到哪臺
#Tomcat後,後繼的請求會一直分發到此Tomcat服務器上處理;若是設爲false,則代表需求會話複製。
worker.controller.sticky_session=false
#描述是用於httpd自身狀態監控的status
worker.status.type=status

4.在httpd.conf同目錄下新建 uriworkermap.properties文件(未測試是否對集羣有影響)

/*=controller                       
/jkstatus=status                   
!/*.gif=controller                  
 !/*.jpg=controller 
!/*.png=controller 
!/*.css=controller 
!/*.js=controller 
!/*.htm=controller 
!/*.html=controller

 修改Tomact配置:(tomcat 6.0.36  能夠實現集羣  ,可是session沒有共享。緣由未找到)(tomcat 7.0.42 實現集羣及session共享)

 

以 tomcat 7.0.42  爲實例

1.修改分發tomcat對應的service.xml文件,保證Apache對應的 workers.properties中的AJP13的connector的port. 

<!-- 定義一個AJP 1.3 鏈接端口爲9988 ,默認值爲8009,這裏咱們改爲咱們本身定義的9988端口 --> <Connector port="9988" protocol="AJP/1.3" redirectPort="8443" />

2.增長jvmRoute的值,保證同workers.properties裏邊配置的值一致

<!--增長jvmRoute,值爲在Apache中配置的list集羣結點中的值,這裏定義爲tomcat1結點--> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

3.去掉默認註釋掉的集羣配置

<!--取消集羣結點相關的註釋,該句默認值註釋掉的,咱們須要配置集羣因此去掉註釋,讓其起做用--> <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

 

4.實例中咱們的兩個tomcat結點在同一臺機器上,因此還須要保證protocol="HTTP/1.1"的端口不一致.否則本地的兩個tomcat會起衝突

下面爲筆者實例中解決同一臺機器上多個tomcat服務器之間端口衝突作的修改.

 

實例測試

   1.在web.xml文件中增長

<distributable/>

2.編寫測試jsp代碼 
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="java.text.SimpleDateFormat"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Tomcat集羣測試</title>
  </head>
  
  <body> 服務器信息: <%
      String dtm = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()); System.out.println("["+request.getLocalAddr()+":"+ request.getLocalPort()+"]" + dtm); out.println("<br>["+request.getLocalAddr()+":" +request.getLocalPort()+"]" + dtm+"<br>"); %> session分發: <% session.setAttribute("name","dennisit"); System.out.println("[session分發] session id:"+session.getId()); out.println("<br>[session分發] session id: " + session.getId()+"<br>"); %>
  </body>
</html>

3.測試負載均衡與session分發

將項目部署到每一個集羣結點中,即實例中的tomcat_node1和tomcat_node2,依次移動Apache和tomcat服務器,tomcat服務器之間的啓動順序隨意.這裏Apache端口使用默認的80.

上面是在FireFox中運行項目後刷新3次執行的效果,能夠看到2個tomcat分發結點之間輪流負載.並且兩臺服務器上的session值是同樣的.說明session分發成功.

兩臺Tomcat服務器日誌打印輸出結果:

錯誤解決:

    (1)apache 服務器沒法加載jk代理

                        緣由:apache 和 mod_jk  版本差別致使。解決辦法,將mod_jk.so替換爲 mod_jk-1.2.31-httpd-2.2.3.so。

    (2)apache 服務器沒法啓動

                      緣由:httpd.conf  配置文件有誤。首次安裝能夠啓動。你改動有誤。

 其餘

     附上tomcat  6   與tomcat  7   server.xml  對比代碼:

tomcat  6  

<?xml version='1.0' encoding='utf-8'?>
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -->
<!-- Note:  A "Server" is not itself a "Container", so you may not define subcomponents such as "Valves" at this level. Documentation at /docs/config/server.html -->
<Server port="8005" shutdown="SHUTDOWN">

  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />


  <!-- Global JNDI resources Documentation at /docs/jndi-resources-howto.html -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by UserDatabaseRealm to authenticate users -->
    <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" />
  </GlobalNamingResources>

  <!-- A "Service" is a collection of one or more "Connectors" that share a single "Container" Note:  A "Service" is not itself a "Container", so you may not define subcomponents such as "Valves" at this level. Documentation at /docs/config/service.html -->
  <Service name="Catalina">
  
    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
    -->
    
    
    <!-- A "Connector" represents an endpoint by which requests are received and responses are returned. Documentation at : Java HTTP Connector: /docs/config/http.html (blocking & non-blocking) Java AJP Connector: /docs/config/ajp.html APR (HTTP/AJP) Connector: /docs/apr.html Define a non-SSL HTTP/1.1 Connector on port 8080
    -->
    <Connector port="9008" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
    -->           
    <!-- Define a SSL HTTP/1.1 Connector on port 8443 This connector uses the JSSE configuration, when using APR, the connector should be using the OpenSSL style configuration described in the APR documentation -->
    <!--
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" />
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="9988" enableLookups="false" protocol="AJP/1.3" redirectPort="8443" />

    <!--For clustering-->
    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
<!--    <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster" managerClassName="org.apache.catalina.cluster.session.DeltaManager" expireSessionsOnShutdown="false" useDirtyFlag="true" notifyListenersOnReplication="true">

            <Membership className="org.apache.catalina.cluster.mcast.McastService" mcastAddr="228.0.0.4" mcastPort="45564" mcastFrequency="500" mcastDropTime="3000"/>

            <Receiver className="org.apache.catalina.cluster.tcp.ReplicationListener" tcpListenAddress="auto" tcpListenPort="4001" tcpSelectorTimeout="100" tcpThreadCount="6"/>

            <Sender className="org.apache.catalina.cluster.tcp.ReplicationTransmitter" replicationMode="pooled" ackTimeout="15000" waitForAck="true"/>

            <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
                  
            <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/>
                     
            <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
        </Cluster>


          
-->


    <!-- An Engine represents the entry point (within Catalina) that processes every request. The Engine implementation for Tomcat stand alone analyzes the HTTP headers included with the request, and passes them on to the appropriate Host (virtual host). Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie : <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">         
    --> 
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

      <!--For clustering, please take a look at documentation at: /docs/cluster-howto.html (simple how to) /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->        

      <!-- The request dumper valve dumps useful debugging information about the request and response data received and sent by Tomcat. Documentation at: /docs/config/valve.html -->
      <!--
      <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
      -->

      <!-- This Realm uses the UserDatabase configured in the global JNDI resources under the key "UserDatabase". Any edits that are performed against this UserDatabase are immediately available for use by the Realm.  -->
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>

      <!-- Define the default virtual host Note: XML Schema validation will not work with Xerces 2.2. -->
      <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
      <!-- <context docBase= "e:\webapps\tomcat_apche" path="/tomcat_apche"  debug="0" reloadable="true"/> -->
      <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example. Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
        -->

      </Host>
    </Engine>
  </Service>
</Server>
View Code

tomcat  6  死活沒弄出來session 共享  即便加上各位大神的以下代碼。(無心冒犯,就事說事。)

http://www.linuxidc.com/Linux/2012-08/69311p2.htm

tomcat  7

<?xml version='1.0' encoding='utf-8'?>
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -->
<!-- Note:  A "Server" is not itself a "Container", so you may not define subcomponents such as "Valves" at this level. Documentation at /docs/config/server.html -->
<Server port="8005" shutdown="SHUTDOWN">
  <!-- Security listener. Documentation at /docs/config/listeners.html <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources Documentation at /docs/jndi-resources-howto.html -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by UserDatabaseRealm to authenticate users -->
    <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" />
  </GlobalNamingResources>

  <!-- A "Service" is a collection of one or more "Connectors" that share a single "Container" Note:  A "Service" is not itself a "Container", so you may not define subcomponents such as "Valves" at this level. Documentation at /docs/config/service.html -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received and responses are returned. Documentation at : Java HTTP Connector: /docs/config/http.html (blocking & non-blocking) Java AJP Connector: /docs/config/ajp.html APR (HTTP/AJP) Connector: /docs/apr.html Define a non-SSL HTTP/1.1 Connector on port 8080
    -->
    <Connector port="9008" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
    -->
    <!-- Define a SSL HTTP/1.1 Connector on port 8443 This connector uses the JSSE configuration, when using APR, the connector should be using the OpenSSL style configuration described in the APR documentation -->
    <!--
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" />
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="9988" protocol="AJP/1.3" redirectPort="8443" />


    <!-- An Engine represents the entry point (within Catalina) that processes every request. The Engine implementation for Tomcat stand alone analyzes the HTTP headers included with the request, and passes them on to the appropriate Host (virtual host). Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie : -->
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
   
    <!--<Engine name="Catalina" defaultHost="localhost">-->

      <!--For clustering, please take a look at documentation at: /docs/cluster-howto.html (simple how to) /docs/config/cluster.html (reference documentation) -->
      <!-- -->
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
     

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI resources under the key "UserDatabase". Any edits that are performed against this UserDatabase are immediately available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>
View Code

比較不錯的大牛參考博文:

     Apache+Tomcat負載均衡兩種session共享方式的設置:http://blog.sina.com.cn/s/blog_5f53615f0100p4fj.html

     Apache + Tomcat + mod_jk實現集羣服務:http://www.linuxidc.com/Linux/2015-02/114231.htm

     Apache2+Tomcat7+mod_jk2.2.3集羣負載均衡配置(目前最強悍)

相關文章
相關標籤/搜索