PC客戶端軟件升級方式簡史

  • 在windows8以前,微軟的Windows平臺一直沒有提供一個想蘋果的AppStore或者Linux的包管理這樣的統一軟件管理工具。因此Windows下的軟件安裝、升級、卸載的事情通常都是軟件本身去負責。這樣致使Windows下的軟件安裝、升級、卸載的方式五花八門,但整體上來講方法都大同小異。安裝程序主要分兩種,下載器的安裝包和離線安裝包,這個不贅述。
  • 今天重點聊一下升級,升級功能看似簡單,但對於一個想持續經營的客戶端軟件來講倒是一個重要的生命線。開發團隊辛苦修改的bug、作的新功能都但願用戶能立刻經過升級新版本體驗到。
  • 在互聯網還沒普及的蠻荒年代,不少軟件公司升級都是發佈離線升級包,通常這種包就是一個安裝程序,它只負責安裝程序須要更新的部分,而後作一些修改註冊表之類的系統配置以適應新版本的功能。
  • 如今互聯網普及後,全部的PC客戶端軟件基本上都是使用的在線升級。git

    • 最簡單的在線升級方式是首先客戶端發送檢測更新的消息到服務器,服務器給返回是否有新版本,最新版本號以及下載地址等信息,客戶端就根據這些信息處理。若是有更新就去剛剛獲取到的地址下載最新的安裝程序,而後執行安裝程序更新。
    • 後來你們以爲每次都從新安裝太麻煩,並且安裝包也特別大,下載也很是耗時。因而這個下載的程序被替換成了一個壓縮包,裏面裝的是程序須要更新的文件。升級程序下載好壓縮包後再解壓到安裝目錄中就完成了軟件的升級。
  • 隨着敏捷開發方式的普及,軟件的升級就變得愈來愈頻繁了。對於PC客戶端軟件每次升級時主程序以及一些重要的動態庫都有可能更新,因此下載的壓縮包也會比較大。因而就產生了比較文件二進制差別的算法BsDiff,以及Google基於其進一步改進的Courgette(小胡瓜)。這些算法的加入可讓補丁包縮小了n個數量級。這樣須要客戶端去下載的壓縮包就會很小了,下載耗時也會大大縮短。
  • 另外值得一提的是,隨着軟件升級包大小愈來愈大,用戶下載更新文件的等待時間也愈來愈長,因而有些軟件就採用了後臺靜默下載的方式。這種方式雖然流氓,但可能對於用戶來講體驗要好一些。那麼這種狀況下主程序通常都還在運行,而升級程序下載完成後想要更新文件當即升級就必須關閉主程序而後進行文件替換,以避免文件被佔用,致使升級失敗。因而Google的chorme搞出一個雙目錄更新的方法來應對這種狀況。所謂雙目錄更新就是把原來的文件先複製到另外一個目錄下,更新程序的時候就更新這個文件目錄,升級完成後就直接重新的目錄中啓動新版本。
  • chrome的目錄結構是這樣的:
Chorme
    +Application
        +57.0.2987.110
        +57.0.2987.88
            chrome.exe
  • 能夠看到,他是以版本號作目錄名。之後啓動chrome.exe時去加載最新版本就能夠了。固然它能這樣作主要由於chrome.exe自己是個很小的程序,基本它自身是不須要升級的,它主要負責的就是檢測版本號而後加載新版本的dll。
  • 固然如今的客戶端升級程序還涉及一些入灰度,md5完整性檢測斷點續傳等技術這裏也不在贅述。下面我簡單介紹一下BsDiff和Courgette。
BsDiff: Linux中的一個開源工具,致力於快速和輕量的更新Linux的操做系統漏洞(跟微軟的安全補丁相似),其算法的核心思想是基於統計學規律進行近似匹配,而後經過一系列的變化(好比BWT變換)提升「近似段」的壓縮率。
Courgette: Google Chrome升級系統的核心模塊,基於BsDiff,但對其進行了一系列的改進,將平臺相關的信息(即x86彙編指令)融入其中,以指望更精確的定位指針,從而避免統計算法在差別明顯時候的錯誤率。
  • Google官方給了一個10M的升級包例子使用bsdiff能夠看到包小了很多,用Courgette更是少了幾個數量級。

  • 使用bsdiff算法咱們的升級過程是這樣的:
server:
    diff = bsdiff(original, update)
    transmit diff

client:
    receive diff
    update = bspatch(original, diff)
  • 大體流程就是這使用bsdiff算法比較不一樣版本的二進制文件製做補丁包,客戶端下載補丁包後調用bspatch生成新的二進制文件。
  • 使用Courgette的升級過程是這樣的:
server:
    asm_old = disassemble(original)
    asm_new = disassemble(update)
    asm_new_adjusted = adjust(asm_new, asm_old)
    asm_diff = bsdiff(asm_old, asm_new_adjusted)
    transmit asm_diff

client:
    receive asm_diff
    asm_old = disassemble(original)
    asm_new_adjusted = bspatch(asm_old, asm_diff)
    update = assemble(asm_new_adjusted)
  • Courgette對於bsdiff的優化主要就是在adjust這一步上,具體能夠參考Courgette官方說明
  • 最後,Google還開源了一套Windows下的升級協議,你們有興趣也能夠研究下omaha
相關文章
相關標籤/搜索