SpringBoot项目jar、war方式的部署

一、jar形式部署

java -jar  xxxxxx.jar 

这种方式的启动,linux只会短暂的运行该项目,当退出控制台后会自动关闭该项目。

nohup java -jar xxxxxxx.jar >日志文件名.log 2>&1 &

命令详解:

  • nohup:不挂断地运行命令,退出帐户之后继续运行相应的进程。如果未安装请执行 yum install coreutils 。
  • >日志文件名.log:是nohup把command的输出重定向到当前目录的指定的“日志文件名.log”文件中,即输出内容不打印到屏幕上,而是输出到”日志文件名.log”文件中。不指定文件名会在当前目录创建nohup.out,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。

  • 2>&1:2就是标准错误,1是标准输出,该命令相当于把标准错误重定向到标准输出么。这里&相当于标准错误等效于标准输出,即把标准错误和标准输出同时输出到指定的“日志文件名.log”文件中。
  • &:让该作业在后台运行。
shell

平时我们用的最多的shell来启动、停止项目。

启动方法:app.sh start 会自动生成catalina.log(文件名称可以自行修改脚本) 文件可供查阅日志
查阅实时日志方法:tail -f catalina.log
停止方法:app.sh stop 会杀掉当前目录下的服务进程
重启方法:app.restart 平滑重启服务
查询状态:app.status
app.sh内容如下:

#!/bin/bash
version="6.6.6";
appName=$2
if [ -z $appName ];then
    # 搜索目录下的jar,还是一个项目一个文件夹,一个文件内有jar包和该sh文件
    appName=`ls -t |grep .jar$ |head -n1`
fi

## 后台启动项目 自动生成 catalina.log日志文件
function start()
{
    count=`ps -ef |grep java|grep $appName|wc -l`
    if [ $count != 0 ];then
        echo "Maybe $appName is running, please check it..."
    else
        echo "The $appName is starting..."
        nohup java -jar ./$appName -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -Xms512M -Xmx4G > catalina.log 2>&1 &
    fi
}
## 停止项目
function stop()
{
    appId=`ps -ef |grep java|grep $appName|awk '{print $2}'`
    if [ -z $appId ];then
        echo "Maybe $appName not running, please check it..."
    else
        echo "The $appName is stopping..."
        kill $appId
    fi
}
##重启项目(平滑启动)
function restart()
{
    # get release version
    releaseApp=`ls -t |grep .jar$ |head -n1`

    # get last version 
    lastVersionApp=`ls -t |grep .jar$ |head -n2 |tail -n1`

    appName=$lastVersionApp
    stop
    for i in {5..1}
    do
        echo -n "$i "
        sleep 1
    done
    echo 0

    backup

    appName=$releaseApp
    start
}

function backup() 
{
    # get backup version
    backupApp=`ls |grep -wv $releaseApp$ |grep .jar$`

    # create backup dir
    if [ ! -d "backup" ];then
        mkdir backup
    fi

    # backup
    for i in ${backupApp[@]}
    do
        echo "backup" $i
        mv $i backup
    done
}

## 查看项目当前状态 
function status()
{
    appId=`ps -ef |grep java|grep $appName|awk '{print $2}'`
    if [ -z $appId ] 
    then
        echo -e "\033[31m Not running \033[0m" 
    else
        echo -e "\033[32m Running [$appId] \033[0m" 
    fi
}


function usage()
{
    echo "Usage: $0 {start|stop|restart|status|stop -f}"
    echo "Example: $0 start"
    exit 1
}

case $1 in
    start)
    start;;

    stop)
    stop;;

    restart)
    restart;;

    status)
    status;;

    *)
    usage;;
esac
View Code

二、war形式部署

要使用war形式部署,首先就要打包成war。

pom依赖 剔除内置的tomcat
<!-- web 剔除内置的tomcat, 部署时才用剔除,开发可用内置的-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions> 
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!--添加servlet-api的依赖-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
pom依赖,配置启动类
<build>
    <plugins>
        <!-- 添加spring的插件, 就可以直接通过 mvn spring-boot:run 运行了 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>com.linhw.example.AppClient</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
            <!--在这里添加 springloader plugin,热部署 -->
            <dependencies>
                <dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>springloaded</artifactId>
                    <version>1.2.8.RELEASE</version>
                </dependency>
            </dependencies>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>
修改启动Application文件继承SpringBootServletInitializer,实现configure方法
@EnableDiscoveryClient
@SpringBootApplication
public class AppClient extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(AppClient.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(AppClient.class);
    }
}
 修改pom的打包方式
<packaging>war</packaging>
打包后,把target目录下的war包放到tomcat的webapps目录下,启动tomcat,即可自动解压

如果使用的是tomcat7会报java.lang.NoClassDefFoundError: javax/el/ELManager,这可能是因为el-api的版本太低了。在tomcat的lib里面添加javax.el-api-3.0.0.jar即可解决。

访问地址:localhost:{tomcat端口号} /重命名的war包名/xxxx,这里要特别注意,端口是tomcat的端口号

三、优雅停服(针对jar)

首先我们不能使用kill-9。如果加了-9,那么系统就不会给JVM调用 shutdown hook 的机会,也就无法完成资源清理了。也不能使用kill -6 否则无法调用到移除eureka的方法。

spring-boot-starter-actuator中提供了/shutdown的方式来优雅的停止服务,所以在pom.xml中必须加入以下依赖:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

并在全局配置文件中开启shutdown:

#启动所有端点, 也可以设置部分启动, 如:env,beans。默认是health, info
management.endpoints.web.exposure.include=*
## 启用shutdown,优雅停服功能,配置actuator的优雅关闭
## actuator 组件监听shutdown请求地址的时候,要求请求的method必须是POST
## shutdown的请求地址是使用:@PostMapping或@RequestMapping(method=RequestMethod.POST)
management.endpoint.shutdown.enabled=true

服务启动后,可以通过linux的curl命令发送POST请求的方式优雅的停止服务。编写脚本,可命名为:shutdown.sh,内容:

curl -X POST host(ip):port(端口)/actuator/shutdown
# curl -X POST 192.168.178.5:8888/actuator/shutdown
# 返回:{"message":"Shutting down, bye..."}

 

posted @ 2020-03-05 12:45  codedot  阅读(533)  评论(0编辑  收藏  举报