天天看點

關于java Tomcat 叢集的面試問題



在java工程師面試過程中,一些比較厲害的技術經理經常會問到一些比較難的面試題,比如Tomcat叢集。那我們就來分析下可能會問到的一些問題吧。

1、如何在tomcat叢集中實作Session共享

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/>節點中注釋掉的下面這句取消注釋并改為(官網上http://tomcat.apache.org/tomcat-6.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.JvmRouteSessionIDBinderListener”/>  

          <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不能完全利用記憶體,會産生記憶體碎片,如果存儲塊不足,還會産生記憶體溢出。

四,總結

上面三種方法都是可行的

第一種方法,最影響系統速度的那種,不推薦使用;

第二種方法,效果不錯,不過安全隐患一樣的存在;

第三種方法,個人覺得第三種方法是最好的,推薦大家使用

其實這麼寫,可能對你幫助不是很大,但了解一些大概關于叢集的知識,對你的面試還是有些幫助的。