1. 程式人生 > >N個tomcat之間實現Session共享

N個tomcat之間實現Session共享

前言

對於高訪問量、高併發量的網站或web應用來說,目前最常見的解決方案應該就是利用負載均衡進行server叢集,例如比較流行的nginx+memcache+tomcat。叢集之後比如我們有N個Tomcat,使用者在訪問我們的網站時有可能第一次請求分發到tomcat1下,而第二次請求又分發到了tomcat2下,有過web開發經驗的朋友都知道這時session不一致會導致怎樣的後果,所以我們需要解決一下多個tomcat之間session共享的問題。

環境準備

首先我們需要下載tomcat,這裡我們選擇tomcat7的解壓縮版:


下載完成後我們新建一個目錄叫tomcat_cluster(tomcat叢集的意思),直接解壓下載好的tomcat,並重命名為tomcat1,可以看到目錄結構如下:

準備一個最簡單的web專案(在IDE中建立部署,拷貝出來即可),並修改index.jsp的內容如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <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>
    
		SessionID:<%=session.getId()%>
		<BR>
		SessionIP:<%=request.getServerName()%>
		<BR>
		SessionPort:<%=request.getServerPort()%>
		<%
		out.println("This is Tomcat Server 11111");
		%>
  </body>
</html>

這樣基本工作就做完了,下面需要修改tomcat的配置檔案,我們開啟conf下的server.xml檔案,找到下面這一行:
<Engine name="Catalina" defaultHost="localhost">
不需要做任何修改,在這一行的下面加入如下程式碼:
	<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="8">

          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>

          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
            <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="4000"
                      autoBind="100"
                      selectorTimeout="5000"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
            <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
          </Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=""/>
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

          <Deployer className="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"/>
          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>


這個就是tomcat自帶的叢集配置了,我們可以在tomcat官方文件中的cluster-howto.html中看到相關注意事項,其中有一條需要注意一下:

Make sure your web.xml has the <distributable/> element

很明顯是說我們的web專案的web.xml檔案中需要有<distributable/>這個元素,所以在我們剛才引入的web專案中做如上的修改。

這樣我們的基本配置就完成了,因為是叢集,所以在tomcat_cluster目錄下拷貝一份tomcat1,並重命名成tomcat2。


注意一下需要修改的地方:

1、首先肯定是埠號,所有port字樣的配置都修改一下保證兩個不重複,我這裡將tomcat1的埠修改為7080,tomcat2的埠修改為9080

2、修改webapps下的專案中的index.jsp檔案,因為要測試session共享所以有必要區分一下,在jsp中加入一行靜態文字即可,我這裡是用“This is Tomcat Server 111111”和“This is Tomcat Server 22222”來進行區分的,下面分別啟動兩個tomcat進行測試,我們分別執行bin目錄下的startup.bat,發現第一個tomcat啟動之後,第二個無法啟動,這是因為啟動指令碼(startup.bat)沒有修改,引用同樣的CATALINA_HOME必然會報錯,所以請注意下面的第三點。

3、為我們的這兩個tomcat新增兩個環境變數——CATALINA_HOME2、CATALINA_HOME3分別指向這兩個tomcat的安裝目錄:


然後分別修改兩個tomcat中bin目錄下的兩個指令碼:startup.bat和catalina.bat,把tomcat1中的這兩個檔案中的%CATALINA_HOME%替換為%CATALINA_HOME2%,把tomcat2中的這兩個檔案中的%CATALINA_HOME%替換為%CATALINA_HOME3%,現在再啟動tomcat,會發現兩個tomcat都可以正常啟動了,解壓版的tomcat需要這樣配置一下。在瀏覽器中檢測一下tomcat是否可以成功訪問:


OK,再訪問一下我們的測試專案,看看session是否一致:


可以發現我們兩個tomcat下的這兩個專案Session完全一致,重新整理也不會變,到此為止我們就算成功實現了Session共享,也就是說我們tomcat已經成功完成了任務,剩餘的交給nginx就OK了。最後再強調一下,這兩個testdemo的web.xml中需要加這麼元素:


總結

本篇blog介紹了tomcat叢集之前的必備工作——session共享的配置,以及同時啟動兩個tomcat解壓縮版需要注意的問題,希望對看到的同學有所幫助吧,The End。