Spring Boot项目使用maven-assembly-plugin根据不同环境打包成tar.gz或者zip

spring-boot-assembly

  1. 在spring boot项目中使用maven profiles和maven assembly插件根据不同环境打包成tar.gz或者zip
  2. 将spring boot项目中的配置文件提取到外部config目录中
  3. 将spring boot项目中的启动jar包移动到boot目录中
  4. 将spring boot项目中的第三方依赖jar包移动到外部lib目录中
  5. bin目录中是启动,停止,重启服务命令
  6. 打包后的目录结构类似于tomcat/maven目录结构

代码托管

Gitee

主要插件

  1. maven-assembly-plugin
  2. maven-jar-plugin
  3. spring-boot-maven-plugin
  4. maven-dependency-plugin
  5. maven-resources-plugin

1.maven-assembly-plugin 配置assembly.xml文件路径


        maven-assembly-plugin
        3.1.0
        
            
                src/main/assembly/assembly.xml
            
        
        
            
                make-assembly
                package
                
                    single
                
            
        
    

2.assembly.xml打包配置文件



    
    
    ${profileActive}-${project.version}

    
    
        tar.gz
        
    

    true

    
        
        
        
            ${basedir}/src/bin
            bin
            0755
            
                **.sh
                **.bat
            
        

        
        
            ${basedir}/target/classes
            config
            0644
            
                application.yml
                application-${profileActive}.yml
                mapper/**/*.xml
                static/**
                templates/**
                *.xml
                *.properties
            
        

        
        
            ${basedir}/target/lib
            lib
            0755
        

        
        
            ${basedir}/target
            boot
            0755
            
                ${project.build.finalName}.jar
            
        

        
        
            ${basedir}
            
                NOTICE
                LICENSE
                *.md
            
        
    



3.spring-boot-maven-plugin 排除启动jar包中依赖的jar包


    org.springframework.boot
    spring-boot-maven-plugin
    
        ZIP
        
            
            
                non-exists
                non-exists
            
        
    


4.maven-jar-plugin 自定义maven jar打包内容


    org.apache.maven.plugins
    maven-jar-plugin
    3.1.0
    
        
            
                
                Application
                
                ../lib
                true
            
        
        
            
            io/geekidea/springboot/**
        
    
    

5.maven-dependency-plugin 复制项目的依赖包到指定目录


    org.apache.maven.plugins
    maven-dependency-plugin
    3.1.0
    
        
            prepare-package
            
                copy-dependencies
            
            
                target/lib
                false
                false
                true
                compile
            
        
    


6.maven-resources-plugin


    org.apache.maven.plugins
    maven-resources-plugin
    3.1.0



    src/main/resources
    true
    
        application.yml
        application-${profileActive}.yml
        mapper/**/*.xml
        static/**
        templates/**
        *.xml
        *.properties
    


7.maven profiles配置




    
        local
        
            local
        
        
            true
        
    
    
        dev
        
            dev
        
        
            false
        
    
    
        test
        
            test
        
        
            false
        
    
    
        uat
        
            uat
        
        
            false
        
    
    
        prod
        
            prod
        
        
            false
        
    


8.阿里云仓库配置


    
    
        aliyun
        http://maven.aliyun.com/nexus/content/groups/public/
    



项目源码结构
├─bin
│      restart.sh
│      shutdown.sh
│      startup.bat
│      startup.sh
│
├─logs
│      springboot-assembly.log
│
├─main
│  ├─assembly
│  │      assembly.xml
│  │
│  ├─java
│  │  └─io
│  │      └─geekidea
│  │          └─springboot
│  │              └─assembly
│  │                      Application.java
│  │                      HelloController.java
│  │                      HelloService.java
│  │                      HelloServiceImpl.java
│  │
│  └─resources
│      │  application-dev.yml
│      │  application-local.yml
│      │  application-prod.yml
│      │  application-test.yml
│      │  application-uat.yml
│      │  application.yml
│      │
│      ├─mapper
│      │  │  test.xml
│      │  │
│      │  └─hello
│      │          hello.xml
│      │
│      ├─static
│      │      index.html
│      │
│      └─templates
│              test.txt
│
└─test

项目打包
mvn clean package

使用maven assembly插件打包local环境后的压缩包,target目录下
spring-boot-assembly-local-1.0.RELEASE.tar.gz

linux解压tar.gz
tar -zxvf spring-boot-assembly-local-1.0.RELEASE.tar.gz

解压后的目录结构
└─spring-boot-assembly
    │  LICENSE
    │  NOTICE
    │  README.md
    │
    ├─bin
    │      restart.sh
    │      shutdown.sh
    │      startup.bat
    │      startup.sh
    │
    ├─boot
    │      spring-boot-assembly.jar
    │
    ├─config
    │  │  application-local.yml
    │  │  application.yml
    │  │
    │  ├─mapper
    │  │  │  test.xml
    │  │  │
    │  │  └─hello
    │  │          hello.xml
    │  │
    │  ├─static
    │  │      index.html
    │  │
    │  └─templates
    │          test.txt
    │
    └─lib
            classmate-1.4.0.jar
            fastjson-1.2.54.jar
            hibernate-validator-6.0.13.Final.jar
            jackson-annotations-2.9.0.jar
            jackson-core-2.9.7.jar
            jackson-databind-2.9.7.jar
            jackson-datatype-jdk8-2.9.7.jar
            jackson-datatype-jsr310-2.9.7.jar
            jackson-module-parameter-names-2.9.7.jar
            javax.annotation-api-1.3.2.jar
            jboss-logging-3.3.2.Final.jar
            jul-to-slf4j-1.7.25.jar
            log4j-api-2.11.1.jar
            log4j-to-slf4j-2.11.1.jar
            logback-classic-1.2.3.jar
            logback-core-1.2.3.jar
            slf4j-api-1.7.25.jar
            snakeyaml-1.23.jar
            spring-aop-5.1.2.RELEASE.jar
            spring-beans-5.1.2.RELEASE.jar
            spring-boot-2.1.0.RELEASE.jar
            spring-boot-autoconfigure-2.1.0.RELEASE.jar
            spring-boot-starter-2.1.0.RELEASE.jar
            spring-boot-starter-json-2.1.0.RELEASE.jar
            spring-boot-starter-logging-2.1.0.RELEASE.jar
            spring-boot-starter-tomcat-2.1.0.RELEASE.jar
            spring-boot-starter-web-2.1.0.RELEASE.jar
            spring-context-5.1.2.RELEASE.jar
            spring-core-5.1.2.RELEASE.jar
            spring-expression-5.1.2.RELEASE.jar
            spring-jcl-5.1.2.RELEASE.jar
            spring-web-5.1.2.RELEASE.jar
            spring-webmvc-5.1.2.RELEASE.jar
            tomcat-embed-core-9.0.12.jar
            tomcat-embed-el-9.0.12.jar
            tomcat-embed-websocket-9.0.12.jar
            validation-api-2.0.1.Final.jar


window启动,会打开浏览器,访问项目测试路径
bin/startup.bat

  • 访问地址: http://localhost:8080/example/hello?name=123
  • 响应结果:
{"msg":"service hello:123","code":200}

linux启动,停止,重启
sh bin/startup.sh   启动项目
sh bin/shutdown.sh  停止服务
sh bin/restart.sh   重启服务

startup.sh 脚本中的主要内容
  • 配置项目名称及项目启动jar名称,默认项目名称与启动jar名称一致
APPLICATION="spring-boot-assembly"
APPLICATION_JAR="${APPLICATION}.jar"

  • JAVA_OPTION配置
  • JVM Configuration
  • -Xmx256m:设置JVM最大可用内存为256m,根据项目实际情况而定,建议最小和最大设置成一样。
  • -Xms256m:设置JVM初始内存。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存
  • -Xmn512m:设置年轻代大小为512m。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
  • -XX:MetaspaceSize=64m:存储class的内存大小,该值越大触发Metaspace GC的时机就越晚
  • -XX:MaxMetaspaceSize=320m:限制Metaspace增长的上限,防止因为某些情况导致Metaspace无限的使用本地内存,影响到其他程序
  • -XX:-OmitStackTraceInFastThrow:解决重复异常不打印堆栈信息问题
JAVA_OPT="-server -Xms256m -Xmx256m -Xmn512m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"

执行启动命令:后台启动项目,并将日志输出到项目根目录下的logs文件夹下

nohup java ${JAVA_OPT} -jar ${BASE_PATH}/boot/${APPLICATION_JAR} --spring.config.location=${CONFIG_DIR} > ${LOG_PATH} 2>&1 &

最终执行jar包的命令

nohup java -server -Xms256m -Xmx256m -Xmn512m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m -XX:-OmitStackTraceInFastThrow -jar /opt/spring-boot-assembly/boot/spring-boot-assembly.jar --spring.config.location=/opt/spring-boot-assembly/config/ > /opt/spring-boot-assembly/logs/spring-boot-assembly.log 2>&1 &

  • nohup:在后台运行jar包,然后将运行日志输出到指定位置
  • -server:指定JVM参数
  • -jar /opt/spring-boot-assembly/boot/spring-boot-assembly.jar:指定启动的jar包
  • 启动命令中指定的启动jar包路径,配置文件路径,日志路径都是绝对路径
  • 可在任何位置执行start.sh, shutdown.sh,restart.sh脚本
  • –spring.config.location:指定配置文件目录或者文件名称,如果是目录,以/结束
  • /opt/spring-boot-assembly/logs/spring-boot-assembly.log:指定日志输出路径

  • 2>&1 & :将正常的运行日志和错误日志合并输入到指定日志,并在后台运行

shutdown.sh停服脚本,实现方式:找到当前项目的PID,然后kill -9

PID=$(ps -ef | grep "${APPLICATION_JAR}" | grep -v grep | awk '{ print $2 }')
kill -9 ${PID}

日志记录

项目启动日志存储路径,一个项目只有一个启动日志文件
logs/spring-boot-assembly_startup.log

================================================ 2018-12-12 12:36:56 ================================================
application name: spring-boot-assembly
application jar name: spring-boot-assembly.jar
application bin path: /opt/spring-boot-assembly/bin
application root path: /opt/spring-boot-assembly
application log path: /opt/spring-boot-assembly/logs/spring-boot-assembly.log
application JAVA_OPT : -server -Xms256m -Xmx256m -Xmn512m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m -XX:-OmitStackTraceInFastThrow
application background startup command: nohup java -server -Xms256m -Xmx256m -Xmn512m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m -XX:-OmitStackTraceInFastThrow -jar /opt/spring-boot-assembly/boot/spring-boot-assembly.jar --spring.config.location=/opt/spring-boot-assembly/config/ > /opt/spring-boot-assembly/logs/spring-boot-assembly.log 2>&1 &
application pid: 11596

项目运行日志存储路径,最近一次启动项目的运行日志
logs/spring-boot-assembly.log

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.0.RELEASE)

2018-12-12 23:28:58.420  INFO 11596 --- [           main] o.s.boot.SpringApplication               : Starting application on VM_0_17_centos with PID 11596 (started by root in /opt/spring-boot-assembly)
2018-12-12 23:28:58.442  INFO 11596 --- [           main] o.s.boot.SpringApplication               : The following profiles are active: local
2018-12-12 23:29:01.355  INFO 11596 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2018-12-12 23:29:01.437  INFO 11596 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2018-12-12 23:29:01.437  INFO 11596 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/9.0.12
2018-12-12 23:29:01.461  INFO 11596 --- [           main] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2018-12-12 23:29:01.646  INFO 11596 --- [           main] o.a.c.c.C.[.[localhost].[/example]       : Initializing Spring embedded WebApplicationContext
2018-12-12 23:29:01.647  INFO 11596 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 3028 ms
2018-12-12 23:29:01.708  INFO 11596 --- [           main] o.s.b.w.servlet.ServletRegistrationBean  : Servlet dispatcherServlet mapped to [/]
2018-12-12 23:29:01.712  INFO 11596 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-12-12 23:29:01.712  INFO 11596 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-12-12 23:29:01.712  INFO 11596 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'formContentFilter' to: [/*]
2018-12-12 23:29:01.713  INFO 11596 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-12-12 23:29:02.250  INFO 11596 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2018-12-12 23:29:03.179  INFO 11596 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path '/example'
2018-12-12 23:29:03.182  INFO 11596 --- [           main] o.s.boot.SpringApplication               : Started application in 5.844 seconds (JVM running for 6.547)
spring.profiles.active = local
contextPath = /example
server.port = 8080
hello = Hello Local
http://localhost:8080/example/hello?name=123

项目历史运行日志存储路径,每启动一次项目,会将之前的运行日志移动到back目录
`-- logs
    |-- back
    |   |-- spring-boot-assembly_back_2018-12-12-23-30-10.log
    |   `-- spring-boot-assembly_back_2018-12-12-23-36-56.log
    |-- spring-boot-assembly.log
    `-- spring-boot-assembly_startup.log

maven项目打包

1. 使用IDEA工具打包,选择对应的profiles,然后clean package
mvn-clean-package-local
mvn-clean-package-dev
2. 使用maven命令打包
mvn clean package -Pdev

3. 使用mvn-package脚本打包

window

mvn-package.bat dev

linux/mac

sh mvn-package.sh dev

FAQ

Q: 项目打成tar包后,不能正常读取resource目录下的某些配置文件
A:如果resource目录中还用到其它配置文件,需要在pom.xml和assembly.xml文件的resource中进行配置
  1. pom.xml中的resource默认配置

把需要打包的文件添加到include中



    src/main/resources
    true
    
        application.yml
        application-${profileActive}.yml
        mapper/**/*.xml
        static/**
        templates/**
        *.xml
        *.properties
        
        xxx.keystore
    


  1. assembly.xml中的resource默认配置

把需要打包的文件添加到include中



    ${basedir}/target/classes
    config
    0644
    
        application.yml
        application-${profileActive}.yml
        mapper/**/*.xml
        static/**
        templates/**
        *.xml
        *.properties
        
        xxx.keystore
    


参考:
  • https://docs.spring.io/spring-boot/docs/current/maven-plugin/
  • http://maven.apache.org/components/plugins/maven-assembly-plugin/usage.html
  • http://maven.apache.org/plugins/maven-jar-plugin/
  • http://maven.apache.org/components/plugins/maven-dependency-plugin/
  • https://maven.apache.org/plugins/maven-resources-plugin/
  • http://maven.apache.org/guides/introduction/introduction-to-profiles.html
startup.sh
#! /bin/shell

#======================================================================
# 项目启动shell脚本
# boot目录: spring boot jar包
# config目录: 配置文件目录
# logs目录: 项目运行日志目录
# logs/spring-boot-assembly_startup.log: 记录启动日志
# logs/back目录: 项目运行日志备份目录
# nohup后台运行
#
#======================================================================

# 项目名称
APPLICATION="spring-boot-assembly"

# 项目启动jar包名称
APPLICATION_JAR="${APPLICATION}.jar"

# bin目录绝对路径
BIN_PATH=$(cd `dirname $0`; pwd)
# 进入bin目录
cd `dirname $0`
# 返回到上一级项目根目录路径
cd ..
# 打印项目根目录绝对路径
# `pwd` 执行系统命令并获得结果
BASE_PATH=`pwd`

# 外部配置文件绝对目录,如果是目录需要/结尾,也可以直接指定文件
# 如果指定的是目录,spring则会读取目录中的所有配置文件
CONFIG_DIR=${BASE_PATH}"/config/"

# 项目日志输出绝对路径
LOG_DIR=${BASE_PATH}"/logs"
LOG_FILE="${APPLICATION}.log"
LOG_PATH="${LOG_DIR}/${LOG_FILE}"
# 日志备份目录
LOG_BACK_DIR="${LOG_DIR}/back/"

# 项目启动日志输出绝对路径
LOG_STARTUP_PATH="${LOG_DIR}/${APPLICATION}_startup.log"

# 当前时间
NOW=`date +'%Y-%m-%m-%H-%M-%S'`
NOW_PRETTY=`'date +%Y-%m-%m %H:%M:%S'`

# 启动日志
STARTUP_LOG="================================================ ${NOW_PRETTY} ================================================\n"

# 如果logs文件夹不存在,则创建文件夹
if [[ ! -d "${LOG_DIR}" ]]; then
  mkdir "${LOG_DIR}"
fi

# 如果logs/back文件夹不存在,则创建文件夹
if [[ ! -d "${LOG_BACK_DIR}" ]]; then
  mkdir "${LOG_BACK_DIR}"
fi

# 如果项目运行日志存在,则重命名备份
if [[ -f "${LOG_PATH}" ]]; then
    mv ${LOG_PATH} "${LOG_BACK_DIR}/${APPLICATION}_back_${NOW}.log"
fi

# 创建新的项目运行日志
echo "" > ${LOG_PATH}

# 如果项目启动日志不存在,则创建,否则追加
echo "${STARTUP_LOG}" >> ${LOG_STARTUP_PATH}

#==========================================================================================
# JVM Configuration
# -Xmx256m:设置JVM最大可用内存为256m,根据项目实际情况而定,建议最小和最大设置成一样。
# -Xms256m:设置JVM初始内存。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存
# -Xmn512m:设置年轻代大小为512m。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。
#          持久代一般固定大小为64m,所以增大年轻代,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
# -XX:MetaspaceSize=64m:存储class的内存大小,该值越大触发Metaspace GC的时机就越晚
# -XX:MaxMetaspaceSize=320m:限制Metaspace增长的上限,防止因为某些情况导致Metaspace无限的使用本地内存,影响到其他程序
# -XX:-OmitStackTraceInFastThrow:解决重复异常不打印堆栈信息问题
#==========================================================================================
JAVA_OPT="-server -Xms256m -Xmx256m -Xmn512m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"

#=======================================================
# 将命令启动相关日志追加到日志文件
#=======================================================

# 输出项目名称
STARTUP_LOG="${STARTUP_LOG}application name: ${APPLICATION}\n"
# 输出jar包名称
STARTUP_LOG="${STARTUP_LOG}application jar name: ${APPLICATION_JAR}\n"
# 输出项目bin路径
STARTUP_LOG="${STARTUP_LOG}application bin  path: ${BIN_PATH}\n"
# 输出项目根目录
STARTUP_LOG="${STARTUP_LOG}application root path: ${BASE_PATH}\n"
# 打印日志路径
STARTUP_LOG="${STARTUP_LOG}application log  path: ${LOG_PATH}\n"
# 打印JVM配置
STARTUP_LOG="${STARTUP_LOG}application JAVA_OPT : ${JAVA_OPT}\n"

# 打印启动命令
STARTUP_LOG="${STARTUP_LOG}application background startup command: nohup java ${JAVA_OPT} -jar ${BASE_PATH}/boot/${APPLICATION_JAR} --spring.config.location=${CONFIG_DIR} > ${LOG_PATH} 2>&1 &\n"

#======================================================================
# 执行启动命令:后台启动项目,并将日志输出到项目根目录下的logs文件夹下
#======================================================================
nohup java ${JAVA_OPT} -jar ${BASE_PATH}/boot/${APPLICATION_JAR} --spring.config.location=${CONFIG_DIR} > ${LOG_PATH} 2>&1 &

# 进程ID
PID=$(ps -ef | grep "${APPLICATION_JAR}" | grep -v grep | awk '{ print $2 }')
STARTUP_LOG="${STARTUP_LOG}application pid: ${PID}\n"

# 启动日志追加到启动日志文件中
echo -e ${STARTUP_LOG} >> ${LOG_STARTUP_PATH}
# 打印启动日志
echo -e ${STARTUP_LOG}

# 打印项目日志
tail -f ${LOG_PATH}

startup.bat
@echo off
rem ======================================================================
rem windows startup script
rem
rem ======================================================================

rem Open in a browser
start "" "http://localhost:8080/example/hello?name=123"

rem startup jar
java -jar ../boot/spring-boot-assembly.jar --spring.config.location=../config/

pause

shutdown.sh
#! /bin/shell

#======================================================================
# 项目停服shell脚本
# 通过项目名称查找到PID
# 然后kill -9 pid
#
#======================================================================

# 项目名称
APPLICATION="spring-boot-assembly"

# 项目启动jar包名称
APPLICATION_JAR="${APPLICATION}.jar"

PID=$(ps -ef | grep "${APPLICATION_JAR}" | grep -v grep | awk '{ print $2 }')
if [[ -z "$PID" ]]
then
    echo ${APPLICATION} is already stopped
else
    echo kill  ${PID}
    kill -9 ${PID}
    echo ${APPLICATION} stopped successfully
fi

restart.sh
#! /bin/shell

#======================================================================
# 项目重启shell脚本
# 先调用shutdown.sh停服
# 然后调用startup.sh启动服务
#
#======================================================================

# 项目名称
APPLICATION="spring-boot-assembly"

# 停服
echo stop ${APPLICATION} Application...
sh shutdown.sh

# 启动服务
echo start ${APPLICATION} Application...
sh startup.sh

你可能感兴趣的:(Spring Boot项目使用maven-assembly-plugin根据不同环境打包成tar.gz或者zip)