SpringBoot 如何打包部署

Spring Boot 使用了內嵌容器,所以它的部署方式也變得很是簡單靈活,一方面能夠將 Spring Boot 項目打包成獨立的 Jar 或者 War 包來運行,也能夠單獨打包成 War 包部署到 Tomcat 容器中運行,若是涉及到大規模的部署 Jinkins 就成爲最佳選擇之一。html

Spring Boot 默認集成 Web 容器,啓動方式和普通 Java 程序同樣,main 函數入口啓動,其內置 Tomcat 容器或 Jetty 容器,具體由配置來決定(默認 Tomcat)。java

1、相關配置

一、多環境配置

在這裏將介紹一下 Spring Boot 多環境配置文件,在咱們開發過程當中一定會面臨多環境的問題,好比開發環境、測試環境、生產環境,在不一樣的環境下會有不一樣的數據庫鏈接池等配置信息。若是都寫在一個配置文件中,在不一樣的環境下啓動須要手動修改對應的環境參數,這種方式容易出錯且不夠優雅。Spring Boot 支持多配置文件的使用,只須要啓動時指定對應的配置文件便可。git

  • 首先在 pom.xml 中添加相關配置:
<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <env>dev</env>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <env>test</env>
        </properties>
    </profile>
    <profile>
        <id>pro</id>
        <properties>
            <env>pro</env>
        </properties>
    </profile>
</profiles>

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>application-dev.properties</exclude>
                <exclude>application-pro.properties</exclude>
                <exclude>application-test.properties</exclude>
            </excludes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>application-${env}.properties</include>
            </includes>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
  • 在 Spring Boot 中多環境配置文件名須要知足 application-{profile}.properties 的格式,其中 {profile} 對應環境標識。在 resources 目錄下建立如下三個文件。
aplication-dev.properties:開發環境 
application-test.properties:測試環境 
application-prod.properties:生產環境
  • 不一樣的配置文件對應不一樣的環境,啓動的時候經過參數設置來啓用不一樣的配置,開發過程當中在 application.properties 文件中經過 spring.profiles.active 屬性來設置,其值對應 {profile} 值,生產中使用 --spring.profiles.active=dev 參數來控制加載某個配置文件。

二、配置項介紹

  • 對 Server 的幾個經常使用配置作個簡單說明:
# 項目 contextPath,通常不用配置
server.servlet.context-path=/myspringboot
# 錯誤頁,指定發生錯誤時,跳轉的 URL
server.error.path=/error
# 服務端口
server.port=6060
# session最大超時時間(分鐘),默認爲30
server.session-timeout=60
# 該服務綁定 IP 地址,啓動服務器時如本機不是該 IP 地址則拋出異常啓動失敗,只有特殊需求的狀況下才配置
# server.address=192.168.0.6
  • 若是使用的是 Tomcat 還能夠進行如下的配置:
# tomcat 最大線程數,默認爲 200  
server.tomcat.max-threads=600  
# tomcat 的 URI 編碼  
server.tomcat.uri-encoding=UTF-8  
# 存放 Tomcat 的日誌、Dump 等文件的臨時文件夾,默認爲系統的 tmp 文件夾 
server.tomcat.basedir=/tmp/log  
# 打開 Tomcat 的 Access 日誌,並能夠設置日誌格式  
#server.tomcat.access-log-enabled=true  
#server.tomcat.access-log-pattern=  
# accesslog 目錄,默認在 basedir/logs  
#server.tomcat.accesslog.directory=  
# 日誌文件目錄  
logging.path=/tmp/log  
# 日誌文件名稱,默認爲 spring.log  
logging.file=myapp.log

以上的配置都爲可選,在默認狀況下均可不配置,項目中根據實際的使用狀況來調整。web

2、項目打包

一、打成 jar 包

內嵌容器技術的發展爲 Spring Boot 部署打下了堅實的基礎,內嵌容器不僅在部署階段發揮着巨大的做用,在開發調試階段也會帶來極大的便利性,對比以往開發 Web 項目時配置 Tomcat 的繁瑣,會讓你們使用 Spring Boot 內嵌容器時有更深的感觸。使用 Spring Boot 開發 Web 項目,不須要關心容器的環境問題,專心寫業務代碼便可。spring

內嵌容器對部署帶來的改變動多,如今 Maven 、Gradle 已經成了咱們平常開發必不可少的構建工具,使用這些工具很容易的將項目打包成 Jar 或者 War 包,在服務器上僅僅須要一條命令便可啓動項目,咱們以 Maven 爲例來進行演示。數據庫

  • Maven 默認會將項目打成 jar 包,也能夠顯示指出打包方式。
<groupId>com.neo</groupId>
<artifactId>spring-boot-package</artifactId>
<version>1.0.0</version>
<!--指定打包方式-->
<packaging>jar</packaging>

Maven 打包會根據 pom 包中的 packaging 配置來決定是生成 Jar 包或者 War 包。tomcat

  • pom.xml 同目錄下,執行如下命令:
    • mvn clean 是清除項目 target 目錄下的文件
    • mvn package 打包命令,能夠和 mvn clean 一塊兒執行
cd 項目跟目錄(和 pom.xml 同級)
mvn clean package
## 或者執行下面的命令
## 排除測試代碼後進行打包
mvn clean package  -Dmaven.test.skip=true
  • 打包完成後 jar 包會生成到 target 目錄下,命名通常是「項目名+版本號.jar」的形式。
  • 啓動 jar 包命令:
java -jar  target/spring-boot-package-1.0.0.jar
  • 這種方式,只要控制檯關閉,服務就會中止,生產中咱們通常使用後臺運行的方式來啓動:
nohup java -jar spring-boot-package-1.0.0.jar &
  • 設置 jvm 參數:
java -Xms10m -Xmx80m -jar spring-boot-package-1.0.0.jar &
  • 也能夠在啓動的時候選擇讀取不一樣的配置文件:
java -jar spring-boot-package-1.0.0.jar --spring.profiles.active=dev
  • gradle
  • 若是使用的是 gradle,使用下面命令打包:
gradle build
java -jar build/libs/mymodule-0.0.1-SNAPSHOT.jar
  • Spring Boot 支持在啓動的時候添加定製,好比設置應用的堆內存、垃圾回收機制、日誌路徑等。

二、打成 war 包

  • 打成 war 包也很是的簡單,但須要添加一些額外的配置。
  • (1)Maven 項目,修改 pom 包
<packaging>jar</packaging>
改成:
<packaging>war</packaging>
  • (2)打包時排除 Tomcat
    • 在這裏將 scope 屬性設置爲 provided,這樣在打包產生的 war 中就不會包含此 jar。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
  • (3)註冊啓動類
    • 在項目的啓動類中繼承 SpringBootServletInitializer 並重寫 configure() 方法:
@SpringBootApplication
public class PackageApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(PackageApplication.class);
    }
    public static void main(String[] args) {
        SpringApplication.run(PackageApplication.class, args);
    }
}
  • 最後執行:
mvn clean package  -Dmaven.test.skip=true
  • 會在 target 目錄下生成:項目名 + 版本號.war 文件,複製到 Tomcat 服務器中啓動便可。springboot

  • 打包成功輸出的內容:服務器

Results :
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

...

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 29.290 s
[INFO] Finished at: 2017-11-26T15:19:43+08:00
[INFO] Final Memory: 36M/354M
[INFO] ------------------------------------------------------------------------
  • gradle
  • 若是使用的是 Gradle,基本步驟和 Maven 相似,build.gradle 中添加 war 的支持,排除 spring-boot-starter-tomcat:
...
apply plugin: 'war'
...
dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:2.1.0.RELEASE"){
        exclude mymodule:"spring-boot-starter-tomcat"
    }
}
  • 再使用構建命令:
gradle build
  • war 會生成在 build\libs 目錄下。

3、部署運維

一、單個部署

  • 簡單粗暴
  • 直接 kill 掉進程再次啓動 jar 包:
ps -ef|grep java 
##拿到對於 Java 程序的 pid
kill -9 pid
## 再次重啓
Java -jar  xxxx.jar
  • 固然這種方式比較傳統和暴力,建議你們使用下面的方式來管理。session

  • 腳本執行

  • 若是使用的是 Maven,須要包含如下的配置:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <executable>true</executable>
    </configuration>
</plugin>
  • 若是使用是 Gradle,須要包含下面配置:
Spring Boot {
    executable = true
}
  • 啓動方式:

    • (1)能夠直接 ./yourapp.jar 來啓動
    • (2)註冊爲服務
  • 也能夠作一個軟連接指向你的 jar 包並加入到 init.d 中,而後用命令來啓動。

  • init.d 例子:

ln -s /var/yourapp/yourapp.jar /etc/init.d/yourapp
chmod +x /etc/init.d/yourapp
  • 這樣就可使用 stop 或者是 restart 命令去管理你的應用了。
/etc/init.d/yourapp start|stop|restart
或者
service yourapp start|stop|restart
  • 若是是打包成獨立的 war 包部署到 Tomcat 中,就按照 Tomcat 的相關命令來重啓。固然以上只是單個項目部署,假設咱們有 1000 多個項目,若是再按照這種方式來打包上傳啓動的話,整個平臺部署完成估計須要幾個小時,而且很是容易出錯。在大量部署應用時,給你們介紹另一款自動化部署神器 Jenkins。

二、批量部署(Jenkins)

Jenkins 是目前持續構建領域使用最普遍的工具之一,它是一個獨立的開源自動化服務器,可用於自動化各類任務,如構建、測試和部署軟件。Jenkins 能夠經過本機系統包以 Docker 的方式部署項目,甚至能夠經過安裝 Java Runtime Environment 的任何機器獨立運行。

Jenkins 能夠很好的支持各類語言(如 Java、C#、PHP 等)項目構建,也徹底兼容 ant、maven、gradle 等多種第三方構建工具,同時跟 svn、git 能無縫集成,也支持直接與知名源代碼託管網站,好比 GitHub、Bitbucket 直接集成。

說直白一點 Jenkins 就是專門來負責如何將代碼變成可執行的程序包,將它部署到目標服務器中,並對其運營狀態(日誌)進行監控的軟件。自動化、性能、打包、部署、發佈、發佈結果自動化驗證、接口測試、單元測試等關於咱們打包測試部署的方方面面 Jenkins 均可以很友好的支持。

  • Jenkins 搭建部署分爲四個步驟:
    • 第一步,Jenkins 安裝
    • 第二步,插件安裝和配置
    • 第三步,Push SSH
    • 第四步,部署項目

具體的安裝部署過程能夠參考文章:使用 Jenkins 部署 Spring Boot(http://www.ityouknow.com/springboot/2017/11/11/springboot-jenkins.html)。

  • 在這裏主要看一下使用 Jenkins 部署 Spring Boot 的腳本。
DATE=$(date +%Y%m%d)
export JAVA_HOME PATH CLASSPATH
JAVA_HOME=/usr/java/jdk1.8.0_131
PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$CLASSPATH
DIR=/root/xxx
JARFILE=xxx-1.0.0-SNAPSHOT.jar

if [ ! -d $DIR/backup ];then
   mkdir -p $DIR/backup
fi
cd $DIR

ps -ef | grep $JARFILE | grep -v grep | awk '{print $2}' | xargs kill -9
mv $JARFILE backup/$JARFILE$DATE
mv -f /root/Jenkins-in/$JARFILE .

java -jar $JARFILE > out.log &
if [ $? = 0 ];then
        sleep 30
        tail -n 50 out.log
fi

cd backup/
ls -lt|awk 'NR>5{print $NF}'|xargs rm -rf
  • 首先導入相關環境變量,而後根據日期對項目進行備份,kill 掉正在執行的 Spring Boot 項目,將推送過來的項目包放到對應目錄下,使用 java -jar 命令來啓動應用,最後將啓動日誌打印出來。

  • 使用 Jenkin 以後,部署項目的步驟以下:

    • push 代碼到 Github(或者 SVN) 觸發 WebHook
    • Jenkins 從倉庫拉去代碼
    • Maven 構建項目、單元測試
    • 備份項目,中止正在運行的項目
    • 啓動應用
    • 查看啓動日誌

使用 Jenkin 前期作一些簡單的配置,後期當發佈項目時只須要點擊項目對應的發佈按鈕,就能夠將項目從版本庫中拉取、打包、發佈到目標服務器中,大大簡化了運維後期的部署工做。

三、查看應用運行配置

  • 能夠根據 Java 自帶的 jinfo 命令:
jinfo -flags pid
  • 來查看 jar 啓動後使用的是什麼 gc、新生代、老年代分批的內存都是多少,示例以下:
    • XX:CICompilerCount:最大的並行編譯數
    • XX:InitialHeapSize 和 -XX:MaxHeapSize:指定 JVM 的初始和最大堆內存大小
    • XX:MaxNewSize:JVM 堆區域新生代內存的最大可分配大小
    • XX:+UseCompressedClassPointers: 壓縮類指針
    • XX:+UseCompressedOops: 壓縮對象指針
    • XX:+UseParallelGC:垃圾回收使用 Parallel 收集器
Attaching to process ID 5589, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=16777216 -XX:MaxHeapSize=262144000
 -XX:MaxNewSize=87359488 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=5570560 -XX:OldSize=11206656 
 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC

4、總結

Spring Boot 項目支持在不一樣環境下指定不一樣配置文件啓動,方便開發人員在各個環節部署。Spring Boot 由於使用了內嵌容器,所以極大的優化了項目的部署難度,咱們能夠根據配置將 Spring Boot 打包成 Jar 或者 War 部署,單個項目可使用命令行或者腳本的形式部署項目,若是涉及大量應用的部署運維,建議使用 Jenkins 發佈 Spring Boot 項目,使用 Jinkins 能夠以圖形化的形式批量部署 Spring Boot 應用。

相關文章
相關標籤/搜索