天天看點

JBoss企業級應用服務平台群集指南(七)第二部分

    在章節 5.3中, “在mod_jk中配置工作節點”, 我們涵蓋了如何使用”會話粘貼”,以確定為了維持會話狀态客戶在一個會話上總是請求相同的服務節點。可是, 它并不是完美的。随着時間的過去,在所有分布式節點上的負載可能是不平均,如果一個節點當掉(關閉了),那麼在它上面的所有會話資料就丢失了。一個更好和更可靠的辦法就是在叢集中的所有節點之間複制會話資料。這樣,客戶可以連接配接到任何服務節點上,并獲得同樣的會話資料。

    jboss.cache:service=TomcatClusteringCache MBean在JBoss Tomcat叢集的HTTP負載平衡中使用JBoss緩存提供HTTP會話複制服務。該MBean已經在deploy/tc5-cluster.sar/META-INF/jboss-service.xml檔案中定義。

注意: 

    在AS 4.0.4 CR2以前, HTTP會話緩存配置檔案是deploy/tc5-cluster-service.xml檔案. 更多的細細請見AS 4.0.3的文檔

  下面是一個典型的deploy/tc5-cluster.sar/META-INF/jboss-service.xml 檔案。在TomcatClusteringCache MBean中這個配置屬性與部分 2, “JBossCache配置”非常相似。

<mbean code="org.jboss.cache.aop.TreeCacheAop" 

name="jboss.cache:service=TomcatClusteringCache"> 

<depends>jboss:service=Naming</depends> 

<depends>jboss:service=TransactionManager</depends> 

<depends>jboss.aop:service=AspectDeployer</depends> 

<attribute name="TransactionManagerLookupClass"> 

org.jboss.cache.BatchModeTransactionManagerLookup 

</attribute> 

<attribute name="IsolationLevel">REPEATABLE_READ</attribute> 

<attribute name="CacheMode">REPL_ASYNC</attribute> 

<attribute name="ClusterName"> 

Tomcat-${jboss.partition.name:Cluster} 

<attribute name="UseMarshalling">false</attribute> 

<attribute name="InactiveOnStartup">false</attribute> 

<attribute name="ClusterConfig"> 

... ... 

<attribute name="LockAcquisitionTimeout">15000</attribute> 

</mbean>

對于TreeCache MBean的詳細配置見部分2, “JBossCache 配置”。下面,我們将僅僅讨論與HTTP叢集會話複制關聯的幾個屬性。

•  TransactionManagerLookupClass 設定事務管理工廠。預設值是 org.jboss.cache.BatchModeTransactionManagerLookup.。它通知緩存不要參與JTA-specific事務。代替, 它的緩存管理自己的事務以支援細微的卵複制。

•  IsolationLevel 設定隔離級别為更新對于事務處理分布式緩存。有效的值有 SERIALIZABLE, REPEATABLE_READ, READ_COMMITTED, READ_UNCOMMITTED,和 NONE. 這些隔離級别設定與在資料庫上的隔離級别是相同的東西。預設隔離值REPEATABLE_READ對于大多數web應用程式是有意義的。

•  CacheMode控制緩存的複制方式。有效值包括 REPL_SYNC 和 REPL_ASYNC, 來确定改變是同步的或者是異步的。使用同步複制確定改變在web請求完成之前傳播到叢集。然而, 同步複制是非常慢的. 對于異步方式, 你必須應該啟用(enable)并調整複制隊列。

•  ClusterName指定了緩存所服務的群集的名字。預設的群集名是 "Tomcat-" 後面跟着目前的 JBoss 分區名。所有節點都應該使用相同的群集名。雖然會話複制能夠和 JBoss 的其他群集服務共享同一通道(多點傳送位址和端口),複制還是應該有自己的群集名。

•  UseMarshalling和InactiveOnStartup屬性必須有相同的值。如果需要使用 FIELD 級會話複制(請參考後面的内容),它們的值必須是 true。否則,它們的預設值是 false。

•  ClusterConfig配置底層的 JGroups 棧。最重要的配置元素是用于群集通訊的多點傳送位址和端口,分别是mcast_addr 和mcast_port。這些值對你的網絡該很有用。請參考章節 1, “JGroups 配置”來獲得更多資訊。

•  LockAcquisitionTimeout 設定等待獲得一個鎖的最大時間,機關是毫秒。預設值是15000.

•  UseReplQueue 确定當使用異步複制的時候是否激活複制隊列。這允許若幹緩存更新被綁定在一起提高性能。複制隊列的性能由ReplQueueInterval 和ReplQueueMaxElements的性能限制。

•  ReplQueueInterval 指定JBoss Cache 在發送請求到複制隊列之前的等待時間,機關是毫秒。

•  ReplQueueMaxElements: 指定JBoss緩存将發送一個更新之前,在複制隊列裡允許的元素的最大數量。

    要在你的web應用程式中啟用叢集,你必須在web.xml描述符中聲明distributable。這裡有一個例子:

<?xml version="1.0"?> 

<web-app    [url]http://java.sun.com/xml/ns/j2ee[/url]="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 

[url]http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd[/url]" 

version="2.4"> 

<distributable/> 

<!-- ... --> 

</web-app>

你可以在jboss-web.xml檔案中用replication-config 元素進一步配置會話複制。這裡有一個例子:

    replication-trigger元素決定用什麼觸發一個會話複制(或什麼時候會話被認為是 dirty 的)。它有四個選項:

•  SET: 在這個選項下,隻有在會話裡設定了屬性,會話才被認為是 dirty。如果你的應用程式總把改變的寫回到會話裡,從性能角度來講這個選項可能是最優化的。如果隻從會話裡取出一個對象而不把它寫回到會話裡,對這個對象的修改将不會被複制。

•  SET_AND_GET: 如使用這個政策,所有 get 或 set 的屬性都會被标記為 ditry。如果從會話裡取出一個對象并修改它,但沒有寫回到這個會話裡,這些修改也将被複制。這個選項對性能有比較大的影響。

•  SET_AND_NON_PRIMITIVE_GET: 這個政策和 SET_AND_GET 相似,除了隻有非基本(non-primitive)get 操作被當作 dirty。例如,http 會話請求可能從屬性裡取出一個非基本對象執行個體,然後修改了這個執行個體。如果我們沒有指定非基本 get 應該考慮為 dirty,這個修改就不會正确地被複制。這個選項是預設值。

•  ACCESS: 這個選項表示,隻要會話被通路,就把會話标記為 ditry。因為在每個 HTTP 請求的過程中,會話都會被通路,是以會話每次都會被複制。會話執行個體裡的時間戳也會相應地更新。由于複制并沒有包括時間戳,其他群集節點的時間戳可能不會被更新。如果 HTTP 請求沒有取出或修改任何會話屬性,其他節點的會話就可能會先于活動節點過期。當設定了這個選項,會話的時間戳将在所有群集節點中同步。注意采用這個選項對性能影響很大,需要小心行事。

     replication-granularity 元素控制複制機關的大小。支援的選項包括:

•  SESSION: 複制基于每一會話執行個體。隻要當調用 snapshot manager 時它被認為有修改,整個會話對象都将串行化。

•  ATTRIBUTE: 複制僅針對于會話裡的 ditry 屬性加上某些會話資料,如 lastAccessTime。對于承載大量資料的會話,這個選項可以提高複制性能。

•  FIELD: 複制僅針對于會話屬性對象裡的資料字段(後面會有更多内容)。

replication-field-batch-mode 指出你是否在每個 HTTP 請求之間進行批量更新。它的預設值是 true。

    如果你的會話通常很小,使用 SESSION 選項是更好的政策。如果你的會話更大些而且某些部分并不常被通路,ATTRIBUTE 方式的複制就會更有效。如果你的應用程式在會話屬性裡擁有非常大的資料對象,而且隻有這些對象裡的某些字段被經常修改,采用 FIELD 政策将是最佳選擇。在後面的内容裡,讓我們讨論一下怎樣使用 FIELD 級的複制。

    字段級複制隻複制存儲在會話裡的對象内部的被修改的資料字段。它能夠極大地減少群集節點之間的資料通信,也是以提高了整個群集系統的性能。為了使用字段級複制,你首先得用 Java 類來指出哪個字段要被複制。它是通過在 JavaDocs 嵌入的 JDK 1.4 風格的注解(annotations)來完成的:

    為了注解(annotate)你的 POJO,我們提供兩個注解方式:@@org.jboss.web.tomcat.tc5.session.AopMarker 和

@@org.jboss.web.tomcat.tc5.session.InstanceAopMarker. 當你用 AopMarker 注解你的類時,你可以指出這個類的執行個體字段級複制。例如:

/* 

* My usual comments here first. 

* @@org.jboss.web.tomcat.tc5.session.AopMarker 

*/ 

public class Address 

... 

}

   如果你用InstanceAopMarker注解類時,它所有的子類都将自動被注解。例如,

* @@org.jboss.web.tomcat.tc5.session.InstanceOfAopMarker 

public class Person 

當你有一個子類,如:

public class Student extends Person 

    你不需要注解Student。因為它是Person的子類,是以它将自動被注解。

    然而,既然目前我們隻支援 JDK 1.4 風格的注解(由 JBoss Aop 提供),你将需要執行一個預處理步驟。在 Java 編譯器編譯之前和之後,你需要用 JBoss AOP pre-compiler annotationc 和 post-compiler aopc 來處理上面的源碼。這裡是一個怎樣從指令行調用這些指令的例子。

$ annotationc [classpath] [source files or directories] 

$ javac -cp [classpath] [source files or directories] 

$ aopc [classpath] [class files or directories]

    請參考 JBoss AOP 文檔關于怎樣使用 pre- 和 post-compiler。JBoss AOP 項目也提供使用 ANT 來把上述步驟內建在應用程式的 build 過程中的簡單方法。下一個 AS 釋出版本将提供對 JDK 5.0 注解的更透明的支援。但是現在,你還得用 pre- 和 post-compiler來編譯你的源碼。

    或者,你也能夠在[url]http://wiki.jboss.org/wiki/Wiki.jsp?page=Http_session_field_level_example[/url]裡看到一個怎樣建構(build),部署(deploy),和驗證(validate)采用字段級複制的 web 應用程式的完整例子。這個例子捆綁了 pre- 和 post-compile 工具,是以你不需要再下載下傳單獨的 JBoss AOP 了。

   當你把 web 應用程式部署到 JBoss AS 時,請確定下面的配置是正确的:

•  在伺服器的deploy/tc5-cluster.sar/META-INF/jboss-service.xml檔案裡,inactiveOnStartup和useMarshalling屬性必須都為 true。

•  在應用程式的jboss-web.xml檔案裡,replication-granularity屬性必須為 FIELD。

    最後,讓我們看一個怎樣在哪些資料類上使用字段級(FIELD-level)複制的例子。請注意你不需要在修改資料對象(data object)後調用session.setAttribute(),對字段的所有修改都自動跨群集地被複制了。

// Do this only once. So this can be in init(), e.g. 

if(firstTime) 

Person joe = new Person("Joe", 40); Person mary = new Person("Mary", 30); Address addr = new Address(); addr.setZip(94086); 

joe.setAddress(addr); 

mary.setAddress(addr); // joe and mary share the same address! 

session.setAttribute("joe", joe); // that's it. 

session.setAttribute("mary", mary); // that's it. 

Person mary = (Person)session.getAttribute("mary"); 

mary.getAddress().setZip(95123); // this will update and replicate the zip code.

除了簡單的對象(plain objects),你還可以使用那些對象的正常 Java 集合(Java collection)作為會話屬性。JBoss cache 會自動地判斷怎樣處理這些集合和複制它們的成員對象裡的字段的變更。

    如果你已經部署和通路了你的應用程式,你可以使用jboss.cache:service=TomcatClusteringCache MBean 和調用printDetails操作。你應該看到下面的輸出結果。

/JSESSION 

/quote 

/FB04767C454BAB3B2E462A27CB571330 

VERSION: 6 

FB04767C454BAB3B2E462A27CB571330: 

org.jboss.invocation.MarshalledValue@1f13a81c 

/AxCI8Ovt5VQTfNyYy9Bomw** VERSION: 4 

這個輸出結果展示了在一個叫quote應用程式裡的兩個獨立的 web 會話,它們通過 JBossCache 來共享。這個例子使用了session的replication-granularity。如果使用了attribute級的複制,應該可以看到展示每個被複制的會話屬性的其他條目。在兩種情況下,被複制的值都存儲在一個不透明的MarshelledValue容器裡。目前還沒有任何工具可以讓你檢視這些被複制的會話值。如果你沒有看到任何輸出,要麼是應用程式沒有正确地标記為distributable,要麼就是你根本沒有通路把值寫入 HTTP 會話的應用程式。org.jboss.cache 和org.jboss.web 日志類别提供了可用于調試目的對會話複制的其他視角。

    JBoss 支援群集的單點登入(single sign-on),允許使用者在一個 JBoss 伺服器上驗證應用程式,然後被在同一個主機或群集裡的其他節點裡的被部署在同一個虛拟主機上的所有應用程式識别。HTTP 會話複制服務處理複制驗證(Authentication replication)。雖然會話複制不需要顯性地為這個應用程式啟用,但 tc5-cluster-service.xml 檔案必須被部署。

    為了啟用單點登入,你必須在tomcat server.xml檔案的Host元素裡加入ClusteredSingleSignOn開關(valve)。這個開關(valve)的配置如下:

<Valve className="org.jboss.web.tomcat.tc5.sso.ClusteredSingleSignOn" />

本文轉自xudayu 51CTO部落格,原文連結:http://blog.51cto.com/xudayu/67634,如需轉載請自行聯系原作者