weblogic 12C叢集環境下的session複製
做過weblogic叢集環境的人應該都清楚,要想實現session同步,必須滿足兩個條件:第一,在weblogic.xml裡面增加session同步相關的程式碼;第二,所有放入session的類都要序列化。
但是,我終於還是栽了。兩個條件明明都滿足了,但就是“有些”物件就是不能同步。
我以前使用session是這樣的:
Java程式碼 REYO reyo = (Customer)session.getAttribute(KEY_REYO);
reyo.setName("reyo");
這樣寫完以後,在單機環境下,session中的變數customer的name屬性就被更改了。然而在叢集環境下,僅僅這樣做是不能觸發session同步機制的。必須要把customer變數在重新放入session中,即:
session.setAttribute(KEY_REYO, customer);
後來我從weblogic的售後工程師那裡也確認了這一點。一點點經驗,和大家分享。
在weblogic的文件中又翻出了以下內容,要是之前認真看了就好了:
Use setAttribute to Change Session State:
In an HTTP servlet that implements javax.servlet.http.HttpSession, use HttpSession.setAttribute (which replaces the deprecated putValue) to change attributes in a session object. If you set attributes in a session object with setAttribute, the object and its attributes are replicated in a cluster using in-memory replication. If you use other set methods to change objects within a session, WebLogic Server does not replicate those changes. Every time a change is made to an object that is in the session, setAttribute() should be called to update that object across the cluster.
下面是補充說明:
在Weblogic中,HttpSession Replication的方式是通過在weblogic.xml中的session- descriptor的定義persistent-store-type來實現的. persistent-store-type可選的屬性包括memory, replicated, replicated_if_clustered, async-replicated, async-replicated-if-clustered, file, async-jdbc, jdbc, cookie, coherence-web.
- memory—Disables persistent session storage.
- replicated—Same as memory, but session data is replicated across the clustered servers.
- replicated_if_clustered—If the Web application is deployed on a clustered server, the in-effect persistent-store-type will be replicated. Otherwise, memory is the default.
- async-replicated—Enables asynchronous session replication in an application or Web application. See "Asynchronous HTTP Session Replication" in Performance and Tuning for Oracle WebLogic Server.
- async-replicated-if-clustered—Enables asynchronous session replication in an application or Web application when deployed to a cluster environment. If deployed to a single server environment, then the session persistence/replication defaults to in-memory. This allows testing on a single server without deployment errors.
- file—Uses file-based persistence (See also session-descriptor).
- async-jdbc—Enables asynchronous JDBC persistence for HTTP sessions in an application or Web application. See Configuring Session Persistence.
- jdbc—Uses a database to store persistent sessions. (see also session-descriptor).
- cookie—All session data is stored in a cookie in the user's browser.
Replicated,async-replicated只用部置叢集在叢集上,而replicated_if_clustered,async-replicated-if-clustered也可以部署在獨立例項上。都不能只部署在叢集的部分例項中上。
例如:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd">
<session-descriptor>
<!-- <persistent-store-type>replicated</persistent-store-type> -->
<persistent-store-type>replicated_if_clustered</persistent-store-type>
<!--<persistent-store-type>memory</persistent-store-type> -->
<timeout-secs>60</timeout-secs>
</session-descriptor>
</weblogic-web-app>
- Load Blanace和Session Affinity
由於這裡的機制是主從備份, 所以叢集中只有兩個例項會有同一HTTP Session的資料. 當叢集裡的例項多於2個以上時,為了確保後續的HTTP請求能訪問到Session資料, 必須要求前置分發請求的load balancer支援session affinity(sticky session/seamless session). Session Affinity就是能夠把特定Session的所有請求都路由到第一次建立Session的同一物理機器上;否則後續的請求就有可能不能夠訪問 Session資料了.
如果設定成非Replication方式即memory模式, 生成的JSESSIONID類似:
gGMWQy2LcSTHTSyLdyLpqYGskYpXPpRJkc2VB618mSKSQC9rgsCv!-1274119771!1353236040031
可以看出這個session被二個!分隔成三部分。第一部分應該是真正的sessionid, -1274119771是例項標識。而1353236040031為session建立時間。
一旦配置成Replicated模式,Weblogic會生成的SessionID類似:
sHkLQyQTnJQQ217Js7SmQL2x9hBb0JQ5hFm7n4QpNkZL7wMnLbPn!-9326295!959096067!1353236595093
這裡出現三個!,第二,三部分為主備例項的標識。
SessionID格式的: sessionid!primary_server_id[!secondary_server_id]!creationTime
2.配置weblogic Load Blanace
session Id:
KSW2QyJFzVcnFxQTWpSLJLhJTTQsCzLGqlM1ShnCvSyKm2r4k29h!-1458785082!2113129367!1353238917906
session CreateTime :1353238917906
current instance :Server1
可以看到該session的primary_server_id為-1458785082,即Server1。(每個server的id是啟動時生成的,所以也是變化,所以你的測試可能與我不一樣。) secondary_server_id為2113129367,即server3. 即server3是Server1的備點。
2) 停止Server1,再次訪問, 頁面顯示:
session Id:
KSW2QyJFzVcnFxQTWpSLJLhJTTQsCzLGqlM1ShnCvSyKm2r4k29h!2113129367!-481865348!1353238917906
session CreateTime :1353238917906
current instance :Server3
可以看到sessionId沒有變化,而該session的primary_server_id為2113129367, 即Server3。secondary_server_id為-481865348,即server0.即Server0是Server3的備點。
3) 停止Server3,再次訪問, 頁面顯示:
session Id:
KSW2QyJFzVcnFxQTWpSLJLhJTTQsCzLGqlM1ShnCvSyKm2r4k29h!-481865348!NONE!1353238917906
session CreateTime :1353238917906
current instance :Server0
可以看到sessionId沒有變化,該session的primary_server_id為-481865348, 即Server0。secondary_server_id為NONE,即該session沒有備點.
通過測試我們大致可以猜出weblogic session複製的基本思路:
1) 每個例項都有兩份Session資料。主資料和備份資料。
2) 當請求的sessionId的primary_server_id為當前例項時,從主資料裡獲取session響應請求,否則進行3).
3) 當請求的sessionId的secondary_server_id為當前例項時,從備份資料裡取session響應請求。並修正該session的primary_server_id/secondary_server_id為自已及其的備點。
3. Weblogic支援的負載均衡
Weblogic支援兩種機制的負載均衡
1) Proxy plug-ins
如果一個例項失敗,plug-in會定位該session的secondary_server,將請求發給它。
2) Hardware load balancers
Hardware load balancers,比如F5. 這些第三方產品並不能按weblogic的意願,定位session的secondary_server。他會隨機選機選擇一個可用例項發給他。然後該例項通過session id裡的secondary_server_id,像secondary_server獲取資料。
雖然weblogic允許這種請求的隨機轉發,但並不建議使用會話不親和方式,因為這將帶來資料併發和一致性問題。
參考文獻: