Jenkins加Shell实现最简单的持续部署
原網址:http://ju.outofmemory.cn/entry/29263
大量的有關持續集成的書籍與文檔中,基本都提到了持續部署這個步驟,然而具體怎么實現,并沒有通行的做法,對于典型的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/bash export 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,有所放棄的是,由于要重啟容器,相比直接通過容器接口部署,會稍微耗時些,但考慮到穩定性的大幅提高及配置的簡化,我覺得還是值得的。
轉載于:https://www.cnblogs.com/yunkong/articles/4413673.html
總結
以上是生活随笔為你收集整理的Jenkins加Shell实现最简单的持续部署的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nagios/Postfix 转发警报邮
- 下一篇: Spring – ${} is not