在tomcat集群中實現Session共享
轉自:http://www.toutiao.com/i6388049068718817794/
Apache集群實現Tomcat的Session共享配置其實很簡單,在Tomcat自帶的文檔中有詳細的說明( /docs/cluster-howto.html ),只不過是英語的,所以聯合
下面根據說下怎么配置吧:
1、既然是集群肯定要多准備幾個Tomcat來模擬,比如分別為Tomcat01、Tomcat02、Tomcat03。
如果各Tomcat程序放在不同的機器上,那么就不會有端口的沖突。如果是放在同一台機器上的話,那就簡單改幾個端口,防止端口占用造成的沖突。打開conf文件夾中的server.xml文件,需要修改的端口有:
1、<Server port=”8015″ shutdown=”SHUTDOWN”>
2、<Connector port=”8081″ protocol=”HTTP/1.1″ connectionTimeout=”20000″ redirectPort=”8443″ />
3、<Connector port=”8019″ protocol=”AJP/1.3″ redirectPort=”8443″ />
以上port需要修改,至於修改成什么樣子,看你自己了,只要不出現端口沖突就可以了,要保證各個Tomcat實例間沒有端口沖突
2、配置Tomcat的集群設置:
還是修改server.xml文件,最簡單的集群配置只需要將<Engine/>節點中注釋掉的下面這句取消注釋即可。
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
或在<Engine>下添加如下配置(官網上http://tomcat.apache.org/tomcat-8.0-doc/cluster-howto.html)
<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.ClusterSessionListener"/>
</Cluster>
3、修改項目的web.xml文件:
web.xml文件的修改很簡單:只需要在<web-app/>節點中添加<distributable/>這個節點就可以了。
經過這三步就實現了Tomcat的集群下的Session的共享了。
2、Tomcat集群方式的優缺點
Tomcat集群方式有三種,分別是:
1.使用DNS輪詢.
2.使用Apache R-proxy方式。
3.使用Apache mod_jk方式.
DNS輪詢
缺點:當集群中某台服務器停止之后,用戶由於dns緩存的緣故,便無法訪問服務,必須等到dns解析更新,或者這台服務器重新啟動。
還有就是必須把集群中的所有服務端口暴露給外界,沒有用apache做前置代理的方式安全,並且占用大量公網IP地址,而且tomcat還要負責處理靜態網頁資源,影響效率。
優點:集群配置最簡單,dns設置也非常簡單。
R-proxy(反向代理)
缺點:當其中一台tomcat停止運行的時候,apache仍然會轉發請求過去,導致502網關錯誤。但是只要服務器再啟動就不存在這個問題。
mod_jk
優點:Apache 會自動檢測到停止掉的tomcat,然后不再發請求過去。
缺點:當停止掉的tomcat服務器再次啟動的時候,Apache檢測不到,仍然不會轉發請求過去。
R-proxy和mod_jk的共同優點是.可以只將Apache置於公網,節省公網IP地址資源。
可以通過設置來實現Apache專門負責處理靜態網頁,讓Tomcat專門負責處理jsp和servlet等動態請求。
共同缺點是:如果前置Apache代理服務器停止運行,所有集群服務將無法對外提供。
R-proxy和mod_jk對靜態頁面請求的處理,都可以通設置來選取一個盡可能優化的效果。
這三種Tomcat集群方式對實現最佳負載均衡都有一定不足,mod_jk相對好些,可以通過設置lbfactor參數來分配請求任務,但又因為mod_jk2方式不被推薦,mod_jk2已經不再被更新了。
在 做了web集群后,你肯定會首先考慮session同步問題,因為通過負載均衡后,同一個IP訪問同一個頁面會被分配到不同的服務器上,如果 session不同步的話,一個登錄用戶,一會是登錄狀態,一會又不是登錄狀態。所以本文就根據這種情況給出三種不同的方法來解決這個問題:
一,利用數據庫同步session
在做多服務器session同步時我沒有用這種方法,如果非要用這種方法的話,我想過二種方法:
1,用一個低端電腦建個數據庫專門存放web服務器的session,或者,把這個專門的數據庫建在文件服務器上,用戶訪問web服務器時,會去這個專門的數據庫check一下session的情況,以達到session同步的目的。
2,這種方法是把存放session的表和其他數據庫表放在一起,如果mysql也做了集群了話,每個mysql節點都要有這張表,並且這張session表的數據表要實時同步。
說明:用數據庫來同步session,會加大數據庫的負擔,數據庫本來就是容易產生瓶頸的地方,如果把session還放到數據庫里面,無疑是雪上加霜。上面的二種方法,第一點方法較好,把放session的表獨立開來,減輕了真正數據庫的負擔
二,利用cookie同步session
session 是文件的形勢存放在服務器端的,cookie是文件的形勢存在客戶端的,怎么實現同步呢?方法很簡單,就是把用戶訪問頁面產生的session放到 cookie里面,就是以cookie為中轉站。你訪問web服務器A,產生了session把它放到cookie里面了,你訪問被分配到web服務器 B,這個時候,web服務器B先判斷服務器有沒有這個session,如果沒有,在去看看客戶端的cookie里面有沒有這個session,如果也沒 有,說明session真的不存,如果cookie里面有,就把cookie里面的sessoin同步到web服務器B,這樣就可以實現session的 同步了。
說明:這種方法實現起來簡單,方便,也不會加大數據庫的負擔,但是如果客戶端把cookie禁掉了的話,那么session就無從同步了,這樣會給網站帶來損失;cookie的安全性不高,雖然它已經加了密,但是還是可以偽造的。
三,利用memcache同步session
memcache可以做分布式,如果沒有這功能,他也不能用來做session同步。他可以把web服務器中的內存組合起來,成為一個”內存池”,不管是哪個服務器產生的sessoin都可以放到這個”內存池”中,其他的都可以使用。
優點:以這種方式來同步session,不會加大數據庫的負擔,並且安全性比用cookie大大的提高,把session放到內存里面,比從文件中讀取要快很多。
缺點:memcache把內存分成很多種規格的存儲塊,有塊就有大小,這種方式也就決定了,memcache不能完全利用內存,會產生內存碎片,如果存儲塊不足,還會產生內存溢出。
四,總結
上面三種方法都是可行的
第一種方法,最影響系統速度的那種,不推薦使用;
第二種方法,效果不錯,不過安全隱患一樣的存在;
第三種方法,個人覺得第三種方法是最好的,推薦大家使用