概要:
- 持續發佈版本所面臨的問題
- 版本快速迭代流程設計
- 集成部署環境構建
一、持續發佈版本所面臨的問題
提問:
- 現在所在的公司是如何發佈版本的?多久發佈一次?
- 已什麼樣的形式進行發佈?
- 有沒有出現過發佈事故?
增量發佈?
修改的 Class 直接丟給甲方 工程師
產品迭代過程
一般情況下產品迭代發佈過程分爲以下幾個階段:
編碼 -> 構建 -> 集成 -> 測試 -> 交付 -> 部署 ,但隨着敏捷開發模式與微服務架構的盛行,導致整個鏈路實施過程變得越來越複雜沉重,迭代週期脫長。 爲了解決這一問題大牛們分別提出了,持續集成、技術交互、技術部署的概念,經證實這是一個行之有效的方式,但同時也對團隊的技能水平提出了過分的要求,所以說現在並沒有完全運用起來,未來的技術發展趨勢整體是朝這個方向走的。現在我們就先來認識一下,持續集成、交互、部署的概念很有必要。
持續集成(continuous INTEGRATE):
持續集成是指軟件個人研發的部分向軟件整體部分交付,頻繁進行集成以便更快地發現其中的錯誤。
持續交付(continuous DELIVER)
持續交付在持續集成的基礎上,將集成後的代碼部署到更貼近真實運行環境的,預演境。
持續部署 (continuous deployment )
持續部署則是在持續交付的基礎上,把部署到生產環境的過程自動化。
企業如何做到持續集成、交互、部署呢?正如網絡流行語:“這個問題充錢就能解決”,大量的私有云廠商通過容器化技術已經打通整條鏈路:無論是自動化測試、持續集成、持續交付、自動化部署都有較成熟的解決方案。
如果企業不願意購買現成的解決方案,那就只能自己動來實踐,當然這個摸索過程會長一些,但也會更貼近企業的實際環境。接下來我們要講的是一個真實的企業產品集成部署解決方案。(注:不一定完全適合你們企業,但借鑑下總是可以的)
二、 版本快速迭代流程設計
知識點:
- 整體流程設計
- 發佈窗口機制
- 發佈計劃與實施計劃
- 時間節點
開發環境===> 測試環境 ==》預演環境 ==》 生產環境
1、整體流程設計
2、發佈窗口機制
上述的發佈流程還是比較重的,我們不可能每天走一遍。可以設定一個固定的發佈時間,一般是設在週四。下午4點準時發佈,如果這個點還沒有來得及實現或測試的需求,則需要到下一下個窗口才能發佈。這樣做的目的是爲了讓團隊中每個人清晰有一個時間概念,知道什麼時候該幹什麼事,避免手腳亂的隨意發佈上線。
3、發佈計劃
很多的時候我們跌代的需求之間是有依賴關係,還有需求的工作量也不一樣,有的下個窗口就能完成,有的則需要更長時間,爲此我們需要提前計劃好下個窗口能上線的需求,避免A需求發佈時,他所依賴的B需求確不能發佈的情況發生,或者中間隨意添加需求,從而讓發佈變得難以控制。
通常我們會在週五前由產品經或測試與開發協商後製定下個窗口期的發佈計劃表。包含以下內容
需求說明 |
需求編號 |
應用系統 |
開發負責人 |
測試負責人 |
對應版本號 |
|
|
|
|
|
|
3、實施計劃
有了發佈計劃 並不意味着我們就可以拿着計劃更新上線了,到了發佈時間計劃的項目不一定能夠如期實現,更重要的是發佈計劃中並不沒有包含實施更新說明如:需要更新哪些SQL腳本哪些配置文件等。而這些都是測試人員在更新環境的時候所必要的。所以在發佈之前需要開發人員填寫一個部署說明文檔其包含如下內容:
需求說明、需求編號、應用系統、依賴系統、項目文件、變更腳本、變更配置、開發負責人、測試負責人、版本編號、發佈時間。 一般由各個開發來共同編寫這個文檔。所以我們需要可以在線共同協作的文本編輯系統來實現。而不是採用桌面軟件來編輯。目前有很多這類的文檔系統如:石默、有道雲、騰訊文檔等。當然你們企業可能禁止訪問公網,或者對信息安全非常敏感那這時我們需要安裝購買:confluence這類的協同軟件。
4、時間節點
整個過程涉及多方團隊協作,只要一方延誤,就會造成其它方 等待或工作推遲的情況發生。比如開發的A需求延遲半天提測就這會導致測試的工作會延盡、從而影響上線時間。爲避免這種情況我們需要設計精細的時間節點如下:
三、集成部署環境構建
知識點:
- 版本倉庫選型
- 更新機制實現(更新腳本、jenkins配置)
- 項目更新
- 配置文件更新
- 版本回滾
- 適應不同環境(開發、測試、運維)
1、版本倉庫選型
我在我們設計的整個流程當中版本倉庫是非常重要的一項,他用於存儲版本發佈所需 程序包、更新腳本、更新配置。這裏我們直接採用SVN實現。爲什麼不採用nexus 或git 呢?因爲nexus 不能存儲更新腳本和配置文件,而git對於測試人員和運維人員使用稍複雜,此外版本倉庫只是單純的存儲,git的特性發揮不出來。
注:下面特整裏了SVN的安裝方法,但這不是本課的重點。
SVN 服務搭建-----------------------------------------------------------------------------------------------
SVN服務安裝
#yum 安裝
yum install subversion
#查看svnserver版本
svnversion --version
創建SVN版本目錄
mkdir -p /data/svn/repository
svnadmin create /data/svn/repository
SVN配置
配置目錄: /data/svn/repository/conf
authz :目錄權限設置
vim authz
#表示添加一個admin帳號,密碼爲 admin123
admin=admin123
passwd:用戶與密碼設置
vim passwd
#表示admin 擁有所有目錄的讀寫權限
[/]
admin=rw
svnserve.conf :svn服務
vim svnserve.conf
anon-access = read
auth-access = write
password-db = passwd
authz-db = authz
realm = /data/svn/repository
啓動svn 服務
svnserve -d -r /var/svn/svnrepos
基於客戶端訪問svn
默認端口:3690
地址:svn://192.168.17.200:3690/
end------------------------------------------------------------------------------------------------------------
2、更新機制實現
更新機制是指項目如何進行實質的更新,圖中我們充計了兩種方式:一種是自動推送,另外一種是手動拉取。前者用於開發環境、後者可以用於所有環境。
手動拉取
拉取更新流程如下:
上述流程是由自己編寫的一個 deploy.sh 腳本實現:
#!/bin/bash -e
cd "`dirname $0`"
. ./pom.sh
#1. download war, ready env
echo "deploy time: $work_time"
mkdir -p war/
war=war/$pom_a-$pom_v.war
download_path="$nexus_redirect?r=$pom_r&g=$pom_g&a=$pom_a&v=$pom_v&e=war"
wget $download_path -O $war
deploy_war() {
target_d=war/${pom_a}-${pom_v}-$work_time
target_dir=`pwd`/$target_d
if [ ! -f "$war" ]; then
echo "war not exist: $war"
exit 1
fi
unzip -q $war -d $target_dir
cp -r app-conf/* $target_dir/WEB-INF/classes/
rm -rf appwar
ln -sf $target_d appwar
./tomcat.sh stop
target_ln=`pwd`/appwar
echo '<?xml version="1.0" encoding="UTF-8" ?>
<Context docBase="'$target_ln'" allowLinking="true">
</Context>' > conf/Catalina/localhost/ROOT.xml
./tomcat.sh start
}
deploy_war
注:在上述deploy.sh 腳本中還用到了 pom.sh 與tomcat.sh 其作用後續在做說明。
在測試環境、預演環境還有生產環境的時候 ,我們是不會直接從nexus 中下載的,而是特定的版本庫。這時只需要修改 $download_path 參數即可。
自動推送:
自動推送方式採用在jenkins 構建完成之後,執行遠程sh 腳本 用於下載本次構建WAR包,在自動部署重啓。基jenkins 配置如下:
注:前提條件是 jenkins 服務要在業務服務器上做免密登錄。
此處只能用 Execute shell 而不用能用:Execute shell script on remote host using ssh ,因爲BUILD_ID=dontKillMe 不會被修改 ,而是當作參數來傳遞
${BUILD_URL} 是一個隱示參數,表示本次構建的URL。
jenkins.sh 是放置在應用目錄下的一個腳本:
#!/bin/bash -e
cd "`dirname $0`"
. ./pom.sh
#1. download war, ready env
echo "deploy time: $work_time"
mkdir -p war/
# 配置下載存放目錄
war=war/$pom_a-$pom_v.war
# 基於遠程傳過來的 BUILD_URL下載本次構建
wget "${BUILD_URL}${pom_g}\$${pom_a}/artifact/$pom_g/$pom_a/$pom_v/$pom_a-$pom_v.war" -O $war
# 執行部署函數
deploy_war
配置文件更新:
我們在跌代的過程當中總共 要經過四個環境,每個環境的配置信息是不一樣的,如何在更新項目的時候把對應的配置文件也更新了呢? 有在有一種做法是 採用 Disconf 之類的配置系統來管理各個環境 的配置,但這裏我們採用的是一個簡單些的方案: 把當前環境 的配置文件放到 app-conf 目錄下,等更新腳本的時候會一同覆蓋原來的配置文件。
版本回滾:
之前在部署的時候是通過軟鏈接的形式指向指定程序目錄,而且原歷史版本不會刪除,回滾的時候只要把原軟軟鏈接 指定歷史程序目錄即可。而且配置文件也會一同回滾。
更新腳本說明:
前面說過deploy.sh 部署腳本中還用到了 pom.sh 與tomcat.sh 等腳本,這些腳本的作用是什麼呢?整體邏輯如下依賴關係如下:
說明:
- env-set.sh : 設置jvm 、Tomcat 等環境參數
- pom.sh: 設置當前項目的 groupid 、artifact、version 信息
- tomcat.sh:啓動關閉Tomcat
- deploy.sh : 下載並部署項目
- jenkins.sh: 用於被jenkins 遠程觸發下載指定更新版本
注:以上腳本分別存儲至 env-set.sh 與 Tomcat-deomo.zip 私聊發