注意本文不討論原理,只講述具體的搭建過程,並且步驟都通過了整理,不然過程可能會出現其餘異常,請自行google。apache與tomcat整合的方式除了jk以外,使用apache自帶的mod_ajp_proxy模塊也能夠很方便的完成。
先來看一下架構圖:
屬於正式環境中原session複製方案的改進。css
jrrt-3.1.2-1.6.0-linux-x64.bin(或jdk1.6.0_33) jvm httpd-2.2.26.tar.gz web服務器,處理靜態資源 apache-tomcat-6.0.32.tar.gz 應用服務器,Servlet容器處理動態請求 tomcat-connectors-1.2.30-src.tar.gz apache與tomcat整合插件mod_jk.so tomcat-native.tar.gz APR加速tomcat,提升線程併發能力。使用tomcat自帶版本。 memcached-session-manager 使用msm解決多tomcat集羣時session同步問題所需jar包 asm-3.2.jar, couchbase-client-1.2.2.jar, kryo-1.04.jar, kryo-serializers-0.11.jar msm-kryo-serializer-1.6.5.jar memcached-session-manager-1.6.5.jar memcached-session-manager-tc6-1.6.5.jar minlog-1.2.jar, reflectasm-1.01.jar spymemcached-2.10.2.jar
下載將JRockit二進制安裝文件,賦予可執行權限html
# pwd /apps/test/java # chmod o+x jrrt*.bin # ./jrrt-3.1.2-1.6.0-linux-x64.bin
可沒必要爲整個linux環境設置JAVA_HOME="/apps/test/java/jrrt-3.1.2-1.6.0"
,在tomcat中指定便可。java
由於tomcat-native
依賴於apr,因此這裏先直接從 httpd-2.2.26/srclib 目錄下安裝apache自帶的apr
和apr-util
。node
[root@cachets httpd-2.2.26]# pwd /apps/test/soft_src/httpd-2.2.26 [root@test httpd-2.2.26]# cd srclib/apr [root@test apr]# ./configure --prefix=/usr/local/apr [root@test apr]# make && make install [root@test apr]# cd ../apr-util/ [root@test apr-util]# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr [root@test apr-util]# make && make install
建議將srclib下的pcre
也裝上,主要是考慮後面轉發請求時可能要使用地址rewrite,須要正則語法的支持。默認CentOS6.x已經安裝了這個庫。linux
安裝apache:web
[root@test httpd-2.2.26]# ./configure --prefix=/apps/test/apache2 --enable-mods-shared=all --enable-modules=so --enable-rewrite --enable-deflate --with-mpm=worker --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util [root@test httpd-2.2.26]# make && make install
解壓apache-tomcat-6.0.32.tar.gz拷貝至/app/test/tomcat0,不建議使用root用戶管理tomcat.apache
[test@cachets soft_src]$ tar -zxvf apache-tomcat-6.0.32.tar.gz [test@cachets soft_src]$ cp -a apache-tomcat-6.0.32 /app/crm/tomcat0 // 安裝tomcat-native(不用單獨下載,在tomcat的bin目錄中自帶) # yum install -y openssl-devel apr-devel [root@cachets ~]# cd /app/test/soft_src/apache-tomcat-6.0.32/bin [root@cachets bin]# tar -zxvf tomcat-native.tar.gz [root@cachets bin]# cd tomcat-native-1.1.20-src/jni/native/ [root@cachets native]# ./configure --with-apr=/usr/local/apr/bin/apr-1-config --with-ssl --with-java-home=/apps/test/java/jrrt-3.1.2-1.6.0 [root@cachets native]# make && make install
配置tomcat:瀏覽器
tomcat默認參數是爲開發環境制定,而非適合生產環境,尤爲是內存和線程的配置,默認都很低,容易成爲性能瓶頸。下面是一些配置示例,須要根據實際須要更改。tomcat
[crm@cachets tomcat0]$ vi bin/setenv.sh JAVA_OPTS="-XX:PermSize=128M -XX:MaxPermSize=256M -Xms1536M -Xmx2048M -verbosegc " CATALINA_OPTS="-Dcom.sun.management.jmxremote.port=7091 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.10.100" JAVA_HOME="/apps/test/java/jrrt-3.1.2-1.6.0" CATALINA_OPTS="$CATALINA_OPTS -Djava.library.path=/usr/local/apr/lib" [crm@cachets tomcat0]$ chmod 755 bin/setenv.sh
bin目錄下新建的可執行文件setenv.sh
會由tomcat自動調用。上面的jmxremote.authenticate
在正式環境中請務必設爲true並設置用戶名/密碼,減小安全隱患,或者註釋掉CATALINA_OPTS
。(有時候出於性能調優的目的,才須要設置JMX)。對於具體的鏈接協議有不一樣的優化屬性,參考以下:
對HTTP:安全
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" URIEncoding="UTF-8" enableLookups="false" maxThreads="400" minSpareTheads="50" acceptCount="400" acceptorThreadCount="2" connectionTimeout="30000" disableUploadTimeout="true" compression="on" compressionMinSize="2048" maxHttpHeaderSize="16384" redirectPort="8443" />
對AJP:
<Connector port="8009" protocol="AJP/1.3" maxThreads="300" minSpareThreads="50" connectionTimeout="30000" keepAliveTimeout="30000" acceptCount="200" URIEncoding="UTF-8" enableLookups="false" redirectPort="8443" />
[crm@test soft_src]$ tar -zxvf tomcat-connectors-1.2.30-src.tar.gz [crm@test soft_src]$ cd tomcat-connectors-1.2.30-src/native [root@test native]# ./configure --with-apxs=/apps/test/apache2/bin/apxs [root@test native]# make && make install
此時能夠看到在/apps/test/apache2/modules
下有mod_jk.so
文件,用於鏈接apache與tomcat。
創建配置文件httpd-jk.conf
:
[root@cachets ~]# cd /app/test/ [root@cachets crm]# vi apache2/conf/extra/httpd-jk.conf # Load mod_jk module LoadModule jk_module modules/mod_jk.so # 指定保存了worker相關工做屬性定義的配置文件 JkWorkersFile conf/extra/workers.properties # Specify jk log file JkLogFile /app/test/apache2/logs/mod_jk.log # Specify jk log level [debug/error/info] JkLogLevel info #指定哪些請求交給tomcat處理,"controller"爲在workers.properties裏指定的負載分配控制器名 JkMount /servlet/* controller JkMount /*.jsp controller JkMount /*.do controller // 在conf/httpd.conf最後加上 Include conf/extra/httpd-vhosts.conf Include conf/extra/httpd-jk.conf
創建工做文件workers.properties
:
[root@cachets crm]# vi apache2/conf/extra/workers.properties # servers worker.list=controller # ====== tomcat0 ======= worker.tomcat0.port=8009 worker.tomcat0.host=192.168.10.100 worker.tomcat0.type=ajp13 worker.tomcat0.lbfactor=1 # ====== tomcat1 ======= worker.tomcat1.port=8109 worker.tomcat1.host=192.168.10.100 worker.tomcat1.type=ajp13 worker.tomcat1.lbfactor=1 # ====== tomcat2 ======= worker.tomcat2.port=8209 worker.tomcat2.host=192.168.10.100 worker.tomcat2.type=ajp13 worker.tomcat2.lbfactor=1 # ====== controller ==== worker.controller.type=lb worker.controller.balance_workers=tomcat0,tomcat1,tomcat2 worker.controller.sticky_session = 1
以上是3個tomcat的作負載均衡的狀況,負載因子lbfactor
都爲1,session爲sticky模式,apache與tomcat鏈接的協議採用AJP/1.3,同一臺服務器上經過端口來區分tomcat0/tomcat1/tomcat2。
在tomcat0/conf/server.xml
中加入jvmRoute
屬性,這個屬性與上面的workers.properties
的worker相同:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat0">
設置測試應用的訪問路徑,在tomcat0/conf/server.xml
的<Host>
節點下添加以下:
<Context path="" docBase="/apps/test/testapp/TEST" reloadable="true" />
爲了看到負載均衡的效果,在/apps/test/testapp/TEST
目錄下創建測試頁面test.jsp:
<%@ page contentType="text/html; charset=UTF-8" %> <%@ page import="java.util.*" %> <html><head><title>Cluster App Test</title></head> <body> Server Info: <% out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%> <% out.println("<br> ID " + session.getId()+"<br>"); // 若是有新的 Session 屬性設置 String dataName = request.getParameter("dataName"); if (dataName != null && dataName.length() > 0) { String dataValue = request.getParameter("dataValue"); session.setAttribute(dataName, dataValue); } out.println("<b>Session 列表</b><br>"); 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+"<br>"); System.out.println( name + " = " + value); } %> <form action="test.jsp" method="POST"> CRM <br> 名稱:<input type=text size=20 name="dataName"> <br> 值:<input type=text size=20 name="dataValue"> <br> <input type=submit> </form> </body> </html>
到這裏還差一步就能夠看到集羣的效果,那就是3個tomcat之間session同步的問題。能夠經過打開<Engine>
節點下的<Cluster>
標籤的註釋來簡單的實現session複製:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
而後在tomcat0/conf/web.xml
的<webapp>
根節點下加入<distributable />
複製tomcat0到tomcat一、tomcat2,修改 的端口避免衝突,修改對應的jvmRoute
啓動apache和3個tomcat,就能夠看到效果。但這裏咱們使用memcached-session-manager
來同步session,因此沒必要打開<Cluster>
這一步。
這裏memcached搭建在另一臺服務器上(192.168.10.20),也能夠安裝在本地。
[root@cachets msm]# yum install libevent libevent-devel [root@cachets msm]# tar -zxvf memcached-1.4.19.tar.gz [root@cachets msm]# cd memcached-1.4.19 && ./configure && make && make install // 啓動兩個memcached節點,端口分別爲112十一、11212 [root@cachets ~]#memcached -d -m 64 -p 11211 -u daemon -P /var/run/memcached.pid [root@cachets ~]#memcached -d -m 64 -p 11212 -u daemon -P /var/run/memcached2.pid
若是開啓了防火牆,須要加入112十一、11212端口的容許規則。
加入jar包
將asm-3.2.jar
, couchbase-client-1.2.2.jar
, kryo-1.04.jar
, kryo-serializers-0.11.jar
, msm-kryo-serializer-1.6.5.jar
, memcached-session-manager-1.6.5.jar
, memcached-session-manager-tc6-1.6.5.jar
, minlog-1.2.jar
, reflectasm-1.01.jar
, spymemcached-2.10.2.jar
這些jar包加入tomcat0/lib/下。能夠看到這裏選用的session序列化策略採用的是kryo。另外要注意版本之間的兼容性,這裏只針對tomcat6.x。
修改conf/server.xml
:
將節點修改爲:
<Context path="" docBase="/apps/test/testapp/TEST" reloadable="true" > <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:192.168.10.20:11211,n2:192.168.10.20:11212" failoverNodes="n1" sticky="true" requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$" sessionBackupAsync="false" sessionBackupTimeout="100" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" copyCollectionsForSerialization="false" /> </Context>
接着將tomcat0完整的複製2份(tomcat1,tomcat2),也能夠放到另一臺服務器上。
修改成workers.properties
中定義的AJP等端口:
node tomcat | Server port | Connector port http | Connector port ajp | Engine jvmRoute | memcached failoverNodes |
---|---|---|---|---|---|
tomcat0 | 8005 | 8080 | 8009 | tomcat0 | n1 |
tomcat1 | 8105 | 8081 | 8109 | tomcat1 | n1 |
tomcat2 | 8205 | 8082 | 8209 | tomcat2 | n2 |
分別啓動tomcat0、tomcat一、tomcat2和apache,注意觀察tomcat的啓動日誌和memcached服務器的日誌。
[test@cachets ~]$ /apps/test/tomcat0/bin/startup.sh [test@cachets ~]$ /apps/test/tomcat1/bin/startup.sh [test@cachets ~]$ /apps/test/tomcat2/bin/startup.sh [root@cachets ~]# /apps/test/apache2/bin/apachectl start
在瀏覽器訪問http://192.168.10.100/test.jsp
。主要測試負載均衡與session共享。
原文連接地址:http://seanlook.com/2014/10/29/apache-3tomcat-cluster-jk-memcached/