美文网首页
使用assembly 插件定制化打包项目

使用assembly 插件定制化打包项目

作者: touch_The_Sky | 来源:发表于2018-05-30 14:11 被阅读0次

    assembly(装配/组装)
    对于SpringBoot项目通常我们会使用mavaen提供的普通的打包方式打成一个jar包, 这对于在本地运行似乎没有什么问题, 但是把这种方式在Linux上运行却会出现很多问题,导致无法运行, 而且打包的结构也并不清晰,所以我们需要一个插件来完成打包的工作, 把你的项目打包成一个包含脚本、配置文件、运行时所有依赖的部署包
    “assembly”就是把一组文件、目录、依赖元素组装成一个归档文件的插件
    官方配置详解:http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
    这里使用SpringBoot + Dubbo 的Server项目进行演示

    一. 原始项目是一个最简单的SpringBoot +Dubbo 生产者端的小示例,只发布了一个helloWord服务, 在此基础上拷贝assebly的几个文件到main目录

    assembly.jpg
    
    - bin 目录放打包后项目的启动/停止脚本 , 这几个脚本可以到dubbo-2.5.7.jar-->MATA-INF-->assembly.bin
      下去拷,然后根据需要修改一下 主方法类 和配置文件名称 等
    - assembly.xml 是maven-assembly-plugin插件对应的配置文件
    
    

    二, 在maven中添加assembly插件

    <build>
            <!--我们自己的文件会打成一个demo-server.jar包,此包中不需要配置文件-->
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <excludes>
                        <exclude>**/*.xml</exclude>
                        <exclude>**/*.properties</exclude>
                    </excludes>
                </resource>
            </resources>
            <plugins>
                
                <!--assebly插件-->
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.5.5</version>
                    <configuration>
                        <finalName>${project.artifactId}</finalName>
                        <skipAssembly>false</skipAssembly>
                        <appendAssemblyId>false</appendAssemblyId>
    <!--如果路径长度超过100字符,执行的操作warn" (default), "fail", "truncate", "gnu", or "omit". -->
                        <tarLongFileMode>gnu</tarLongFileMode>
                        <outputDirectory>target</outputDirectory>
                        <!--具体配置文件所在路径-->
                        <descriptors>
                            <descriptor>src/main/assembly/assembly.xml</descriptor>
                        </descriptors>
                    </configuration>
                    <!--执行的操作-->
                    <executions>
                        <execution>
                            <id>assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
    
        </build>
    <!--profile设置 , 这个跟Assebly打包没关系,根据需要配置 -->
    <profiles>
            <profile>
                <id>dev</id>
                <properties>
                    <dubbo.application.name>demo-server-dev</dubbo.application.name>
                </properties>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
            </profile>
            <profile>
                <id>test</id>
                <properties>
                    <dubbo.application.name>demo-server-test</dubbo.application.name>
                </properties>
            </profile>
        </profiles>
    
    

    PS:在使用Assembly打包的时候必须要springboot把默认的打包插件删除掉,否则会报找不到启动类

        <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    

    二,配置assembly.xml定制打包过程

    <?xml version="1.0" encoding="UTF-8"?>
    <assembly>
        <id>prd</id>
        <baseDirectory>${project.artifactId}</baseDirectory>
        <includeBaseDirectory>true</includeBaseDirectory>
        <formats>
            <format>tar.gz</format><!--打包的文件格式:tar.zip war zip等-->
        </formats>
        <fileSets>
            <!-- 将src/main/resources下配置问价打包到conf目录 -->
            <fileSet>
                <directory>src/main/resources</directory>
                <outputDirectory>/conf</outputDirectory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtered>true</filtered><!-- 是否进行属性替换 -->
            </fileSet>
    
            <!-- 打包.sh文件到bin 目录 -->
            <fileSet>
                <directory>src/main/assembly/bin</directory>
                <outputDirectory>/bin</outputDirectory>
                <includes>
                    <include>*.*</include>
                </includes>
                <fileMode>0755</fileMode><!--赋予文件权限-->
            </fileSet>
        </fileSets>
        <!--依赖输出-->
        <dependencySets>
            <dependencySet>
                <unpack>false</unpack><!--不解压-->
                <outputDirectory>lib</outputDirectory><!--依赖包输出路径-->
                <useProjectArtifact>true</useProjectArtifact><!--当前项目构件是否包含在这个依赖集合里。-->
                <scope>runtime</scope><!-- 将scope为runtime的依赖包打包到lib目录下。 -->
    
            </dependencySet>
        </dependencySets>
    </assembly>
    

    三,根据需要配置startup.sh/stop.sh等便捷启动/停止项目的脚本,这里给出一个示例:

    1.startup.sh

    #!/bin/bash
    cd `dirname $0`
    BIN_DIR=`pwd`
    cd ..
    DEPLOY_DIR=`pwd`
    CONF_DIR=$DEPLOY_DIR/conf
    MAIN_CLASS=cn.wolfcode.DemoServerApplication
    
    SERVER_NAME=`sed '/spring.dubbo.application.name/!d;s/.*=//' conf/application.properties | tr -d '\r'`
    SERVER_PROTOCOL=`sed '/spring.dubbo.protocol.name/!d;s/.*=//' conf/application.properties | tr -d '\r'`
    SERVER_PORT=`sed '/spring.dubbo.protocol.port/!d;s/.*=//' conf/application.properties | tr -d '\r'`
    LOGS_FILE=`sed '/dubbo.log4j.file/!d;s/.*=//' conf/application.properties | tr -d '\r'`
    
    if [ -z "$SERVER_NAME" ]; then
        SERVER_NAME=`hostname`
    fi
    
    PIDS=`ps -ef | grep java | grep -v grep | grep "$CONF_DIR" |awk '{print $2}'`
    if [ -n "$PIDS" ]; then
        echo "ERROR: The $SERVER_NAME already started!"
        echo "PID: $PIDS"
        exit 1
    fi
    
    if [ -n "$SERVER_PORT" ]; then
        SERVER_PORT_COUNT=`netstat -tln | grep $SERVER_PORT | wc -l`
        if [ $SERVER_PORT_COUNT -gt 0 ]; then
            echo "ERROR: The $SERVER_NAME port $SERVER_PORT already used!"
            exit 1
        fi
    fi
    
    LOGS_DIR=""
    if [ -n "$LOGS_FILE" ]; then
        LOGS_DIR=`dirname $LOGS_FILE`
    else
        LOGS_DIR=$DEPLOY_DIR/logs
    fi
    if [ ! -d $LOGS_DIR ]; then
        mkdir $LOGS_DIR
    fi
    STDOUT_FILE=$LOGS_DIR/stdout.log
    
    LIB_DIR=$DEPLOY_DIR/lib
    LIB_JARS=`ls $LIB_DIR|grep .jar|awk '{print "'$LIB_DIR'/"$0}'|tr "\n" ":"`
    
    JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true "
    JAVA_DEBUG_OPTS=""
    if [ "$1" = "debug" ]; then
        JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n "
    fi
    JAVA_JMX_OPTS=""
    if [ "$1" = "jmx" ]; then
        JAVA_JMX_OPTS=" -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false "
    fi
    JAVA_MEM_OPTS=""
    BITS=`java -version 2>&1 | grep -i 64-bit`
    if [ -n "$BITS" ]; then
        JAVA_MEM_OPTS=" -server -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 "
    else
        JAVA_MEM_OPTS=" -server -Xms1g -Xmx1g -XX:PermSize=128m -XX:SurvivorRatio=2 -XX:+UseParallelGC "
    fi
    
    echo -e "Starting the $SERVER_NAME ...\c"
    nohup java $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS -classpath $CONF_DIR:$LIB_JARS $MAIN_CLASS > $STDOUT_FILE 2>&1 &
    
    
    echo "OK!"
    PIDS=`ps -f | grep java | grep -v grep | grep "$DEPLOY_DIR" | awk '{print $2}'`
    echo "PID: $PIDS"
    echo "STDOUT: $STDOUT_FILE"
    
    

    stop.sh

    #!/bin/bash
    cd `dirname $0`
    BIN_DIR=`pwd`
    cd ..
    DEPLOY_DIR=`pwd`
    CONF_DIR=$DEPLOY_DIR/conf
    
    SERVER_NAME=`sed '/spring.dubbo.application.name/!d;s/.*=//' conf/application.properties | tr -d '\r'`
    
    if [ -z "$SERVER_NAME" ]; then
        SERVER_NAME=`hostname`
    fi
    
    PIDS=`ps -ef | grep java | grep -v grep | grep "$CONF_DIR" |awk '{print $2}'`
    if [ -z "$PIDS" ]; then
        echo "ERROR: The $SERVER_NAME does not started!"
        exit 1
    fi
    
    if [ "$1" != "skip" ]; then
        $BIN_DIR/dump.sh
    fi
    
    echo -e "Stopping the $SERVER_NAME ...\c"
    for PID in $PIDS ; do
        kill $PID > /dev/null 2>&1
    done
    
    COUNT=0
    while [ $COUNT -lt 1 ]; do    
        echo -e ".\c"
        sleep 1
        COUNT=1
        for PID in $PIDS ; do
            PID_EXIST=`ps -f -p $PID | grep java`
            if [ -n "$PID_EXIST" ]; then
                COUNT=0
                break
            fi
        done
    done
    
    echo "OK!"
    echo "PID: $PIDS"
    
    

    四,配置完毕,执行package

    到Target目录查看是否生成xxx.tar.gz
    生成的xxx.tar.gz包结构:

    |
        |-bin
        |-conf
        |-lib
    

    五,部署

    拷贝xxx.tar.gz到linux
    tar -zxvf xxx.tar.gz
    cd xxx/bin
    ./start.sh
    tail -f -n 100 ../logs/stout.log 查看日志是否启动成功

    ps: SpringBoot + Dubbo 服务端main方法启动需要在最后阻塞进程, 但是不能使用System.in.read() 这种方式, 请参考Dubbo 官方Main类中使用Lock的阻塞方式

    相关文章

      网友评论

          本文标题:使用assembly 插件定制化打包项目

          本文链接:https://www.haomeiwen.com/subject/cvuzjftx.html