天天看點

并行類加載——讓tomcat玩轉雙十一

今年雙十一,是應用容器的最新版本ali-tomcat 7.0.59.x應對的第一次雙十一。這個版本包含的一個主要功能是并行類加載,本文主要對并行類加載在雙十一期間的支援做一個總結。

并行類加載在雙十一期間最主要的業務系統,在雙十一期間支撐了每秒<code>14w</code>訂單建立,是一個非常了不起的成績!

由于各種原因,該業務系統比較龐大,依賴較為複雜。為了解決業務複雜性,應用引入了子產品化系統,通過子產品化的方式抽象出一系列的bundle,而bundle之間互相隔離,享有獨立的類加載器。

由于bundle之間互相隔離,我們自然就會想到,是否能夠在應用啟動時多線程并行的初始化這些bundle呢?

原來的應用運作在jdk6上,tomcat啟動的時候,應用的classloader(webappclassloader)在進行類加載的時候是順序加載的,因為jdk6上classloader.loadclass(string name)這個方法是synchonized的,如果應用裡面有多個線程在同時調用loadclass方法進行類加載的話,那麼鎖的競争将會非常激烈。

大家知道在jdk7上,如果調用classloader.registerasparallelcapable方法,則會開啟并行類加載功能,把鎖的級别從classloader對象本身,降低為要加載的類名這個級别。換句話說隻要多線程加載的不是同一個類的話,loadclass方法都不會鎖住。遺憾的是,開啟并行類加載必須要求一個類加載器繼承鍊路上所有類加載器都調用registerasparallelcapable,但tomcat7自帶的webappclassloader并沒有調用registerasparallelcapable,是以老版本的tomcat7即使運作在jdk7上,也無法利用并行類加載的特性。

從ali-tomcat 7.0.59.2版本開始解決了這個問題,支援在webappclassloader中打開registerasparallelcapable方法。但是情況沒有那麼簡單,還需要解決的一個問題是如何相容jdk6的問題,因為tomcat7.x版本是基于jdk6編譯,同時運作在jdk6和jdk7+以上的。jdk6下是沒有classloader.registerasparallelcapable這個方法的,是以jdk6下必須保持原有的行為,在jdk7下才能支援并行類加載功能。也就是說,即使使用者配置了并行類加載,那麼tomcat也必須根據運作時的jdk版本來決定是否開啟并行類加載功能。ali-tomcat通過反射機制解決了這個問題,在運作時刻對應用的webappclassloader嘗試注冊并行類加載功能,當發現沒有這個方法時,會自動fall back到普通的類加載,也就是線性類加載功能。

并行類加載——讓tomcat玩轉雙十一

可以看到,實際運作過程中,tomcat會自動根據jdk版本來選擇是否啟用并行類加載功能。當然這項功能預設是關閉的,需要使用者通過配置檔案顯示開啟。



并行類加載——讓tomcat玩轉雙十一

我們看到在實際線上機器的啟動時間上,當開啟并行類加載功能後,子產品化系統的啟動時間提升了47%,應用整體啟動時間提升了29%!

确認tomcat的運作環境是jre7及以上。

安裝ali-tomcat 7.0.59.3版本

修改/home/admin/$app/conf/tomcat/context.xml,如果這個檔案不存在,則從

拷貝一份。添加如下配置:

重新開機tomcat

成功啟動後,應該會在控制台看到類似如下的日志:

并行類加載功能已經在捐獻給apache tomcat社群,并且被社群接受,在最新的apache tomcat 7.0.65版本中已經包含該項功能。

并行類加載——讓tomcat玩轉雙十一

并行類加載功能在子產品化業務應用,以及合并部署等等場景下對于性能有較大提升。後續ali-tomcat會在開發體驗,監控診斷等方面繼續發力,幫助業務系統提升開發診斷效率!!