注:本文來源於《it小熊》html
【 ①Java代碼自動部署-總結簡介】java
代碼部署是每個軟件開發項目組都會有的一個流程,也是從開發環節到發佈功能必不可少的環節。對於Java開發者來講,Java代碼的發佈部署也是常常須要作的一件事,特別是互聯網公司。代碼的發佈上線關係到保證生產環境可以正常啓動及功能是否能正常運行,因此代碼部署在整個項目開發週期仍是佔據很重要的地位。git
因爲本人近期在學習Java代碼自動發佈相關的知識,此係列文章是對這次學習到的知識進行鞏固和總結;同時,也但願可以幫助到和我同樣對此方面知識感興趣的同行們。言很少說,直接進入真題。下面針對這次系列文章作一個簡要的概述。web
高效且簡化代碼的部署發佈shell
一、 CentOS操做系統(可使用虛擬機安裝Linux系統)apache
二、 Maven數組
三、 Gittomcat
四、 Shell腳本bash
五、 Jenkins服務器
階段1:
優勢:部署流程簡單方面,開發完成後開發人員在開發環境便可進行代碼部署上線。
缺點:發佈流程粗糙,代碼部署不夠嚴謹,不建議生產環境使用此方式。
階段2:
優勢:由Git進行項目版本管理,下降了代碼發佈的風險,發佈過程有運維人員進行發佈。
缺點:因爲代碼的發佈由運維人員發佈,需開發人員配合進行代碼發佈部署,與發佈部署不成功,得由開發人員查找問題,增長了部署複雜性。
階段3:
優勢:由Jenkins工具進行代碼的發佈部署,規範了代碼的發佈流程,提供可視工具監聽整個發佈流程等。
缺點:對技術要求更高了,須要瞭解Jenkins工具,會編寫Shell腳本等。
①總結簡介
②使用Maven進行代碼部署
③使用Shell進行代碼部署
④使用Jenkins進行代碼部署
⑤課程總結及心得
【 ②使用Maven進行代碼部署】
在使用maven進行代碼發佈的時候,須要用Maven工具的相關插件將須要部署的項目發佈到指定的服務器的部署目錄中。
在學習此技術時,我用的的是一個秒殺項目的ssm版,你們在學學習此技術的時候能夠用簡單一點的Maven項目進行測試。因本項目是學習如何進行部署項目技術的,本次就針對具體項目進行介紹。
1) 項目自己屬於Maven項目(必要條件)
2) 須要部署的是war包
3) 引入插件
在須要部署的項目的pom,xml文件中引入tomcat插件,在project->build-> plugins節點引入tomcat插件。
<build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <!-- 引入tomcat插件 --> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <!-- <url>http://localhost:8080/manager</url> --> <!-- tomcat6部署管理路徑 --> <url>http://192.168.25.133:8080/manager/text</url> <!-- tomcat7部署管理路徑 --> <!-- tomcat控制檯帳號 --> <username>admin</username> <!-- tomcat的管理員帳號 --> <!-- tomcat控制檯密碼--> <password>admin</password> <!-- 本地運行時指定的端口號 --> <port>8080</port> <path>/seckill-manager</path> <!-- 部署路徑 --> <charset>UTF-8</charset> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> |
4) 執行Maven的redeploy操做
執行的命令:tomcat7:redeploy
在eclipse下配置的命令以下:
一、在將項目發佈到遠程Tomcat時須要啓動遠程Tomcat管理控制檯帳號
開啓tomcat管理控制檯帳號地址爲:Tomcat安裝目錄/conf/tomcat-users.xml文件
在tomcat-users.xml文件中須要配置容許訪問純文本接口權限,以便maven的tomat插件可以經過此方式進行部署項目。
在tomcat-users節點新增role屬性和user屬性,以下:
<role rolename="manager-script" /> <role rolename="manager-gui"/> <user username="admin" password="admin" roles="manager-gui,manager-script"/> |
解釋:給帳號admin配置manager-script及manager-gui權限
Tomcat角色解釋圖:
二、在須要遠程發佈到的目標Tomcat應該是運行狀態,保證Maven的tomcat插件可以訪問到目標Tomcat完成項目的部署。
【③使用Shell進行代碼部署】
在使用Shell腳本進行從新部署項目時,須要掌握Shell腳本的編寫,Shell腳本須要完成如下功能:
一、 將代碼clone到服務器指定目錄
二、 根據pom.xml文件將代碼打包成war包
三、 將war發佈到指定服務器
環境要求:
一、 安裝Maven並配置環境變量
二、 Git客戶端,並配置環境變量
三、 熟悉Shell腳本相關知識
在Linux的指定目錄新建shell腳本,我是在項目的專用tomcat根目錄新建了shell腳本,方便進行tomcat集羣部署操做。腳本內容以下:
#!/bin/bash #shell功能概要:seckill的service提供者構建shell #發佈service提供者的服務器的進程名 serverName="seckill_provider" #獲取發佈service提供者的服務器的進程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" #發佈的tomcat集羣,數組方式存儲 projectServicersPath=(/opt/seckill-tomcat/seckill-tomcat-02 /opt/seckill-tomcat/seckill-tomcat-03) projectName="sekill" #循環強制中止指定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 #判斷執行上面mvn操做的返回值是否爲0 if [ $? -ne 0 ] then echo "構建失敗,請查看代碼問題!" exit 1; fi #循環將項目部署到集羣tomcat中 for projectServicer in ${projectServicersPath[@]} do cp $javaBaseSrc$javaProjectSrc $projectServicer/webapps echo "$projectServicer 代碼發佈成功!" sh $projectServicer/bin/startup.sh if [ $? -ne 0 ] then echo "$projectServicer 啓動失敗" exit 1; else echo "$projectServicer 啓動成功"; fi done echo "啓動 $serverName 成功" |
在編寫Shell腳本時須要知道每句Shell的含義,儘量將全部問題點都能考慮到,好比:
a) 強殺進程問題
進行PID=$(ps -ef | grep $serverName | grep -v grep | awk '{ print $2 }')時,要肯定查詢的只是目標Tomcat的進程pid,防止在後續強制中止時將其餘應用Tomcat誤強行中止,這裏建 議給每個目標Tomcat設置指定的進程名,設置方法爲:
在指定tomcat的bin/ setclasspath.sh文件中找到if [ -z "$_RUNJAVA" ]判斷語句,進行如下設置便可
if [ -z "$_RUNJAVA" ]; then #_RUNJAVA="$JRE_HOME"/bin/java #註釋tomcat默認進程名,設置指定的進程名稱,集羣的時候能夠進行編號01,02,03設置 cp "$JAVA_HOME/bin/java" "$JAVA_HOME/bin/seckill_consumer01" _RUNJAVA="$JRE_HOME/bin/seckill_consumer01" fi |
b) Shell腳本儘量通用
我吸收了如今比較流行的一句話「約定大於配置」及平時所看所想,在編寫Shell腳本時能夠提取可變或多處使用的變量,使整個Shell腳本儘量提煉成通用,以便相似項目部署可使用現有腳本進行更改後使用,減小從新編寫新Shell腳本帶來不可控的問題。
【④使用Jenkins進行代碼部署】
在使用Jenkins進行項目部署時,須要將Jenkins的war包放在服務器的指定位置。Jenkins的war的下載能夠去Jenkins的官網進行下載。
使用Jenkins進行代碼部署時須要的環境支持:
一、安裝Maven並配置環境變量
二、Git客戶端,並配置環境變量
三、熟悉Shell腳本相關知識
四、對Jenkins有必定了解
使用Jenkins進行代碼部署以下:
在jenkins.war目錄執行如下命令操做啓動Jenkins工具。
[xiongshx@localhost jenkins]$ java -jar jenkins.war
Jenkins工具初始化的一些操做能夠百度或者去Jenkins查看能夠參考【https://www.cnblogs.com/cheng95/p/6542036.html】
初始化後須要進行的配置
工具配置
【系統管理】->【全局工具配置】
Jdk配置:
Git配置:
Maven配置:
須要注意的點:
一、填寫源碼倉庫地址
二、構建時操做及自定義shell代碼
Shell代碼以下:
#!/bin/bash #shell功能概要:seckill的Web消費者構建shell #引用的技術有:git、maven #發佈web消費者的服務器的進程名 serverName="seckill_consumer" #獲取發佈web消費者的服務器的進程PID PID=$(ps -ef | grep $serverName | grep -v grep | awk '{ print $2 }') #須要在腳本開始時添加export BUILD_ID=dontKillMe。 #緣由:由於Jenkins執行完當前任務以後須要執行下一個任務,此時Jenkins會直接把tomcat進程殺掉, #所以在腳本中編寫的tomcat啓動命令是不會執行的。 export BUILD_ID=dontKillMe #java代碼本地倉庫地址 javaBaseSrc="/home/xiongshx/.jenkins/workspace/" #項目路徑 javaProjectSrc="seckill/seckill-web/target/seckill-web.war" #發佈的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" #若是上一個命令執行失敗,執行的狀態碼不爲0 if [ $? -ne 0 ] then echo "構建失敗,請查看代碼問題!" exit 1; fi for projectServicer in ${projectServicersPath[@]} do cp $javaBaseSrc$javaProjectSrc $projectServicer/webapps echo "$projectServicer 代碼發佈成功!" /bin/bash $projectServicer/bin/startup.sh if [ $? -ne 0 ] then echo "$projectServicer 啓動失敗" exit 1; else echo "$projectServicer 啓動成功"; fi done echo "啓動 $serverName 成功" |
【當即構建】->【點擊構建的連接】->【控制檯輸出】便可查看整個代碼部署過程當中的信息輸出。
一、Jenkins的war問題
最簡單jenkins.war的啓動方式是在控制檯終端執行命令:java -jar jenkins.war;可是此方法會佔用一個終端窗口,且關閉後Jenkins工具就不能進行訪問,可使用命令進行後臺執行,命令以下:
nohup java -jar jenkins.war --httpPort=9090 > /dev/null 2>&1 &
命令解釋:
nohup 後臺執行操做
--httpPort=9090表示指定佔用9090端口進行訪問
> /dev/null 將日誌輸出到/dev/null
2>&1 & 用來將標準錯誤2重定向到標準輸出1中的此處1前面的&就是爲了讓bash將1解釋成標準輸出而不是文件1。最後一個&,則是讓bash在後臺執行。
另一種更優雅的方式是使用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已是啓動狀態..." 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已經中止..." 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後輸入如下參數:{start|stop|restart} 端口號(不填寫時默認端口9090)" exit 1 esac exit $? |
二、Jenkins中自定義Shell問題
#須要在腳本開始時添加export BUILD_ID=dontKillMe。
#緣由:由於Jenkins執行完當前任務以後須要執行下一個任務,此時Jenkins會直接把tomcat進程殺掉,#所以在腳本中編寫的tomcat啓動命令是不會執行的。
export BUILD_ID=dontKillMe
【⑤課程總結及心得】
學習代碼自動部署的原因一來是因爲在平時開發過程當中常常會遇到代碼部署的環節,但願經過學習此知識後,若是後續有機會針對本身學會的方案進行評估後簡化項目中的項目部署,二來是鞏固本身近期來學習到的一些知識,經過層層迭進來學習代碼的自動部署方案。雖然目前本身的這些流程方案可能還有所欠缺,且尚未通過實際項目考驗,但能學到不少實際的知識也足夠了,好比Maven相關知識、Shell相關知識以及Jenkins相關知識,這些是隻能經過本身動手慢慢去實踐才能獲取到的經驗。若是對代碼部署也感興趣且以爲我寫的東西對你有幫助的同行們,我建議能夠按照個人學習步驟去學習自動構建技術。
此係列文章可能寫的還不夠好,而且不少地方我都進行了一些精簡。其實我但願給你們提供的是一個思路。好比學習整個項目部署的思路,由Maven插件部署到Shell腳本部署再到Jenkins部署項目,其實越到後面,Jenkins只是對一些操做作了集成封裝,可是我以爲若是咱們能從最基本作起,瞭解其中的流程及原理,真正使用Jenkins進行代碼部署時,咱們能知道因此然,那樣我以爲能夠更好的使用Jenkins工具。另外,好比Jenkins.war的啓動,我很天然的想到使用Shell腳本將它的啓動、運行、重啓等命令進行封裝,並把它設置爲開機啓動,我以爲這是一個優雅的方式,之後有相似的狀況時,我也會考慮這麼作。
本文中還有一些沒有說起和沒有實現的內容,我但願以及對此技術感興趣的同行們,均可以發散思惟,把事情盡善盡美,作到最優作好。經過編寫此係列文章,我鞏固了我此類技術的知識的瞭解以及拓展,也但願可以幫助到你們。若是你們在學習此類技術上遇到疑惑或問題,能夠百度查看解決辦法,也能夠給我留言進行探討。
最後,但願全部人在不久的未來都能遇到一個優秀的本身。
================================================