演講實錄——倉庫依賴管理器 [復制鏈接]

2019-5-9 10:52
九霄逆鱗 閱讀:245 評論:0 贊:0
Tag:  

本文來自2019安卓巴士開發者大會現場實錄,由于錄入匆忙,內容可能存在偏差,歡迎大家掃描文末二維碼查看現場實錄視頻和下載大會完整PPT。講師:王世昌


大家上午好,今天我分享的主題是關于Android工程效率方面的,倉庫依賴管理器。

 

個人簡介


我先介紹下,我常用的網絡ID是墨鏡貓和JackyWang,我在github的star,java方面的話有四千七百多,總的star在一萬兩千多,在深圳java分類排名應該可以排到前三。我之前在滴滴和樂視工作過,現在在TCL·雷鳥。

 


開源貢獻


給大家說下我這幾年對開源社區的貢獻,原創的項目有7個,貢獻的代碼有39.4w行,和8個國家12個地區的開發者一起維護其中的3個項目,其中兩個倉庫在各自的類別里面排到了前三。


我是從14年開始做開源,一直到現在,中間換了一次ID,所以你們看到我的賬號是從16年開始的。我14年開始做開源的時候,當時是做了一個小項目放了上去,后來就過了一年多時間,突然有一天有一個愛爾蘭的程序員給我發郵件,說你做的這個開源項目還可以,正好我們這有一個可以合作的項目,后來我們就聊了聊,大概意思就是想讓我根據我那個開源項目給他們做下定制,價錢大概是三千美金。這件事對我觸動還是非常大的,開源社區就像你和世界上其他人溝通的一個窗口一樣,可以把你和任意位置的人連接起來,并產生價值。從那之后就一直做開源到現在,收獲的遠比我之前想象的要多得多,認識了很多有趣的人、見識到了世界級的項目是什么樣的還認識了像Facebook、微軟這種級別企業的Hr,開源社區的價值還是非常大的。

 


倉庫維護的痛點


接下來說下依賴管理器,我們先看下這張圖,一個常見的依賴關系圖,這個就像一個倒立的大樹一樣,每一個葉子都是一個倉庫,樹根就是主客戶端,樹里面每個葉子之間也有很復雜的依賴關系,如果這個時候監控這個葉子出現了問題,就像這樣,依賴他的上面的十幾個葉子都會受到影響。


假如你改動了一個倉庫,比如這個監控倉庫,受影響的有依賴他的十幾個倉庫,就是這個圖里面紅色箭頭指的地方,每個受影響的倉庫都得升級到修復過后的版本,去一一驗證,而且這個過程非常容易反復,比如你修復了一個問題,對日志生效了,但對圖像又產生了問題,再修復,再發版本,還要再把十幾個倉庫升級再去驗證,不停的重復這個過程,浪費很多時間。

 

那怎么去提升倉庫的維護效率,減少驗證的次數?

 


解決方案


那有沒有更徹底更高效的方式,在主工程里面把十幾個受影響的倉庫一次性驗證完,只驗證一次行不行。


那怎么才能實現只驗證一次呢?就是把受影響的線上倉庫,轉為本地的可修改可編輯的源碼倉庫。比如我現在要修復監控倉庫,我把線上監控倉庫轉為本地源碼倉庫。

 

上面受影響的十幾個倉庫依賴的都是本地的源碼倉庫,而不是線上地址。這樣有問題只需要在本地監控倉庫修復,改完后對依賴監控的十幾個倉庫同時有效。這樣就可以了,對吧?

 

那關鍵是怎么把線上倉庫轉為源碼倉庫,最原始的方式就是把線上的地址在工程里面注釋掉,把源碼工程include進來。這種方式對于較復雜的項目來說,成本太高,也不可維護。

 

我們是希望只需要一個開關,就可以靈活的切換線上線下依賴。打開就是本地源碼工程,關閉就是線上依賴。我們看下該怎么去實現。

 


關鍵點


配置語言怎么選?


首先配置該怎么選?配置可選的方式有很多種,json、xml、dsl或者其他的配置語言。json、xml在結構化擴展方面還是挺強的,但是一旦結構變得復雜,可讀性就會比較差,我們看下這個對比圖,左邊是DSL,右邊是同樣結構的JSON描述,很顯然json閱讀起來還是挺困難的,關于DSL有一句話挺有意思,“你以為這是一句話,其實這是一段腳本”

 

動態加載DSL


解析json和xml其實都比較簡單,就是讀文件就好了,但是對于dsl這種怎么辦?

關于dsl文件其實本質上還是一個腳本,關于dsl有句話也是這么說的,你以為這是一句話 其實這是一個腳本。所以我們首先還是去動態加載這個腳本,在groovy里面提供了groovyshell,可以加載任意的groovy腳本,調用evaluate方法就可以加載獨立的groovy 腳本,evaluate方法可以接受腳本字符、文件、Uri都可以。加載腳本之后,我們還需要拿到我們在dsl里面配置的信息,就是pod里面的東西,就是在定義腳本的地方,定義一個接受閉包的函數,函數名為pod,當groovyshell去加載腳本的時候,遇到pod配置,就會被這個函數接收,然后就可以把我們在項目中配置的dsl信息拿到。


簡單來講,就是通過groovyshell去執行這個dsl腳本,每一個pod可以看成是一個函數調用,括號里面的就是傳進去的參數值,調用這個函數的聲明就是這樣寫,然后我們就可以拿到我們在項目中的配置。這樣就完成了dsl的動態加載。

 


動態包含任意地址本地倉庫


首先,包含進來的項目才能依賴,所以第一步我們需要能動態的include本地任意路徑的源碼模塊。在gradle 初始化階段加載settings.gradle 時候,去apply我們的插件,這個時候可以拿到settings實例,這個和配置階段拿到的project是不一樣的,settings里面有個很重要的接口include,include里面填上我們配置的項目名稱就可以了,和我們直接在settings.gradle里面直接寫include是一樣的,不一樣的是我們這個是動態的。然后需要對我們剛剛include進去的project指定路徑,settings里面可以通過project拿到我們指定名稱的項目描述,在這個描述里面可以配置路徑,任意的本地路徑。

 


動態去除線上、添加本地倉庫


經過之前的準備,終于到了最后一步,按照我們的配置去修改這個依賴關系了。

第一步,怎么把線上的依賴去除掉?在gradle配置階段,我們每一個project都會apply我們的插件,apply的時候我們就可以拿到當前project實例,這和上面那個初始化階段是不一樣的,那個拿的是settings實例,我們通過project里面的configuration,可以去配置我們需要去除的線上依賴信息,configuration的exclude接口接收的是一個map,在這個map里配置我們在DSL里面配置的name和group就可以了。


下一步,我們需要把我們之前include進來的project,添加到我們的項目中去,通過我們當前的project實例,拿到當前工程的依賴關系,這個依賴是一個DependencyHandler,這個handler使用來描述依賴關系的,通過handler的add接口就可以把我們的本地倉庫依賴動態添加進去,add接口接收buildtype和project實例,buildtype就是我們平常依賴使用的compile apiimplementation這些東西。

 

總的來說,通過配置信息把我們需要去除的依賴填進去,通過DependencyHandler把我們本地的project依賴添加進去,這樣就實現了動態替換,線上依賴切換為線下依賴。

 


流程


然后我們看下實現流程,大概分為兩個流程,初始化階段和配置階段,在gradle初始化階段會先解析dsl,然后把需要調試的模塊include 進來,在這中間可以做很多事情,比如我想依賴的是問題修復的分支,那就配置下分支名稱就可以,執行自定義的hook命令。在gradle配置階段,根據我們dsl的配置信息,去在依賴樹里去尋找需要替換的節點,就像一個毛毛蟲一樣,去反復的去查找需要替換的葉子,找到后發現需要替換,就把需要調試的線上模塊替換成本地的模塊。因為倉庫變多后,dsl的配置變多,所以我這還有一個輔助生成dsl的任務,他會自動掃描當前哪些是我們可以調試的,比如我們內部的maven倉庫,把依賴樹的信息轉換為dsl,這個功能目前還在測試階段,還沒開源出來。

 

總的來說,大致分為兩個流程,初始化階段先把工程include進來,配置階段再把線上依賴去除,添加本地依賴。

 

我們回顧下,這個插件解決的是什么問題?解決的是maven倉庫依賴復雜,修復的過程繁瑣。那是怎么去做的?用DSL配置倉庫的基本信息,在gradle初始化階段插件動態include倉庫的源碼工程,在配置階段插件動態去除線上依賴、動態添加本地依賴,這樣就做到了動態替換的效果,提升我們的維護效率,對吧。

 


效果


我們看下效果,首先我們現在的主工程是monitor sample,在項目根目錄配置一個dsl文件,內容的話就是這樣,每一個倉庫對應一個pod,pod里面有開關,項目的name和group就是對應一個線上地址(圖里面線上地址和pod對應)然后把需要調試的模塊打開,重新sync工程,這時候上面就會出現本地的源碼倉庫,然后線上倉庫就會被轉為線下源碼倉庫,這時候可以對需要修復的倉庫編輯、調試、驗證功能、發布,只需要驗證一次,節省很多時間。

 

我在舉一個實際的例子吧,比如說我們現在有一個30人的團隊,這三十人分成6個業務線,每個業務線都依賴了我們底層的網絡庫,網絡庫針對每個業務線都有相應的緩存及加密策略。如果這時候需要修改網絡庫的緩存策略,先在網絡庫的源工程里面去做修改,然后再發布到內網的maven服務器,然后再升級各個業務線的網絡庫版本號,再去驗證,如果修改的功能不能滿足需求,還得重新走上面的流程,浪費很多時間。那把網絡庫的依賴通過插件轉為本地依賴,是不是就可以一次驗證完了?對各個業務線驗證完成之后再發布,不會重復的去走發布-驗證這個流程,節省很多時間。


 

今天分享基本就是這些,然后這些是我的聯系方式github、個人網站和我的微信,大家如果有疑問在交流群里或微信問我都可以,謝謝大家。





現場PPT分享:

      關注【安卓巴士Android開發者門戶】公眾號,后臺回復“420”獲取講師完整PPT。


大會現場視頻小程序:




歡迎前往安卓巴士博客區投稿,技術成長于分享

期待巴友留言,共同探討學習


分享到:
我來說兩句
facelist
您需要登錄后才可以評論 登錄 | 立即注冊
所有評論(0)

領先的中文移動開發者社區
18620764416
7*24全天服務
意見反饋:[email protected]

掃一掃關注我們

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粵ICP備15117877號 )

两码中特期期