【 ①Java代碼自動部署-總結(jié)簡介】
代碼部署是每一個軟件開發(fā)項目組都會有的一個流程拓哟,也是從開發(fā)環(huán)節(jié)到發(fā)布功能必不可少的環(huán)節(jié)叉钥。對于Java開發(fā)者來說号杠,Java代碼的發(fā)布部署也是經(jīng)常需要做的一件事嗜暴,特別是互聯(lián)網(wǎng)公司胀莹。代碼的發(fā)布上線關(guān)系到保證生產(chǎn)環(huán)境能夠正常啟動及功能是否能正常運行绰更,所以代碼部署在整個項目開發(fā)周期還是占據(jù)很重要的地位瞧挤。
如果想學(xué)習(xí)Java工程化、高性能及分布式儡湾、深入淺出特恬。微服務(wù)、Spring徐钠,MyBatis癌刽,Netty源碼分析的朋友可以加我的Java高級交流:854630135歉秫,群里有阿里大牛直播講解技術(shù)枚驻,以及Java大型互聯(lián)網(wǎng)技術(shù)的視頻免費分享給大家。
由于本人近期在學(xué)習(xí)Java代碼自動發(fā)布相關(guān)的知識,此系列文章是對此次學(xué)習(xí)到的知識進行鞏固和總結(jié)价说;同時别智,也希望能夠幫助到和我一樣對此方面知識感興趣的同行們展蒂。言不多說惑朦,直接進入真題。下面針對此次系列文章做一個簡要的概述矮台。
1乏屯、學(xué)習(xí)代碼自動部署的目的
高效且簡化代碼的部署發(fā)布
2、使用的相關(guān)工具及技術(shù)
1瘦赫、 CentOS操作系統(tǒng)(可以使用虛擬機安裝Linux系統(tǒng))
2辰晕、 Maven
3、 Git
4确虱、 Shell腳本
5含友、 Jenkins
3、學(xué)習(xí)代碼自動發(fā)布相關(guān)技術(shù)的順序
階段1:
優(yōu)點:部署流程簡單方面校辩,開發(fā)完成后開發(fā)人員在開發(fā)環(huán)境即可進行代碼部署上線窘问。
缺點:發(fā)布流程粗糙,代碼部署不夠嚴謹宜咒,不建議生產(chǎn)環(huán)境使用此方式惠赫。
階段2:
優(yōu)點:由Git進行項目版本管理,降低了代碼發(fā)布的風(fēng)險故黑,發(fā)布過程有運維人員進行發(fā)布儿咱。
缺點:由于代碼的發(fā)布由運維人員發(fā)布,需開發(fā)人員配合進行代碼發(fā)布部署场晶,與發(fā)布部署不成功混埠,得由開發(fā)人員查找問題,增加了部署復(fù)雜性峰搪。
階段3:
優(yōu)點:由Jenkins工具進行代碼的發(fā)布部署岔冀,規(guī)范了代碼的發(fā)布流程,提供可視工具監(jiān)聽整個發(fā)布流程等概耻。
缺點:對技術(shù)要求更高了,需要了解Jenkins工具罐呼,會編寫Shell腳本等鞠柄。
4、Java代碼自動部署總結(jié)分為以下系列
①總結(jié)簡介
②使用Maven進行代碼部署
③使用Shell進行代碼部署
④使用Jenkins進行代碼部署
⑤課程總結(jié)及心得
【 ②使用Maven進行代碼部署】
在使用maven進行代碼發(fā)布的時候嫉柴,需要用Maven工具的相關(guān)插件將需要部署的項目發(fā)布到指定的服務(wù)器的部署目錄中厌杜。
在學(xué)習(xí)此技術(shù)時,我用的的是一個秒殺項目的ssm版,大家在學(xué)學(xué)習(xí)此技術(shù)的時候可以用簡單一點的Maven項目進行測試夯尽。因本項目是學(xué)習(xí)如何進行部署項目技術(shù)的瞧壮,本次就針對具體項目進行介紹。
1匙握、 使用Maven進行部署項目要求
1) 項目本身屬于Maven項目(必要條件)
2) 需要部署的是war包
3) 引入插件
在需要部署的項目的pom,xml文件中引入tomcat插件,在project->build-> plugins節(jié)點引入tomcat插件咆槽。
org.apache.tomcat.maven
tomcat7-maven-plugin
http://192.168.25.133:8080/manager/text
admin
admin
8080
/seckill-manager
UTF-8
UTF-8
4) 執(zhí)行Maven的redeploy操作
執(zhí)行的命令:tomcat7:redeploy
在eclipse下配置的命令如下:
2、需要注意的問題點
1圈纺、在將項目發(fā)布到遠程Tomcat時需要啟動遠程Tomcat管理控制臺賬號
開啟tomcat管理控制臺賬號地址為:Tomcat安裝目錄/conf/tomcat-users.xml文件
在tomcat-users.xml文件中需要配置允許訪問純文本接口權(quán)限秦忿,以便maven的tomat插件能夠通過此方式進行部署項目。
在tomcat-users節(jié)點新增role屬性和user屬性蛾娶,如下:
解釋:給賬號admin配置manager-script及manager-gui權(quán)限
Tomcat角色解釋圖:
2灯谣、在需要遠程發(fā)布到的目標Tomcat應(yīng)該是運行狀態(tài),保證Maven的tomcat插件能夠訪問到目標Tomcat完成項目的部署蛔琅。
【③使用Shell進行代碼部署】
在使用Shell腳本進行重新部署項目時胎许,需要掌握Shell腳本的編寫,Shell腳本需要完成以下功能:
1罗售、 將代碼clone到服務(wù)器指定目錄
2辜窑、 根據(jù)pom.xml文件將代碼打包成war包
3、 將war發(fā)布到指定服務(wù)器
環(huán)境要求:
1莽囤、 安裝Maven并配置環(huán)境變量
2谬擦、 Git客戶端,并配置環(huán)境變量
3朽缎、 熟悉Shell腳本相關(guān)知識
1惨远、編寫Shell腳本
在Linux的指定目錄新建shell腳本,我是在項目的專用tomcat根目錄新建了shell腳本,方便進行tomcat集群部署操作话肖。腳本內(nèi)容如下:
#!/bin/bash
#shell功能概要:seckill的service提供者構(gòu)建shell
#發(fā)布service提供者的服務(wù)器的進程名
serverName="seckill_provider"
#獲取發(fā)布service提供者的服務(wù)器的進程PID
PID=$(ps -ef | grep $serverName | grep -v grep | awk '{ print $2 }')
#java代碼本地倉庫地址
javaBaseSrc="/opt/java_project_src/"
#項目路徑
javaProjectSrc="sekill/seckill-manager/seckill-service/target/seckill-service.war"
#發(fā)布的tomcat集群北秽,數(shù)組方式存儲
projectServicersPath=(/opt/seckill-tomcat/seckill-tomcat-02 /opt/seckill-tomcat/seckill-tomcat-03)
projectName="sekill"
#循環(huán)強制停止指定tomcat
for var in ${PID};
do
echo "準備強制停止PID:$var"
kill -9 $var
done
echo "kill $serverName sucess"
#切換到git本地倉庫目錄
cd $javaBaseSrc
#刪除倉庫庫中代碼
rm -rf $projectName
echo "從/opt/java_project_src倉庫中刪除項目$projectName成功"
#從遠程倉庫下載代碼,因涉及到賬戶信息最筒,此處更改為描述信息
git clone 遠程git倉庫項目URL
cd $javaBaseSrc/sekill/seckill-manager
#安裝項目并跳過測試
mvn -Dmaven.test.skip=true clean install
#判斷執(zhí)行上面mvn操作的返回值是否為0
if [ $? -ne 0 ]
then
echo "構(gòu)建失敗贺氓,請查看代碼問題!"
exit 1;
fi
#循環(huán)將項目部署到集群tomcat中
for projectServicer in ${projectServicersPath[@]}
do
cp $javaBaseSrc$javaProjectSrc $projectServicer/webapps
echo "$projectServicer 代碼發(fā)布成功!"
sh $projectServicer/bin/startup.sh
if [ $? -ne 0 ]
then
echo "$projectServicer 啟動失敗"
exit 1;
else
echo "$projectServicer 啟動成功";
fi
done
echo "啟動 $serverName 成功"
2床蜘、需要注意的問題點
在編寫Shell腳本時需要知道每句Shell的含義辙培,盡可能將所有問題點都能考慮到,比如:
a) 強殺進程問題
進行PID=$(ps -ef | grep $serverName | grep -v grep | awk '{ print $2 }')時邢锯,要確定查詢的只是目標Tomcat的進程pid扬蕊,防止在后續(xù)強制停止時將其他應(yīng)用Tomcat誤強行停止,這里建 議給每一個目標Tomcat設(shè)置指定的進程名丹擎,設(shè)置方法為:
在指定tomcat的bin/ setclasspath.sh文件中找到if [ -z "$_RUNJAVA" ]判斷語句尾抑,進行以下設(shè)置即可
if [ -z "$_RUNJAVA" ]; then
#_RUNJAVA="$JRE_HOME"/bin/java
#注釋tomcat默認進程名歇父,設(shè)置指定的進程名稱,集群的時候可以進行編號01,02,03設(shè)置
cp "$JAVA_HOME/bin/java" "$JAVA_HOME/bin/seckill_consumer01"
_RUNJAVA="$JRE_HOME/bin/seckill_consumer01"
fi
b) Shell腳本盡可能通用
我吸取了現(xiàn)在比較流行的一句話“約定大于配置”及平時所看所想再愈,在編寫Shell腳本時可以提取可變或多處使用的變量榜苫,使整個Shell腳本盡可能提煉成通用,以便類似項目部署可以使用現(xiàn)有腳本進行更改后使用翎冲,減少重新編寫新Shell腳本帶來不可控的問題垂睬。
【④使用Jenkins進行代碼部署】
如果想學(xué)習(xí)Java工程化、高性能及分布式府适、深入淺出羔飞。微服務(wù)、Spring檐春,MyBatis逻淌,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群里有阿里大牛直播講解技術(shù)疟暖,以及Java大型互聯(lián)網(wǎng)技術(shù)的視頻免費分享給大家卡儒。
在使用Jenkins進行項目部署時,需要將Jenkins的war包放在服務(wù)器的指定位置俐巴。Jenkins的war的下載可以去Jenkins的官網(wǎng)進行下載骨望。
使用Jenkins進行代碼部署時需要的環(huán)境支持:
1、安裝Maven并配置環(huán)境變量
2欣舵、Git客戶端擎鸠,并配置環(huán)境變量
3、熟悉Shell腳本相關(guān)知識
4缘圈、對Jenkins有一定了解
使用Jenkins進行代碼部署如下:
1劣光、 啟動Jenkins工具
在jenkins.war目錄執(zhí)行以下命令操作啟動Jenkins工具。
[xiongshx@localhost jenkins]$ java -jar jenkins.war
Jenkins工具初始化的一些操作可以百度或者去Jenkins查看可以參考【https://www.cnblogs.com/cheng95/p/6542036.html】
初始化后需要進行的配置
工具配置
【系統(tǒng)管理】->【全局工具配置】
Jdk配置:
Git配置:
Maven配置:
2糟把、 新建任務(wù)
需要注意的點:
1绢涡、填寫源碼倉庫地址
2、構(gòu)建時操作及自定義shell代碼
Shell代碼如下:
#!/bin/bash
#shell功能概要:seckill的Web消費者構(gòu)建shell
#引用的技術(shù)有:git遣疯、maven
#發(fā)布web消費者的服務(wù)器的進程名
serverName="seckill_consumer"
#獲取發(fā)布web消費者的服務(wù)器的進程PID
PID=$(ps -ef | grep $serverName | grep -v grep | awk '{ print $2 }')
#需要在腳本開始時添加export BUILD_ID=dontKillMe雄可。
#原因:因為Jenkins執(zhí)行完當前任務(wù)之后需要執(zhí)行下一個任務(wù),此時Jenkins會直接把tomcat進程殺掉,
#因此在腳本中編寫的tomcat啟動命令是不會執(zhí)行的缠犀。
export BUILD_ID=dontKillMe
#java代碼本地倉庫地址
javaBaseSrc="/home/xiongshx/.jenkins/workspace/"
#項目路徑
javaProjectSrc="seckill/seckill-web/target/seckill-web.war"
#發(fā)布的tomcat
projectServicersPath=(/opt/seckill-tomcat/seckill-tomcat-01)
projectName="sekill"
for var in ${PID};
do
echo "準備強制停止PID:$var"
kill -9 $var
done
echo "kill $serverName sucess"
#如果上一個命令執(zhí)行失敗数苫,執(zhí)行的狀態(tài)碼不為0
if [ $? -ne 0 ]
then
echo "構(gòu)建失敗,請查看代碼問題辨液!"
exit 1;
fi
for projectServicer in ${projectServicersPath[@]}
do
cp $javaBaseSrc$javaProjectSrc $projectServicer/webapps
echo "$projectServicer 代碼發(fā)布成功!"
/bin/bash $projectServicer/bin/startup.sh
if [ $? -ne 0 ]
then
echo "$projectServicer 啟動失敗"
exit 1;
else
echo "$projectServicer 啟動成功";
fi
done
echo "啟動 $serverName 成功"
3文判、 啟動項目
【立即構(gòu)建】->【點擊構(gòu)建的鏈接】->【控制臺輸出】即可查看整個代碼部署過程中的信息輸出。
4室梅、需要注意的問題點:
1、Jenkins的war問題
最簡單jenkins.war的啟動方式是在控制臺終端執(zhí)行命令:java -jar jenkins.war;但是此方法會占用一個終端窗口亡鼠,且關(guān)閉后Jenkins工具就不能進行訪問赏殃,可以使用命令進行后臺執(zhí)行,命令如下:
nohup java -jar jenkins.war --httpPort=9090 > /dev/null 2>&1 &
命令解釋:
nohup 后臺執(zhí)行操作
--httpPort=9090表示指定占用9090端口進行訪問
> /dev/null 將日志輸出到/dev/null
2>&1 & 用來將標準錯誤2重定向到標準輸出1中的此處1前面的&就是為了讓bash將1解釋成標準輸出而不是文件1间涵。最后一個&仁热,則是讓bash在后臺執(zhí)行。
如果想學(xué)習(xí)Java工程化勾哩、高性能及分布式抗蠢、深入淺出。微服務(wù)思劳、Spring迅矛,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:854630135潜叛,群里有阿里大牛直播講解技術(shù)秽褒,以及Java大型互聯(lián)網(wǎng)技術(shù)的視頻免費分享給大家。
另外一種更優(yōu)雅的方式是使用Shell腳本控制Jenkins工具的啟動威兜、停止销斟、重啟等操作。
樣例如下:
#!/bin/bash
#功能描述:用于Jenkins運行椒舵,停止蚂踊,重啟
#將此腳本放在jenkins.war同級目錄
#獲取Jenkins的進程id
pid=$(ps -ef| grep "jenkins.war" | grep -v grep | awk '{print $2}')
#jenkins默認端口號
jekinsDefaultPort=9090
#如果用戶有自定義端口號,則使用用戶自定義的端口號啟動jenkins
if [ x$2 != x ]
then
jekinsDefaultPort=$2
fi
#啟動jenkins
start(){
if [ x$pid != x ]
then
echo "jenkins已經(jīng)是啟動狀態(tài)..."
exit 1
fi
nohup java -jar jenkins.war --httpPort=$jekinsDefaultPort > /dev/null 2>&1 &
echo "jenkins啟動成功笔宿,端口號為:$jekinsDefaultPort..."
return $?
}
stop(){
echo "準備停止jenkins..."
if [ x$pid != x ]
then
kill -9 $pid
echo "jenkins已經(jīng)停止..."
exit $?
else
echo "jenkins的進程id不存在犁钟,無法進行停止操作..."
exit 1
fi
}
# 重新加載Jenkins
restart() {
stop
start
echo "jenkins重新加載成功,jekins端口號為:$jekinsDefaultPort..."
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo $"提示: 請在jenkins后輸入以下參數(shù):{start|stop|restart} 端口號(不填寫時默認端口9090)"
exit 1
esac
exit $?
2措伐、Jenkins中自定義Shell問題
#需要在腳本開始時添加export BUILD_ID=dontKillMe特纤。
#原因:因為Jenkins執(zhí)行完當前任務(wù)之后需要執(zhí)行下一個任務(wù),此時Jenkins會直接把tomcat進程殺掉,#因此在腳本中編寫的tomcat啟動命令是不會執(zhí)行的侥加。
export BUILD_ID=dontKillMe
【⑤課程總結(jié)及心得】
學(xué)習(xí)代碼自動部署的緣由一來是由于在平時開發(fā)過程中經(jīng)常會遇到代碼部署的環(huán)節(jié)捧存,希望通過學(xué)習(xí)此知識后,如果后續(xù)有機會針對自己學(xué)會的方案進行評估后簡化項目中的項目部署担败,二來是鞏固自己近期來學(xué)習(xí)到的一些知識昔穴,通過層層迭進來學(xué)習(xí)代碼的自動部署方案。雖然目前自己的這些流程方案可能還有所欠缺提前,且還沒有經(jīng)過實際項目考驗吗货,但能學(xué)到很多實際的知識也足夠了,比如Maven相關(guān)知識狈网、Shell相關(guān)知識以及Jenkins相關(guān)知識宙搬,這些是只能通過自己動手慢慢去實踐才能獲取到的經(jīng)驗笨腥。如果對代碼部署也感興趣且覺得我寫的東西對你有幫助的同行們,我建議可以按照我的學(xué)習(xí)步驟去學(xué)習(xí)自動構(gòu)建技術(shù)勇垛。
此系列文章可能寫的還不夠好脖母,并且很多地方我都進行了一些精簡。其實我希望給大家提供的是一個思路闲孤。比如學(xué)習(xí)整個項目部署的思路谆级,由Maven插件部署到Shell腳本部署再到Jenkins部署項目,其實越到后面讼积,Jenkins只是對一些操作做了集成封裝肥照,但是我覺得如果我們能從最基本做起,了解其中的流程及原理勤众,真正使用Jenkins進行代碼部署時舆绎,我們能知道所以然,那樣我覺得可以更好的使用Jenkins工具决摧。另外亿蒸,比如Jenkins.war的啟動,我很自然的想到使用Shell腳本將它的啟動掌桩、運行边锁、重啟等命令進行封裝,并把它設(shè)置為開機啟動波岛,我覺得這是一個優(yōu)雅的方式茅坛,以后有類似的情況時,我也會考慮這么做则拷。
本文中還有一些沒有提及和沒有實現(xiàn)的內(nèi)容贡蓖,我希望以及對此技術(shù)感興趣的同行們,都可以發(fā)散思維煌茬,把事情盡善盡美斥铺,做到最優(yōu)做好。通過編寫此系列文章坛善,我鞏固了我此類技術(shù)的知識的了解以及拓展晾蜘,也希望能夠幫助到大家。如果大家在學(xué)習(xí)此類技術(shù)上遇到疑惑或問題眠屎,可以百度查看解決辦法剔交,也可以給我留言進行探討。
如果想學(xué)習(xí)Java工程化改衩、高性能及分布式岖常、深入淺出。微服務(wù)葫督、Spring竭鞍,MyBatis板惑,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群里有阿里大牛直播講解技術(shù)笼蛛,以及Java大型互聯(lián)網(wǎng)技術(shù)的視頻免費分享給大家洒放。
最后,希望所有人在不久的將來都能遇到一個優(yōu)秀的自己滨砍。