一般談到持續交付或自動化部署,都是具備最新架構思維的自主開發方面,或者是利用Ansible、藍綠部署、容器等實現應用程序的快速部署等方法。
但大多數供應商系統的設計陳舊,變更重度依賴數據庫更新(很多邏輯通過存儲過程來實現)。面對這樣的系統,要實現持續交付,需要另闢蹊徑。
我們管理的供應商系統是一個服務於全球包括亞洲和歐洲10個國家和地區的單體應用,是基於.NET和Oracle數據庫開發,運行在Windows Server和IIS服務器上的。每個月有超過20個變更需要發佈到生產環境。
我們一直採用月度發佈的節奏。每次發佈的範圍大、風險高,需要全球各地業務部門加班配合測試,執行時間長。由於維護時間窗口(沒有業務使用,可停機的時間)只有週末和工作日早上6點至8點,要提高發布頻率,只能靠加班,顯然不可持續。
01
—
目標
爲了引導各部門實現DevOps,公司定了明確的目標——發佈次數翻倍,故障數減半。雖然我們並不關注具體數字,但這也給了所有部門方向與壓力。對於我們來說,如何在不加班的情況下實現在工作日發佈成了具體目標。
02
—
重要發現
我們對系統和發佈過程做了深入分析,得出以下的重要結論:
大部分的發佈是數據補丁,這些數據補丁隻影響單個國家或地區,範圍小,風險低。如果在工作日就把這些數據補丁發佈了,既可大大加快其業務價值的實現,提高業務部門的滿意度,也解決了我們“80%的問題”(柏拉圖定律)。剩餘的少數有全球影響的其他補丁,則繼續在月度發佈(週末)完成,但剔除了大部分數據補丁後,其範圍已經大大縮小,風險也降低了。
另外,由於數據補丁隻影響單個國家或地區,我們不必拘泥於早上6點至8點這個全球維護時間窗口。因爲每個國家或地區的業務時間不一樣,我們完全可以根據各個國家或地區的業務時間制定相應的數據補丁發佈時間窗口,比如香港是晚上11點到次日8點,歐洲是凌晨2點到下午4點等,給了我們更大的靈活性。
03
—
實施方案
過去,供應商提供了補丁後,我們IT團隊需要手動部署到測試環境,然後通知業務測試。這個過程費時費力,也沒有什麼價值。考慮到供應商駐場人員可以訪問我們網絡與Github,我們考慮把這個過程自動化了,擬定了以下的流水線設計:
(點開圖片可查看清晰大圖)
1、測試環境
目標:IT團隊不需要介入
供應商駐場人員把補丁發佈提交到Github的測試分支,觸發相應的Jenkins Job;
Jenkins Job觸發公司自研的數據庫自動部署工具,把腳本部署到相應的測試環境;
我們要求供應商在提供補丁時,也要提供相應的驗證腳本,在部署時一同執行;
驗證通過後,我們通知業務開始驗收測試(UAT);
驗證不通過,驗證腳本會拋出異常,部署工具會通知我們執行回滾。
2、生產環境
目標:在維護時間窗口定時自動發佈
當該補丁用戶驗收測試(UAT)通過後,我們把它合併到Github的master分支,並按公司規定發起發佈審批流程;
設定相應Jenkins Job的計劃執行時間(下一個工作日中該補丁涉及到的國家或地區的維護時間窗口);
Jenkins Job觸發數據庫自動部署工具,把腳本部署到生產環境;
驗證腳本通過後,發佈成功;
驗證不通過,我們將收到通知,上線執行回滾。
04
—
成果
通過這套方案,我們實現了以下幾個目標:
大部分的數據補丁不需要等到月度發佈才上線,實現了持續交付,大大加快了其業務價值的實現,提高業務滿意度;
IT從部署這項費時費力、價值不大的工作中解放了出來,可以做更有價值的事情,如業務需求或故障分析;
補丁發佈上線不再是一項高風險的事情,業務和IT都不再對每次發佈戰戰兢兢;
大大減少加班時間;
每月發佈次數從1到2次上升到十幾次,由於每次發佈的範圍小,風險低,也減少了因發佈引起的故障數量,滿足了公司的DevOps目標。
05
—
落地難點
實踐過程總不是一帆風順的,我們在過程中也遇到了很多問題,這部分可以分享一些我們針對落地難點的做法,以供參考。
1、進度保障
由於日常的交付和維護工作佔用了我們幾乎全部的工作時間,文中提到的這類重要而不緊急的事情通常都會無疾而終。爲了避免這種情況,我們利用每日站會來討論落地細節和跟蹤進度。
我們把站會分爲兩類:一、三、五討論日常工作;二、四討論這個流水線的實施。
這樣我們便可確保每天都有進度,並在一個多月的時間內實現了預定目標。
2、自動驗收
由於發佈到生產環境的過程可能是在非工作時間內自動進行的,我們需要有自動驗收發布結果的過程,以確保系統在發佈後能正常運行;當驗收不通過時,觸發發佈失敗,通知我們執行回滾操作。
這就需要供應商在提供補丁腳本時,也要提供驗收腳本,作爲部署的一部分,自動測試補丁部署後的結果是否符合預期。
舉個栗子:
DECLARE
NumberOfPatch_Actual number;
NumberOfPatch_Expect int:=2;
BEGIN
select count(*) into NumberOfPatch_Actual from USERS where a.user_id = 'USERA';
If
NumberOfPatch_Actual <> NumberOfPatch_Expect
then
RAISE_APPLICATION_ERROR(-20001,'Error, This is testing for the log capturing');
END if;
END;
/
這種變相的測試驅動編程(TDD)的思想需要供應商習慣和配合。
3、自動回滾
有了自動驗收,如何實現自動回滾,從而使整個過程完全自動化,是我們其中一個考慮點。但是由於補丁執行過程有若干步,很難預知每一種的失敗情形,最終我們決定還是採用手動回滾比較穩妥。
4、失敗通知
當驗收腳本運行不通過時,意味着發佈失敗,如何讓在工作時間外的我們得到及時的通知,立即上線執行回滾操作,是確保系統正常運行的關鍵。
但是目前我們的流水線系統只能發出郵件通知,沒有針對手機的即時通知手段,這一點仍需要尋找更有效手段。
06
—
總結
常說的持續交付和自動化部署方案大多是針對自主開發和應用程序的。
對於設計陳舊的供應商系統或遺留系統,多數變更在數據庫上實現,要實現持續交付,可能需要另闢蹊徑。
在考慮方案前,要深入理解你的系統和發佈過程;利用每日站會,持續討論落地細節和跟蹤進度,確保目標達成。
關於作者
就職於世界500強銀行,負責基金服務業務軟件開發與交付
敏捷、精益、DevOps專家
精通極限編程、Scrum、看板方法、測試驅動開發、持續集成、行爲驅動開發、DevOps工具棧
曾在GDevOps、DevOpsDays Meetup、中國軟件技術大會等論壇發表主題演講
著有《獵豹行動:硝煙中的敏捷轉型之旅》一書
有聲書已登錄喜馬拉雅,適合路上聽書的你
長按二維碼識別收聽:
購書通道
—
紙質書、電子書在京東、噹噹、亞馬遜等渠道已全面上架,搜索“獵豹行動 硝煙中的敏捷轉型之旅”。
噹噹自營購書碼:
京東自營購書碼:
關注公衆號看其他原創作品
覺得好看,點個“在看”或轉發給朋友們,歡迎你留言。