聊聊OSGI
當初看深入理解Java虛擬機的時候,對於osgi的部分就只是簡單的略過,畢竟很少使用,也很少有人提起,感覺就是一個活在書本上的東西。不過最近。新公司的項目有用到osgi,所以還是得學習一下
1. 模塊
OSGI是一個基於Java語言的動態模塊化規范。OSGI中的模塊稱為bundle,以jar格式封裝,和普通的jar包區別不大,但是bundle可以通過Import-package聲明對其他bundle的依賴,也可用通過Export-Package聲明對外提供的服(在MANIFEST.MF文件中配置),這樣就可以精確的控制bundle內部服務的可見性。
OSGI的模塊化和平級依賴,使得OSGI的程序基本上可以實現bundle的熱插拔,一個bundle的停用,只會影響到依賴該bundle的bundle,如果一個bundle不依賴任何其他的bundle,那么停用,升級部署的影響基本可以忽略。
2. 類加載
OSGi為每個bundle提供一個類加載器,OSGI的類加載順序不同於雙親委派模式的向上委托,而是根據MANIFEST.MF文件的配置,去尋找類對應的加載器,類的加載可以在bundle間互相委托。所以OSGI的類加載器結構是平級的網狀結構。
- 步驟
- 檢查是否java.*,或者在bootdelegation中定義。如果是,則bundle類加載器立即委托給父類加載器(通常是Application類加載器)
- 檢查是否在Import-Package中聲明。如果是,則找到導出包的bundle,將類加載請求委托給該bundle的類加載器。如此往復
- 檢查是否在Require-Bundle中聲明。如果是,則將類加載請求委托給required bundle的類加載器
- 搜索bundle的內嵌jar的類路徑(Bundle Class Path)。如果找不到類或資源,繼續下一步。
- 查找Bundle的Fragment Bundle中導入的包, 如果沒找到繼續下一步
- 如果類或資源位於自己導出的包中,則搜索結束並失敗。
- 否則,如果類或資源位於DynamicImport-Package導入的包中,則嘗試動態導入包。
- 如果動態導入包成功,則將請求委托給導出這個包的類加載器。如果請求被委托給導出類加載器並且找不到類或資源,則搜索終止且失敗
1. 特點
- OSGi的入門門檻在Java眾多技術中算是比較高的
- OSGi本身就具有較高的復雜度
- OSGi確實會增加系統不穩定的風險
bundle盡管可以為隔離的服務建立獨立生命周期管理的熱部署方式,以及明確的服務導出和導入依賴能力,但是其最終基於jvm,無法對bundle對應的服務實現計算資源的隔離,一個服務的故障依然會導致整個jvm crush,這使得在一個運行時的osgi上部署模塊級服務只獲得了模塊部署和啟停隔離,
服務明確依賴的好處,但是沒辦法實現計算節點的線性擴展,在當前分布式,微服務,網絡計算的趨勢下,使得osgi只適合構建單一服務節點的內部應用,但是其分離的bundle的部署負擔對於微服務架構來說,有點用大炮打蚊子的臭味
目前我的理解就是,一個龐大單體應用,需要分團隊開發,用戶量不多,需要分布式部署,但是又不需要像微服務架構一樣,按服務拆分得那么細,那么就可以使用OSGI架構。