terracota DSO client App端原理分析

對於terracota項目是什麼,google一下資料很多。推薦一篇中文文檔,http://yale.iteye.com/blog/1541612

爲了說明本文要關注的方向,並借用一張圖先。下面的TC即表示Terracota。

上圖中,TC Server作爲中心JVM堆服務器,爲多個分佈式部署的相同的App提供JVM堆級的同步服務。那麼當採用DSO模式的時候,客戶端App只需要配置一下tc-config.xml文件,然後給客戶端虛擬機加幾個啓動參數就能實現jvm層次的對象共享複製,怎麼做到的呢?

官方文檔中解釋,客戶端JVM中加入了tc特有的java library,使得在JVM加載類的時候,tc都會再次對java class的字節流進行自己的強化,也就是說,tc會對我們的類冬手腳,加入自己的一些列機制,比如賴加載、同步等機制。這種修改在jvm層自動完成,同時保證不影響我們應用的使用,使得應用程序感覺不到TC的存在,且能正常運行。對hibernate\spring aop中java enhance技術有了解,或者使用過asm等java bytecode工具的開發者來說,這道理很簡單。但是,我們真正關心的是以下兩個問題:

1.  jvm爲什麼會在加載類的時候,讓tc再做一次處理呢?

2. 而且,假設我們的應用中,類加載器不是jvm本身的ext classloader,會不會破壞tc的這種機制呢?


下載了TC的tarbat版本後,研究了sample應用的啓動過程,我們發現,客戶端jvm啓動的時候,tc自動將自己的lib/dso-boot/dso-boot-hotspot_*.jar加到了java啓動參數中。具體的過程,查看platform/bin/下的boot-jar-path.bat和make-boot-jar.bat。boot-jar-path.bat用戶生成dso client jvm啓動時附加的tc庫路徑,第一次執行的時候,dso-boot-hotspot_*.jar並不存在,於是make-boot-jar.bat被調用來生成當前jvm平臺的dso-boot-hotspot_*.jar,比如我這裏生成的是dso-boot-hotspot_win32_160_10.jar,名字上游很多信息一目瞭然。


然後,反編譯了dso-boot-hotspot_win32_160_10.jar。先看看包結構,瞬間明白了。



1.java.lang和 java.util包中的原生java對象,HashMap, HashSet, ArrayList等類,都被tc重寫了,加上了tc的一些機制。所以,java基礎類不需要再做動態的java字節碼強化。

2. javax.swing中的Table數據相關的類,比如DefaultTableModel類,都被tc重寫,這就是platform/samples/pojo/jtable這個例子不用配置就能運行的原因。相信,TC宣稱不支持tomcat、websphere等JavaEE服務器和其他的java中間件,也都是通過類似的方式做類重寫。如果我們要擴展tc,也可以仿照他的做法。

3. sun.misc.Launcher$AppClassLoader和ExtClassLoader已經被改寫TC替換了,這下TC可以爲所欲爲了。打開源代碼以後,發現主要是增加了java jar的查找。

4. 更重要的是,java.lang.ClassLoader類,尤其是它的defineClass()方法被重寫了。這樣JVM中所有的ClassLoader,不管是App/Ext,還是應用自己new出來的ClassLoader, 從字節流生成Class對象都需要tc做最後的處理了。


3和4這兩點,徹底解決了我們的疑問。這也給我們深度的定製和改寫Terracota,提供了可能和樣例。可以想象,Terracota完全可以被應用OSGi bundle中,適應Web組件服務化架構。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章