1. 程式人生 > 實用技巧 >做持續交付概念重要還是場景重要?看“笨辦法”如何找到最佳方案?

做持續交付概念重要還是場景重要?看“笨辦法”如何找到最佳方案?

做持續交付概念重要還是場景重要?看“笨辦法”如何找到最佳方案?

上期文章中我們講到,在經過嚴格的依賴規則校驗和安全審計之後,構建出的軟體包才可以部署釋出。

在開發環境、專案環境、整合測試環境以及預發環境下,我們還要進行各類的功能和非功能性測試,最後才能釋出到正式的生產環境之上。

通常狀況下,做一次軟體版本釋出,必須經過以下幾個環境(如下圖所示)。需要明確的是,專案環境和“小蘑菇”(內部叫法)環境,只有特殊版本才會配備,這裡我們不做強制。

上述這些環境我們在之前都介紹過。而歷經如此多的環境,高效的自動化持續部署和釋出就變得尤為重要。

特別是最後的線上釋出環節,還需要確保業務連續穩定、無間斷,所以,在複雜的微服務架構環境下,我們對軟體的釋出策略選擇、自動化程度和穩定性要求就更高

了。

今天,我們一起看看整個流水線軟體部署和釋出的細節。

軟體的持續部署釋出

這裡,我們直接以生產環境的釋出過程來講解。軟體的部署釋出,簡單來說就是:

將構建完成和驗證通過的應用軟體包,釋出到該應用對應環境下的IP主機上的指定目錄下,並通過應用優雅上下線,來實現軟體最新版本對外提供服務的過程

這個過程會包含的環節,我以圖示整理如下:

我們可以看到,軟體部署釋出,聽上去就是把軟體部署一下,然後啟動起來。這樣的操作方式對於單體架構軟體沒有問題,但是在微服務架構下就滿足不了要求了。

單體架構軟體啟動起來就可以提供服務,但是對於微服務應用,無論停止還是啟動,都需要考慮到對周邊其它依賴和被依賴應用的影響才可以,考慮的點也就相對較多。

我們針對單機發布,分環節來看一下:

  1. 從CMDB中,拿到線上生產環境下的應用主機IP列表去對應關係,目的是要將軟體包釋出到應用對應的IP主機上。

  2. 檢查每臺機器上的服務是否正常執行,如果是正常服務的,說明可以釋出,但是服務本身異常,就要記錄或跳過。

  3. 下載war包到指定目錄。這裡要依賴前期我們介紹的應用配置管理,在這一步要獲取到該應用的原始碼目錄。

  4. 關閉該應用在這臺主機上的監控,以免服務下線和應用終止產生線上錯誤告警。

  5. 優雅下線。RPC服務從軟負載下線,如果該應用還提供了http的Web呼叫,就需要從Nginx這樣的七層負載下線,下線動作均通過API介面呼叫方式實現。

  6. 下線後經過短暫靜默,重啟應用。對於Java應用來說,重啟時可以自動解壓,啟停命令等還是之前從應用配置管理中獲取響應路徑和命令指令碼名稱。

  7. 優雅上線,進行健康監測,檢查程序和應用狀態是否正常,如果全部監測通過,則開始上線服務,開啟監控。

上述是一個應用的單機發布過程,過程比較長,但是可以看出,每個環節並不複雜。這裡我們需要注意兩個關鍵點:

  • 針對場景,進行細分,這樣就可以化整為零,把一個乍看上去很複雜的過程,分解成一個個可執行的步驟。

  • 與服務化的軟負載和註冊中心進行互動,確保應用是可以優雅上下線的,而不是簡單粗暴地啟動和停止。

釋出策略

上述過程是針對單機的操作步驟。但是,如果我們有上百臺主機,甚至一些大的叢集有上千臺主機,這時應該怎麼釋出呢?這裡就涉及到釋出策略問題。

業界常見的幾種模式,如藍綠髮布、灰度釋出(金絲雀釋出)、滾動釋出等等,這幾種模式網上資料豐富,在這裡我們就不逐一展開詳細介紹了。

這裡,我們主要以灰度釋出和滾動釋出的組合方式為例,詳細分析一下這種釋出模式。

前面介紹的線上Beta環境,選擇的就是金絲雀釋出模式,我們內部稱之為灰度釋出或Beta釋出。後來國外Netflix持續交付經驗傳播比較廣,所以我們經常可以聽到金絲雀釋出這種方式,而其本質上還是灰度釋出模式。

Beta環境下,我們會保留1-2臺應用主機,引入較少的線上真實使用者流量。釋出到這個環境上時,對於核心應用和大規模的叢集,我們會靜默較長時間,以觀察應用的新版本執行狀態。

如果沒有嚴重的報錯或崩潰,靜默期過後,我們認為軟體質量和穩定性是沒有問題的,接下來就會發布到正式的生產環境上。

因為生產環境上大的叢集可能會有上百臺甚至上千臺主機,如果每臺主機逐一單獨釋出,這樣會導致釋出效率過低;但是一次性發布數量太多,又會對線上應用容量大幅度縮減,極有可能會導致服務雪崩或業務中斷

所以我們選擇的方式就是滾動釋出,或者可以理解為分批次釋出:即每批次釋出10臺或20臺,升級完成後,再啟動下一批次釋出。這樣每次釋出的機器數量可以自行設定,但是必須低於50%

至此,一個應用的滾動釋出流程就結束了。根據我們實踐的具體情況,這種灰度加滾動的釋出模式,相對平穩和可控。相比於藍綠髮布,不需要額外再獨立一個環境出來,且不需要每次釋出都要做一次整體的流量切換,避免產生較大的操作風險。

對於回滾,我們會根據上個版本的war包名稱記錄,在釋出過程中或釋出後出現嚴重情況時,直接快速回滾。因為這個操作是在緊急和極端的情況下才執行,所以提供一鍵操作,過程跟上述的釋出過程相似,在此也不再贅述。

持續交付體系的收益

持續交付體系運作起來後,整個流水線過程完全自助釋出,運維無需介入,達到了DevOps,或者說是NoOps的效果。如下圖所示:

總結

至此,我們整個持續交付體系的內容就全部介紹完了。對於整個過程的總結,你可以參考本專欄“持續交付”主題的第一篇文章《持續交付知易行難,想做成這事你要理解這幾個關鍵點》,我在文中對整個持續交付體系進行了比較完整的梳理。

細心的你應該可以發現,到本期文章為止,我並沒有提到太多DevOps相關的內容,而這個恰恰是當前業界非常火熱的概念。在寫作過程中,我也沒有特別強調持續交付是什麼,持續整合是什麼,而這些又是當前DevOps裡面特別強調的部分。

我之所以這樣做是因為,概念都是一個個名詞或者Buzzword(時髦名詞),它們所表達的意思也都非常泛,每個人,每個團隊或每個組織對它們的理解以及解讀都是不一樣的。

就拿DevOps舉例,有誰能說清楚它到底是什麼,到底代表什麼意思?估計一千個人會有一千種理解,不同的團隊對它的實踐模式也不一樣。

所以,如果直接從概念出發,反而容易讓我們迷失方向,忘記想要解決的問題,讓我們脫離所處的實際場景,把精力都放在了各種所謂的工具和技術上。這一點也恰恰與我所一直強調的,要從實際問題和業務場景出發來考慮解決方案相違背。

在我們“持續交付”主題的分享中,你可以看到,有很多的解決方案並沒有標準化的模式,也沒有哪一個工具或技術能夠直接解決這些問題。

我們所採取的手段,其實都是些笨辦法:即找到問題,分析問題,調研解決方案,討論碰撞,然後慢慢摸索和實踐,找出最合適我們的方式

希望我的分享能夠給你帶來啟發,就像我們開篇詞提到的:思路上的轉變遠比技術上的提升更為重要

精選提問

  1. 在版本釋出中遇到失敗一般會採用回滾,可是新發布的版本涉及到了資料表結果已經部分欄位的資料初始化,回滾的時候也需要相應的反向操作。在這一點上一般你們會用fyway這樣的資料遷移工具嘛?還是會採用別的方式來對待回滾操作?另外在多版本(小版本)相容的情況下的釋出操作流程會有什麼細節上的變化嘛?

    
    
  2. 我也想做一套持續交付的系統,像阿里雲的雲效,但感覺系統很龐大,開發難度大,有什麼建議嗎?

    雲效是比較完備的一套持續交付體系,可以好好借鑑下,建議分步實施,先理清楚每個環節。
    當然,有條件用雲上產品的話,建議直接用