軟件的升級方法


作者:姚冬
鏈接:https://www.zhihu.com/question/24263552/answer/27216798
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

在互聯網不太普及的時代,很多軟件公司還是會發布離線更新包,這種更新包其實就是個安裝程序,只是安裝的內容是更新的部分,沒有變化的文件直接用已經安裝的版本的。此外這些安裝程序還會修改一些系統配置以適應新版本的功能,比如注冊COM組件,修改注冊表等。

現在互聯網已經十分普及,幾乎所有軟件都采用在線升級,具體實現上,有下列幾種做法。

1. 比較簡單的,通過http協議,檢測是否有更新,就是把本地版本號發給服務器,服務器會返回一個配置文件,里面表明是否有新版本,並且帶有新版本的下載地址,更新程序按照URL下載新版本的安裝程序,然后執行這個安裝程序,用戶根據安裝程序提示進行更新。

2. 再進化一步,每次都重新安裝太麻煩,更新程序下載一個新版本的壓縮包(zip/7z),然后幫用戶解壓縮到安裝目錄。現在客戶端都追求簡單設計盡量降低和系統的耦合,基本都是復制文件就算安裝的那種綠色軟件,所以把新版本的文件一更新就能用。

3. 如果某個軟件體積已經比較大了,比如大於10MB,每次都下載一個完整的新版本的話,下載就太慢,安裝也慢。既然本地已經有個安裝版本了,每次更新其實變化的東西也不是很多,那么有個軟件就下載一個更新文件的壓縮包,然后解壓縮到安裝目錄覆蓋舊文件。

4. 有的軟件更大,更新也頻繁,每次更新的exe dll模塊大多都有更新,所以還是要下載很大的更新包,於是有人用 bsdiff算法求新版本和舊版本的二進制差異,如果新版本就是修了bug改了幾行代碼,那么bsdiff生產的補丁也就幾KB,下載的二進制補丁用bspatch來更新本地版本。bsdiff的算法庫很小,大約才30+KB很容易集成到更新程序里。

5. 有的軟件更更大,即使用bsdiff產生的補丁還是很大,有人搞出了更給力的補丁算法,Chrome的方法,
從介紹看,它比bsdiff生成的補丁還要小一個數量級,這個想法相當巧妙,對於那種代碼模塊為主的程序尤其有效。很多時候我們只改了幾行代碼,但是DLL模塊卻改變了很多,主要是因為代碼優化鏈接時重排造成的,如果比較匯編代碼差異就會很小,Courgette就把DLL反編譯成匯編碼,然后和舊版本的匯編碼比較得到差異,更新的時候把舊版本也反編譯打補丁然后再編譯成DLL。這樣的話如果只改了幾行代碼,那么生成的補丁可能就幾十個字節。

6. 隨着更新包越來越大,更新下載和安裝的時間也越來越長,造成用戶長時間等待,有的軟件采用了后台下載后台更新的方式。所謂后台下載就是無論用戶是否點了立刻更新,只要有新版本就在后台偷偷給用戶下載下來,有點流氓,但這也是為了用戶體驗呢。那么后台更新呢,正在運行的程序,每個文件都是被占用的,是不能更新的。還是Chrome想出來的,雙目錄更新,把就版本先復制到另一個目錄,然后更新這份新復制的,下次用戶啟動的時候就直接啟動新版本。
比如 Chrome有如下的目錄結構
Chrome
    +Application
        +35.0.1916.153
        +35.0.1916.114
         chrome.exe 

它用版本號做目錄名,每次升級的時候更新新版本,舊版本在另一個目錄運行不受影響。下次啟動的時候 Chrome.exe永遠加載最新版本的dll運行就好了。chrome.exe是個很小的程序,里面的邏輯就是檢測下版本號加載最新版本的dll,這樣簡單的程序本身幾乎不需要更新。


在需求的推動下,現代客戶端的升級程序已經相當復雜了,包括了支持灰度放量的新版本檢測,http斷點續傳下載,MD5完整性校驗,bsdiff/courgette 二進制補丁更新,雙目錄迭代升級等技術。到了移動app時代,以上這些技術都用不到了,操作系統壟斷了升級機制,只能通過操作系統檢測下載安裝更新,iOS做得相當徹底,Android還給app留了條自己下載apk安裝的路,但是二進制補丁完整性校驗等就徹底不需要app開發者自己操心了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM