加速Java應用開發速度2:加速專案除錯啟動速度

發表於2013-07-02

伯樂線上注:本文來自文章作者張開濤的推薦投稿(原文)。如果其他朋友也有不錯的原創或譯文,可以嘗試推薦給伯樂線上

————————————————————

上一篇Spring/Hibernate提升速度的文章《加速spring/hibernate應用除錯時啟動速度》,主要是通過一些技巧來提升啟動速度,還是做不到如類的熱部署/熱替換。因此再寫一篇關於熱部署/熱替換的文章。之前也有很多人介紹過這些知識,不過比較分散,我寫此篇的目的是聚合它們。本文以 HotSpot 虛擬機器為例。

 

首先讓我們來看兩個概念:熱部署、熱替換

熱部署

即在容器執行過程中,重新載入類或重新載入整個專案。常見的解決方案就是使用自定義ClassLoader;

部分載入的示例:如JSP、Play框架;

重新載入整個專案的示例:如Tomcat、Jetty;預設都是定期檢測class檔案是否有修改,如果有,先解除安裝當前容器,再重新載入整個專案(reload)。

 

這種情況缺點很明顯:只能重新裝載整個類/整個專案,不能只替換類中的部分。

JSP熱部署的介紹:

http://www.linuxidc.com/Linux/2013-05/83816.htm

Tomcat熱部署的介紹:

http://www.94it.cn/a/jingxuanboke/2013/0501/4578.html

Play!框架:

http://mingj.iteye.com/blog/307238

 

熱替換

熱替換相對於之前的熱部署的優勢就是可以替換如方法體、增刪方法/欄位等類內部區域性替換,而不是整個類。常見的實現方式:HotSpot虛擬機器的HotSwap、HotSwap補丁、

HotSwap

只能熱替換方法體。只要在eclipse或idea等開發工具中開啟debug模式即可使用。

HotSwap補丁 DCEVM

該補丁增強了HotSwap,可以增加、刪除類欄位、方法和改變類的父類。也必須在debug模式下除錯。具體使用可以參考如下文章,在此就不重複了

hotswap 使用者手冊

DCE使用的問題及其解決方法

 

我測試時使用的是jdk1.6.0_25,沒有問題,不支援jdk1.6.0_26,且我測試jdk7_13和jdk7_21沒成功。官網介紹說其是基於JDK7-b102編譯的。估計我下的這兩個版本不對。

 

java agent + Instrumentation

1、Spring-Loaded

SpringSource官網釋出的,用在Grails 2中,允許:新增/修改/刪除 方法/欄位/構造器。型別/方法/欄位/構造器上的註解也允許修改,且也可以新增/刪除/修改enum型別的值。

使用方式:

如在執行tomcat/jetty時的VM引數中指定如上配置即可。無需在debug模式下執行。如果使用的是如idea可以按Ctrl+Shift+F9編譯當前類/Ctrl+F9編譯所有更改的類。

2、Fakereplace 

類似於Spring-Loaded,具體可參考其官網:

https://github.com/fakereplace/fakereplace

https://github.com/fakereplace/fakereplace/wiki/How-It-Works

它的好處是,支援一些框架:

  • Seam 2
  • Weld (基本整合)
  • JSF
  • Metawidget
  • Hibernate (實際是如果實體修改了,重啟整個EMF,也不是很快)
  • Resteasy

具體使用也是在VM引數中指定:

可以到如下地址下載jar包,或自己編譯

http://repo.grails.org/grails/plugins-releases/org/fakereplace/fakereplace-dist/1.0.0.Alpha2/

其提供了一些配置,如:

  • packages 需要熱替換的包
  • log 可選,支援trace,debug,info,error
  • index-file fakereplace索引為的路徑。Fakereplace在第一次執行後儲存這個檔案以加速啟動
  • dump-dir 當熱替換時,Dump類到這個目錄,僅當開發Fakereplace時有用
  • port Fakereplace監聽的埠

它倆的實現很類似,Spring-Loaded使用了CGLIB來實現代理,FakeReplace使用了Javassist來實現的。

還有如Agent Smith,不過N久沒維護了。 其實Play框架也是使用了Instrumentation,但是它是整個替換,所以沒有歸類過來。

以上的都有個缺點:如我在寫spring專案時,無法動態載入如@RequestMapping配置,或動態載入配置檔案。這些在強大的JRebel中都是支援的。

JRebel

JRebel是我目前簡單的最強大的熱替換/熱部署工具。但缺點是收費的,而且不便宜。之前介紹的都是免費的。首先大家可以看一下它支援的特性與JVM Hot Swap對比列表:

JavaEE支援 JRebel JVM Hot Swap
裝載時間 <1s <1s
記憶體洩漏
改變類結構
 改變方法體
新增/刪除方法    
新增/刪除構造器    
新增/刪除欄位    
 新增/刪除類    
 新增/刪除註解    
改變靜態欄位值    
新增/刪除enum值    
改變介面    
替換父類    
新增/刪除實現的介面  
即時構建
跳過WAR目錄的構建    
跳過.WAR/.EAR類更新構建    
跳過.WAR/.EAR資源更新構建    
對映多個source目錄到一個.WAR/.EAR目標目錄    
使用include/exclude模式對映類和資源
使用Ant風格模式對映多個sourcde目錄
使用系統屬性使對映機器無關
Maven外掛
遠端/雲
通過HTTP進行應用更新

JavaEE支援

JSP EL changes
JSP Scriptlet changes
EJB 1.x session bean interface changes
EJB 2.x session bean interface changes
EJB 3.x session bean interface changes
EJB 3.x: adding new EJB
EJB 3.x: adding new EJB reference
JSF changes (Mojarra)
Bean Validation support (Hibernate Validator)
JAXB annotation changes
JAX-RS changes (RESTEasy, Jersey, CXF)
JAX-WS support (Metro, CXF)
JPA changes (Hibernate, EclipseLink, TopLink, OpenJPA)
CDI changes (Weld)
框架支援
Spring Framework 2.x or later
Hibernate
JBoss Seam 2.x or later
Google Guice
Struts 1.x, 2.x
Wicket
Stripes 1.5 or later
檢視完整的框架支援列表
代理支援
CgLib
Javassist
OSGi支援
Apache Felix
Eclipse Equinox

從如上列表看到其不是一般的強大。

接下來看看如何使用(以IDEA為例):

1、首先點選如下圖所示的執行,然後點選Edit Configuration…

2、在彈出的視窗中輸入如下圖所示的jrebel.jar位置


類似於之前的javaagent配置。

3、啟動後,當修改類後,請按Ctrl+F9重新編譯。然後再執行程式即可看到變化。

4、Eclipse內嵌tomcat的配置:


使用起來是非常簡單的。注意:如果使用web容器如tomcat、jetty,請禁用其reload,如jetty,可以配置

<scanIntervalSeconds>0</scanIntervalSeconds> 或者 <reload>manual</reload>。

JRebel也提供如Eclipse、IDEA、Maven外掛,其實沒必要上外掛,直接配javaagent就很簡單。還可以配置

如果有朋友想開啟/禁用某些框架/JavaEE的支援,可以通過新增VM引數,如下所示開啟/關閉:

-Drebel.spring_plugin=true
-Drebel.aspectj_plugin=true
-Drebel.struts2_plugin=true
-Drebel.hibernate_plugin=true
-Drebel.jackson_plugin=true
-Drebel.log4j-plugin=true

完整的框架支援列表

 

還可以通過配置一個rebel.xml來進行選擇性構建:

http://zeroturnaround.com/software/jrebel/how-to-configure-rebel-xml/

 

更多配置請參考其官方的JRebel手冊

到此就介紹完了我見到的所有熱部署/熱替換實現方式,大家還有什麼好的方式歡迎補充。

參考資源:

hotswap 使用者手冊

DCE使用的問題及其解決方法

Dynamic Code Evolution VM

Spring Loaded官網

FakeReplace官網

RJC401:HotSwap和JRebel——幕後的故事

JRebel與Maven整合

JRebel與Eclipse整合

JRebel與IDEA整合

JRebel手冊

相關文章