Java代碼自動部署

来源:https://www.cnblogs.com/xiongshx/archive/2018/08/09/9450680.html
-Advertisement-
Play Games

Java代碼自動部署 【 ①Java代碼自動部署-總結簡介】 代碼部署是每一個軟體開發項目組都會有的一個流程,也是從開發環節到發佈功能必不可少的環節。對於Java開發者來說,Java代碼的發佈部署也是經常需要做的一件事,特別是互聯網公司。代碼的發佈上線關係到保證生產環境能夠正常啟動及功能是否能正常運 ...


Java代碼自動部署

【 ①Java代碼自動部署-總結簡介】

       代碼部署是每一個軟體開發項目組都會有的一個流程,也是從開發環節到發佈功能必不可少的環節。對於Java開發者來說,Java代碼的發佈部署也是經常需要做的一件事,特別是互聯網公司。代碼的發佈上線關係到保證生產環境能夠正常啟動及功能是否能正常運行,所以代碼部署在整個項目開發周期還是占據很重要的地位。

       由於本人近期在學習Java代碼自動發佈相關的知識,此系列文章是對此次學習到的知識進行鞏固和總結;同時,也希望能夠幫助到和我一樣對此方面知識感興趣的同行們。言不多說,直接進入真題。下麵針對此次系列文章做一個簡要的概述。

1、學習代碼自動部署的目的

       高效且簡化代碼的部署發佈

2、使用的相關工具及技術

       1、 CentOS操作系統(可以使用虛擬機安裝Linux系統)

       2、 Maven

       3、 Git

       4、 Shell腳本

       5、 Jenkins

3、學習代碼自動發佈相關技術的順序

    階段1:

    優點:部署流程簡單方面,開發完成後開發人員在開發環境即可進行代碼部署上線。

    缺點:發佈流程粗糙,代碼部署不夠嚴謹,不建議生產環境使用此方式。

    階段2:

    優點:由Git進行項目版本管理,降低了代碼發佈的風險,發佈過程有運維人員進行發佈。

    缺點:由於代碼的發佈由運維人員發佈,需開發人員配合進行代碼發佈部署,與發佈部署不成功,得由開發人員查找問題,增加了部署複雜性。

    階段3:

    優點:由Jenkins工具進行代碼的發佈部署,規範了代碼的發佈流程,提供可視工具監聽整個發佈流程等。

    缺點:對技術要求更高了,需要瞭解Jenkins工具,會編寫Shell腳本等。

4、Java代碼自動部署總結分為以下系列

        ①總結簡介

        ②使用Maven進行代碼部署

        ③使用Shell進行代碼部署

        ④使用Jenkins進行代碼部署

        ⑤課程總結及心得

【 ②使用Maven進行代碼部署】

       在使用maven進行代碼發佈的時候,需要用Maven工具的相關插件將需要部署的項目發佈到指定的伺服器的部署目錄中。

在學習此技術時,我用的的是一個秒殺項目的ssm版,大家在學學習此技術的時候可以用簡單一點的Maven項目進行測試。因本項目是學習如何進行部署項目技術的,本次就針對具體項目進行介紹。

1、 使用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下配置的命令如下:

2、需要註意的問題點

  1、在將項目發佈到遠程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角色解釋圖:

  2、在需要遠程發佈到的目標Tomcat應該是運行狀態,保證Maven的tomcat插件能夠訪問到目標Tomcat完成項目的部署。

 

【③使用Shell進行代碼部署】

  在使用Shell腳本進行重新部署項目時,需要掌握Shell腳本的編寫,Shell腳本需要完成以下功能:

  1、 將代碼clone到伺服器指定目錄

  2、 根據pom.xml文件將代碼打包成war包

  3、 將war發佈到指定伺服器

   

  環境要求:

  1、 安裝Maven並配置環境變數

  2、 Git客戶端,並配置環境變數

  3、 熟悉Shell腳本相關知識

  1、編寫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 成功"

  2、需要註意的問題點

  在編寫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進行代碼部署時需要的環境支持:

  1、安裝Maven並配置環境變數

  2、Git客戶端,並配置環境變數

  3、熟悉Shell腳本相關知識

  4、對Jenkins有一定瞭解

 

  使用Jenkins進行代碼部署如下:

  1、 啟動Jenkins工具

  在jenkins.war目錄執行以下命令操作啟動Jenkins工具。

  [xiongshx@localhost jenkins]$ java -jar jenkins.war

    Jenkins工具初始化的一些操作可以百度或者去Jenkins查看可以參考【https://www.cnblogs.com/cheng95/p/6542036.html】

  初始化後需要進行的配置

  工具配置

  【系統管理】->【全局工具配置】

   Jdk配置:

 

   Git配置:

   Maven配置:

 

  2、 新建任務

 

  需要註意的點:

  1、填寫源碼倉庫地址

 

    2、構建時操作及自定義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 成功"

  3、 啟動項目

  【立即構建】->【點擊構建的鏈接】->【控制台輸出】即可查看整個代碼部署過程中的信息輸出。

 

 4、需要註意的問題點:

   1、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 $?

  2、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腳本將它的啟動、運行、重啟等命令進行封裝,並把它設置為開機啟動,我覺得這是一個優雅的方式,以後有類似的情況時,我也會考慮這麼做。

  本文中還有一些沒有提及和沒有實現的內容,我希望以及對此技術感興趣的同行們,都可以發散思維,把事情盡善盡美,做到最優做好。通過編寫此系列文章,我鞏固了我此類技術的知識的瞭解以及拓展,也希望能夠幫助到大家。如果大家在學習此類技術上遇到疑惑或問題,可以百度查看解決辦法,也可以給我留言進行探討。

最後,希望所有人在不久的將來都能遇到一個優秀的自己。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。 示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子數組 [4,-1,2,1] 的和最大,為 6。 class Solution: def maxSubAr ...
  • 前言 SqlSession是Mybatis最重要的構建之一,可以簡單的認為Mybatis一系列的配置目的是生成類似 JDBC生成的Connection對象的SqlSession對象,這樣才能與資料庫開啟“溝通”,通過SqlSession可以實現增刪改查(當然現在更加推薦是使用Mapper介面形式), ...
  • 前面寫過關於傅里葉演算法的應用例子。 《基於傅里葉變換的音頻重採樣演算法 (附完整c代碼)》 當然也就是舉個例子,主要是學習傅里葉變換。 這個重採樣思路還有點瑕疵, 稍微改一下,就可以支持多通道,以及提升性能。 當然思路很簡單,就是切分,合併。 留個作業哈。 本文不講過多的演算法思路,傅里葉變換的各種變種 ...
  • 註: Nginx版本必須大於等於1.9,linux我使用的是7.0版本,記得關閉防火牆 開始正文: 這裡只提一下兩個比較會出錯的配置,consul,upsync,PCRE庫,SSL庫,ZLIB庫的配置網上很多不一一詳解(我是在/usr/local中配置的) Nginx的配置: cd /usr/loc ...
  • 先來看看這個關鍵字是什麼意思:volatile [ˈvɒlətaɪl] adj. 易變的,不穩定的; 從翻譯上來看,volatile表示這個關鍵字是極易發生改變的。volatile是java語言中,最輕量級的併發同步機制。這個關鍵字有如下兩個作用:1、任何對volatile變數的修改,java中的其 ...
  • 資料庫的配置 1 django預設支持sqlite,mysql, oracle,postgresql資料庫。 <1> sqlite django預設使用sqlite的資料庫,預設自帶sqlite的資料庫驅動 , 引擎名稱:django.db.backends.sqlite3 <2> mysql 引擎 ...
  • RocketMQ是一款分散式、隊列模型的消息中間件,具有以下特點: 能夠保證嚴格的消息順序 提供豐富的消息拉取模式 高效的訂閱者水平擴展能力 實時的消息訂閱機制 億級消息堆積能力 RocketMQ網路部署特 (1)NameServer是一個幾乎無狀態的節點,可集群部署,節點之間無任何信息同步 (2) ...
  • 註:本面試題來源於網路,轉載自http://www.cnblogs.com/goodhacker/p/3366618.html。 1. (1)python下多線程的限制以及多進程中傳遞參數的方式 python多線程有個全局解釋器鎖(global interpreter lock),這個鎖的意思是任一 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...