1. 程式人生 > >Jenkins加Shell實現最簡單的持續部署

Jenkins加Shell實現最簡單的持續部署

大量的有關持續整合的書籍與文件中,基本都提到了持續部署這個步驟,然而具體怎麼實現,並沒有通行的做法,對於典型的Java Web應用來說,大致有兩個思路,一是通過web容器(如Tomcat、JBoss)提供的介面部署,這方面的代表就是Cargo,然而,其缺點是配置複雜且不夠穩定,我的經驗是,部署了很多次之後,容器的JVM就會記憶體溢位,當然這個和具體容器有關,部署多少次之後才溢位,也要看Web應用的大小。

第二種初看起來會更復雜的做法是自己寫Shell指令碼來停止容器、更新Web應用、然後再啟動容器,其實,如果你懂點Shell,這種方法非常簡單,而且這種方法非常穩定,因為每次直接殺JVM程序,直接避免了記憶體溢位的問題。以下是具體的步驟,以Jenkins和Tomcat為例:

1. 配置Jenkins的Build Job在完成之後Archive war檔案備用

這樣每次Build完之後,到對應的Job,如:http://10.12.136.115:8080/job/fileserver/lastSuccessfulBuild/artifact/my-app/target/my-app.war。

另一種方法是直接讓Jenkins Build完了之後直接deploy到Nexus,之後就可以直接從Nexus獲取了,細節這裡就不解釋了。

2. 編寫部署指令碼並測試

指令碼的基本思路就是,看有沒有容器在執行,如果有就kill掉,然後從Jenkins/Nexus下載最新的war檔案,替換掉舊的,再啟動容器,如:

#!/bin/bashexport JAVA_HOME=/usr/java
tomcat_pid=`/usr/sbin/lsof -n -P -t -i :9009`[-n "$tomcat_pid"]&& kill -9 $tomcat_pid
cd /home/admin/
mv myapp.war myapp.war.bak
wget http://10.12.136.115:8080/job/fileserver/lastSuccessfulBuild/artifact/my-app/target/my-app.war
rm /home/admin/apache-tomcat-7.0.40/webapps/myapp.war
rm 
-fr /home/admin/apache-tomcat-7.0.40/webapps/myapp cp myapp.war /home/admin/apache-tomcat-7.0.40/webapps/myapp.war cd /home/admin/apache-tomcat-7.0.40/bin/./startup.sh

為什麼要export JAVA_HOME環境變數稍後解釋。這裡的的lsof命令根據tomcat監聽的埠來獲取其程序ID然後殺掉,其他命令基本一目瞭然。在部署機器上執行該指令碼確保其能工作,然後提交到原始碼倉庫裡。

3. 建一個Jenkins Job專門做部署

建一個freestyle的Job,然後scm等配置也照常,當然,部署指令碼要在scm倉庫中,然後Jenkins的Build配置像這樣:

這條命令就是通過ssh遠端登陸到部署機器上執行部署部署指令碼deploy.sh,-x引數讓shell列印每一行執行的命令,-s則表示從標準輸入讀取要執行的指令碼,這裡重定向了我們的deploy.sh。(如何設定ssh key實現免密碼登陸請自理)

需要注意的是,這種遠端執行指令碼的方式,屬於非互動式Shell,不會觸發諸如~/.bash_profile之類檔案的載入,這也是我為什麼在Shell指令碼中export JAVA_HOME,這個環境變數本來是在~/.bash_profile中的,當然,你也可以直接source整個~/.bash_profile

最後,你可以通過Jenkins的Pipeline,使得當my-app Build成功之後,自動觸發deploy這個任務,做到自動持續。

如果有多個應用,按照類似的方法建立多個Jenkins Job就可以了,由於Shell指令碼是自己寫的,不論什麼容器都OK,有所放棄的是,由於要重啟容器,相比直接通過容器介面部署,會稍微耗時些,但考慮到穩定性的大幅提高及配置的簡化,我覺得還是值得的。