1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Spring Boot 項目打包 + Shell 腳本部署實踐,太有用了!

        共 19451字,需瀏覽 39分鐘

         ·

        2021-04-19 14:27

        作者:神牛003

        來源:cnblogs.com/wangrudong003/p/10502043.html

        本篇和大家分享的是 Spring Boot 打包并結合 Shell 腳本命令部署,重點在分享一個shell 程序啟動工具,希望能便利工作;

        • profiles指定不同環(huán)境的配置
        • maven-assembly-plugin打發(fā)布壓縮包
        • 分享shenniu_publish.sh程序啟動工具
        • linux上使用shenniu_publish.sh啟動程序


        profiles指定不同環(huán)境的配置

        通常一套程序分為了很多個部署環(huán)境:開發(fā),測試,uat,線上 等,我們要想對這些環(huán)境區(qū)分配置文件,可以通過兩種方式:

        • 通過application.yml中編碼指定 profile.active=uat 方式指定
        • 通過mvn中profiles來區(qū)分不同環(huán)境對應的配置文件夾,人工可以手動在idea勾選生成不同環(huán)境的包(推薦)

        這里我們要講的是第二種,首先在mvn中配置如下內容:

        1 <profiles>
         2 <profile>
         3 <id>node</id>
         4 <properties>
         5 <!--傳遞給腳本的參數值-->
         6 <activeProfile>node</activeProfile>
         7 <package-name>${scripts_packageName}</package-name>
         8 <boot-main>${scripts_bootMain}</boot-main>
         9 </properties>
        10 <activation>
        11 <activeByDefault>true</activeByDefault>
        12 </activation>
        13 </profile>
        14 <profile>
        15 <id>node1</id>
        16 <properties>
        17 <activeProfile>node1</activeProfile>
        18 <package-name>${scripts_packageName}</package-name>
        19 <boot-main>${scripts_bootMain}</boot-main>
        20 </properties>
        21 </profile>
        22 <profile>
        23 <id>node2</id>
        24 <properties>
        25 <activeProfile>node2</activeProfile>
        26 <package-name>${scripts_packageName}</package-name>
        27 <boot-main>${scripts_bootMain}</boot-main>
        28 </properties>
        29 </profile>
        30 </profiles>

        節(jié)點粗解:

        id:用來指定不同環(huán)境配置文件所在的目錄,如下我這里:

        img

        properties:該節(jié)點中的節(jié)點是可作為參數傳遞給其他配置文件,如我這里的package-name節(jié)點值就可以在另外的assembly.xml或者shell腳本文件中通過${package-name}獲取到,如下:

        img

        activeByDefault:指定默認環(huán)境配置文件夾

        maven-assembly-plugin打發(fā)布壓縮包

        對于springboot程序打包,可以分為jar和war,這里是jar包;有場景是咋們配置文件或者第三方等依賴包不想放到工程jar中,并且把這些文件壓縮成一個zip包,方便上傳到linux;此時通過maven-assembly-plugin和maven-jar-plugin就可以做到,mvn的配置如:

        1 <plugin>
         2 <groupId>org.apache.maven.plugins</groupId>
         3 <artifactId>maven-jar-plugin</artifactId>
         4 <version>2.6</version>
         5 <configuration>
         6 <archive>
         7 <addMavenDescriptor>false</addMavenDescriptor>
         8 <manifest>
         9 <addClasspath>true</addClasspath>
        10 <classpathPrefix>lib/</classpathPrefix>
        11 <mainClass>${scripts_bootMain}</mainClass>
        12 </manifest>
        13 </archive>
        14 <!--打包排除項-->
        15 <excludes>
        16 <exclude>**/*.yml</exclude>
        17 <exclude>**/*.properties</exclude>
        18 <exclude>**/*.xml</exclude>
        19 <exclude>**/*.sh</exclude>
        20 </excludes>
        21 </configuration>
        22 <executions>
        23 <execution>
        24 <id>make-a-jar</id>
        25 <phase>compile</phase>
        26 <goals>
        27 <goal>jar</goal>
        28 </goals>
        29 </execution>
        30 </executions>
        31 </plugin>
        32
        33 <plugin>
        34 <groupId>org.apache.maven.plugins</groupId>
        35 <artifactId>maven-assembly-plugin</artifactId>
        36 <version>2.4</version>
        37 <!-- The configuration of the plugin -->
        38 <configuration>
        39 <!-- Specifies the configuration file of the assembly plugin -->
        40 <descriptors>
        41 <descriptor>${project.basedir}/src/main/assembly/assembly.xml</descriptor>
        42 </descriptors>
        43 </configuration>
        44 <executions>
        45 <execution>
        46 <id>make-assembly</id>
        47 <phase>package</phase>
        48 <goals>
        49 <goal>single</goal>
        50 </goals>
        51 </execution>
        52 </executions>
        53 </plugin>

        值得注意的地方如下幾點:

        • mainClass節(jié)點:用來指定啟動main函數入口類路徑,如這里的:com.sm.EurekaServerApplication
        • excludes節(jié)點:排除主jar包中配置等一些列后綴文件,因為我們要包這些配置文件放到主包外面
        • descriptor節(jié)點:用來指定assembly插件對應的assembly.xml配置文件

        有了上面mvn配置,我們還需要assembly.xml的配置,這里提取了結合shell腳本發(fā)布程序的配置:

        <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd
        http://maven.apache.org/ASSEMBLY/2.0.0 "
        >
            <id>${activeProfile}</id>
            <!--打包成一個用于發(fā)布的zip文件-->
            <formats>
                <format>zip</format>
            </formats>
            <!--true:zip中生成一級目錄(此處屏蔽,配合腳本需要profiles后綴)-->
            <includeBaseDirectory>false</includeBaseDirectory>
            <dependencySets>
                <dependencySet>
                    <!--打包進zip文件的lib目錄-->
                    <useProjectArtifact>false</useProjectArtifact>
                    <outputDirectory>${package-name}-${activeProfile}/lib</outputDirectory>
                    <unpack>false</unpack>
                </dependencySet>
            </dependencySets>

            <fileSets>
                <!-- 配置文件打包進zip文件的conf目錄 -->
                <fileSet>
                    <directory>${project.basedir}/src/main/profiles/${activeProfile}</directory>
                    <outputDirectory>${package-name}-${activeProfile}/conf</outputDirectory>
                    <includes>
                        <include>**/*</include>
                        <!--<include>*.xml</include>-->
                        <!--<include>*.properties</include>-->
                        <!--<include>*.yml</include>-->
                    </includes>
                </fileSet>

                <!--啟動腳本打包進zip文件-->
                <fileSet>
                    <directory>${project.basedir}/src/main/scripts</directory>
                    <outputDirectory></outputDirectory>
                    <includes>
                        <include>**/*</include>
                    </includes>
                    <!-- 文件文件權限為777 -->
                    <fileMode>777</fileMode>
                    <!-- 目錄權限為777 -->
                    <directoryMode>777</directoryMode>
                    <!--腳本中參數變量為pom中的值 關鍵-->
                    <filtered>true</filtered>
                </fileSet>

                <!-- 項目編譯出來的jar打包進zip文件 -->
                <fileSet>
                    <directory>${project.build.directory}</directory>
                    <outputDirectory>${package-name}-${activeProfile}/</outputDirectory>
                    <includes>
                        <include>*.jar</include>
                    </includes>
                </fileSet>
            </fileSets>
        </assembly>

        重點節(jié)點介紹:

        • formats節(jié)點:把配置文件和jar包等壓縮成什么文件格式,這里可以有:zip,tar等
        • fileMode節(jié)點:指定scripts目錄下腳本文件(這里是:shenniu_publish.sh)在linux上文件權限為777
        • filtered節(jié)點:腳本中參數變量為pom的profiles中properties的值(該配置,是把mvn中屬性值映射生成到sh文件中,如:${package-name})

        完成上面配置后,此時我們可以通過idea上勾選切換不同環(huán)境來打zip包,如圖:

        img

        分享shenniu_publish.sh程序啟動工具

        上面步驟完成了zip格式的發(fā)布包,我們再分享下啟動程序的shell腳本,該腳本具有的功能如:

        • 解壓zip+啟動jar包
        • 啟動jar包
        • 停止對應jar運行
        • 重啟jar程序

        目前該shell中封裝了兩種啟動jar命令的方式:

        • java -cp
        • java -jar

        如圖命令格式:

        img

        來看全部的shell代碼:

        #!/usr/bin/env bash
        #可變參數變量
        languageType="javac" #支持 java,javac,netcore 發(fā)布
        #參數值由pom文件傳遞
        baseZipName="${package-name}-${activeProfile}" #壓縮包名稱 publish-test.zip的publish
        packageName="${package-name}" #命令啟動包名 xx.jar的xx
        mainclass="${boot-main}" #java -cp啟動時,指定main入口類;命令:java -cp conf;lib\*.jar;${packageName}.jar ${mainclass}

        #例子
        # baseZipName="publish-test" #壓縮包名稱 publish-test.zip的publish
        # packageName="publish" #命令啟動包名 publish.jar的xx

        #固定變量
        basePath=$(cd `dirname $0`/; pwd)
        baseZipPath="${basePath}/${baseZipName}.zip"  #壓縮包路徑
        baseDirPath="${basePath}" #解壓部署磁盤路徑
        pid= #進程pid

        #解壓
        function shenniu_unzip()
        {
            echo "解壓---------------------------------------------"
            echo "壓縮包路徑:${baseZipPath}"
            if [ ! `find ${baseZipPath}` ]
            then
                echo "不存在壓縮包:${baseZipPath}"
            else
                echo "解壓磁盤路徑:${baseDirPath}/${baseZipName}"
                echo "開始解壓..."

                #解壓命令
                unzip -od ${baseDirPath}/${baseZipName} ${baseZipPath}

                #設置執(zhí)行權限
                chmod +x ${baseDirPath}/${baseZipName}/${packageName}

                echo "解壓完成。"
            fi
        }

        #檢測pid
        function getPid()
        {
            echo "檢測狀態(tài)---------------------------------------------"
            pid=`ps -ef | grep -n ${packageName} | grep -v grep | awk '{print $2}'`
            if [ ${pid} ]
            then
                echo "運行pid:${pid}"
            else
                echo "未運行"
            fi
        }

        #啟動程序
        function start()
        {
            #啟動前,先停止之前的
            stop
            if [ ${pid} ]
            then
                echo "停止程序失敗,無法啟動"
            else
                echo "啟動程序---------------------------------------------"

                #選擇語言類型
                read -p "輸入程序類型(java,javac,netcore),下一步按回車鍵(默認:${languageType}):" read_languageType
                if [ ${read_languageType} ]
                then
                    languageType=${read_languageType}
                fi
                echo "選擇程序類型:${languageType}"

                #進入運行包目錄
                cd ${baseDirPath}/${baseZipName}

                #分類啟動
                if [ "${languageType}" == "javac" ]
                then
                    if [ ${mainclass} ]
                    then
                        nohup java -cp conf:lib\*.jar:${packageName}.jar ${mainclass} >${baseDirPath}/${packageName}.out 2>&1 &
                       #nohup java -cp conf:lib\*.jar:${packageName}.jar ${mainclass} >/dev/null 2>&1 &
                    fi
                elif [ "${languageType}" == "java" ]
                then
                    nohup java -jar ${baseDirPath}/${baseZipName}/${packageName}.jar >/dev/null 2>&1 &
                    # java -jar ${baseDirPath}/${baseZipName}/${packageName}.jar
                elif [ "${languageType}" == "netcore" ]
                then
                    #nohup dotnet run ${baseDirPath}/${baseZipName}/${packageName} >/dev/null 2>&1 &
                    nohup ${baseDirPath}/${baseZipName}/${packageName} >/dev/null 2>&1 &
                fi

                #查詢是否有啟動進程
                getPid
                if [ ${pid} ]
                then
                    echo "已啟動"
                    #nohup日志
                    tail -n 50 -f ${baseDirPath}/${packageName}.out
                else
                    echo "啟動失敗"
                fi
            fi
        }

        #停止程序
        function stop()
        {
            getPid
            if [ ${pid} ]
            then
                echo "停止程序---------------------------------------------"
                kill -9 ${pid}

                getPid
                if [ ${pid} ]
                then
                    #stop
                    echo "停止失敗"
                else
                    echo "停止成功"
                fi
            fi
        }

        #啟動時帶參數,根據參數執(zhí)行
        if [ ${#} -ge 1 ]
        then
            case ${1} in
                "start")
                    start
                ;;
                "restart")
                    start
                ;;
                "stop")
                    stop
                ;;
                "unzip")
                    #執(zhí)行解壓
                    shenniu_unzip
                    #執(zhí)行啟動
                    start
                ;;
                *)
                    echo "${1}無任何操作"
                ;;
            esac
        else
            echo "
            command如下命令:
            unzip:解壓并啟動
            start:啟動
            stop:停止進程
            restart:重啟

            示例命令如:./shenniu_publish start
            "

        fi

        正如上面小節(jié)說的,shell中的參數 package-name,activeProfile,boot-main 都是由mvn中profiles的properties中提供,是可變的參數,腳本代碼本身不需要人工去修改,只需要變的是mvn的參數即可;其實在我們生成zip包的時候,shell中的參數就被替換了,可以看zip中shell文件內容如:

        img

        把生成的zip上傳到linux上,通過命令解壓:

        1 unzip -od eureka-server-0.0.1-node eureka-server-0.0.1-node.zip

        其實shell腳本中包含有解壓命令,但是我在打包時放在了zip中,所以只能通過手動解壓了,當然可以調整;此時進入加壓目錄如此:

        img

        注:這里第一次執(zhí)行./shenniu_publish.sh腳本時候,提示了錯誤信息;是由于我是在windows上編輯的這個腳本,其空格等和linux上不一樣,所以運行會有問題,要解決可以使用vim命令在linux把該文件轉成linux格式,如下命令:

        1 vim shenniu_publish.sh
        set ff=unix
        3 :wq

        執(zhí)行完后,再來運行腳本./shenniu_publish.sh,此時有如下提示:

        img

        此刻我們文件是解壓狀態(tài),因此只需要start命令啟動程序即可:

        img

        到這里shenniu_publish.sh腳本使用就完成了,只要腳本沒有提示錯誤,基本都能啟動jar服務;其他restart和stop命令也如此執(zhí)行就行:

        img

        可以去研究下shell代碼,希望該腳本能給你帶來效率和好的學習思路,下面是測試用例git地址,腳本在eureka-server項目中:https://github.com/shenniubuxing3/springcloud-Finchley.SR2

        往期資源  需要請自取

        Java項目分享 最新整理全集,找項目不累啦 03版

        臥槽!字節(jié)跳動《算法中文手冊》火了,完整版 PDF 開放下載!

        字節(jié)跳動總結的設計模式 PDF 火了,完整版開放下載!

        堪稱神級的Spring Boot手冊,從基礎入門到實戰(zhàn)進階

        臥槽!阿里大佬總結的《圖解Java》火了,完整版PDF開放下載!

        喜歡就"在看"唄^_^

        瀏覽 33
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            亚洲黄片大全 | 国模人体二区 | 荡货夹的这么紧欠c调教小说 | 国产激情在线视频 | 超碰91大香蕉 | 天天操夜夜拍免费视频 | 好大好湿好硬顶到了爽视频 | 欧美91在线国内日韩 | 欧美日韩精品一二三区 | 天天色天天日天天操 |