Linux使用脚本启动jar/war包(springboot+maven工程jar包)

2 篇文章 0 订阅
2 篇文章 0 订阅

Linux(CentOS7)使用脚本启动java jar/war包


本文以jar包为例(war包是同样的操作流程)。


开始之前,先准备一个jar包

以springboot工程为例。

我打包用的maven。

在pom文件中可以约束最终的jar包名称:
在这里插入图片描述
mvn clear 再然后 mvn install 这些都没什么好说的。


建议以下文件全部放在一个目录下

1、部署jar包

通过xftp或别的方式,将jar包放入服务器某个目录
在这里插入图片描述

2、准备application.yml(springboot工程,如果是别的框架请略过此节)

yml文件放入jar包的同一个目录,内容是常规的springboot-yml文件内容,注意yml格式:
在这里插入图片描述

一会儿启动的时候会以服务器这个yml文件配置的内容为准👆👆👆
而不是项目中的yml文件👇👇👇

在这里插入图片描述

3、准备jvm_opt文件(.file文件)

在这里插入图片描述

此文件内容为java虚拟机启动时的参数:
在这里插入图片描述

配置jvm内存:一般只改abc这三个地方:
a = b 并且 c = a*(2/3)
单位:g 或者 m
如果你怕这么配置有啥问题,你可以临时恶补一下java虚拟机的知识,反正我这儿好几个工具jar包这么配没啥问题。

VM_OPTIONS="-Xms512m -Xmx512m -Xss256K -Xmn384m -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreTouch -XX:-UseLargePages -XX:-UseBiasedLocking"

-Xss根据你的接口或者定时任务的每次调度的数据大小,可以适当增大一些。

4、准备脚本

我这儿命名为boot.sh

先上脚本,文章后面会介绍:怎么用?脚本内容的含义?

#!/bin/bash
APP_NAME=$1
YUM_FILE_PATH=$2

[ -r jvm_opt ] && source jvm_opt   ##检查配置文件存在且可读,则将其souce
VM_OPT=${VM_OPTIONS:-Xms1g -Xmx1g -Xss256K -Xmn600m -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreTouch -XX:-UseLargePages -XX:-UseBiasedLocking}

# 提示输入参数
usage() {
    echo app_name=$APP_NAME vm_opt=$VM_OPT yum=$YUM_FILE_PATH
    echo "Usage: ./boot.sh [APP_NAME] [YML_NAME] [start|stop|restart|status]"
    exit 1
}

# 检查程序是否在运行
is_exist(){
    # 获取PID
    PID=$(ps -ef |grep ${APP_NAME} | grep -v $0 |grep -v grep |awk '{print $2}')
    # -z "${pid}"判断pid是否存在,如果不存在返回1,存在返回0
    if [[ -z "${PID}" ]]; then
        # 如果进程不存在返回1
	echo "进程不存在"
        return 1
    else
        # 进程存在返回0
	echo "进程存在"
        return 0
    fi
}

# 启动方法
start(){
    is_exist
    if [[ $? -eq "0" ]]; then
        echo "${APP_NAME} is already running, PID=${pid}"
    else
        nohup java -jar $VM_OPT -Dspring.config.location=$YUM_FILE_PATH $APP_NAME >log 2>&1 &
		PID=$(echo $!)
        echo "${APP_NAME} start success, PID=$! YUM_FILE_PATH=${YUM_FILE_PATH}"
    fi
}

# 停止方法
stop(){
    is_exist
    if [[ $? -eq "0" ]]; then
        kill -9 ${PID}
        echo "${APP_NAME} process stop, PID=${PID}"
    else
        echo "There is not the process of ${APP_NAME}"
    fi
}

# 重启进程函数
restart(){
    stop
	echo "${APP_NAME} 准备重启..."
	sleep 5
    start
}

# 查看进程状态
status(){
    is_exist
    if [[ $? -eq "0" ]]; then
        echo "${APP_NAME} is running, PID=${PID}"
    else
        echo "There is not the process of ${APP_NAME}"
    fi
}

case $3 in
"start")
        start
        ;;
"stop")
        stop
        ;;
"restart")
        restart
        ;;
"status")
       status
        ;;
	*)
	usage
	;;
esac
exit 0

使用脚本

1、先来到你这几个文件的目录

cd /opt/tools/es-tasks

2、给脚本boot.sh赋予可执行权限:

 chmod 777 boot.sh

777是什么意思?

linux中权限是用二进制表示的。

先看一个控制台的例子:
在这里插入图片描述
看看这一列,第一个位置的 - 或者 d 这种文件描述符咱们先不用看,先从第二个位置的r开始看:
一共有9个位置 rwxrwxrwx 共三组 rwx,分别对应了 三个角色(拥有者、群组、其他人) 对这个文件或文件目录的权限。
“r - -” 就是只有【读】权限,对应二进制的 100
“- w -” 就是只有【写】权限,对应二进制的 010
“- -x” 就是只有【执行】权限,对应二进制的 001
分别翻译成十进制,“r - -” 就是400,"- w -“就是020,”- - x"就是001
那么:

如果是"rw-“就是有【读、写】权限,没有【执行】权限,对应的就是420
如果是"r-x"就是有【读、执行】权限,没有【写】权限,就是401
如果是”-wx"就是有【写、执行】权限,没有【读】权限,对应的就是021(这种设计一般不存在,都能改能执行了,就不能读吗),这里只是说明权限逻辑举例需要。

所以 “rwx” 就是421,而4+2+1=7(777就是从这来的),那么 “chmod 777 file” 这个指令的含义就是:将此文件的【读、写、执行】权限赋予给【拥有者、群组、其他人】这些角色。
当然:
1、如果你只想将此文件的【读、写、执行】权限赋予给【自己】或【自己的群组】,只需要 “chmod 700 file” 或者 “chmod 770 file” 就行。
2、 如果你只想将此文件的【读、写】权限赋予给自己或自己的群组,只需要"chmod 600 file"或者"chmod 660 file"就行了。
3、如果你想让【自己和自己组】拥有【读、写、执行】权限,而【其他人】只能【读】,只需要"chmod 774 file"。

所谓 linux权限,就这么简单。至于用户和用户组,也很简单,阁下可自行查阅其他资料学习,我就不赘述了。

请跟随我回到主题(这篇文章讲啥来着?看看标题,咱们继续)

3、执行命令

启动

./boot.sh xxx.jar application.yml start

停止

./boot.sh xxx.jar application.yml stop

重启

./boot.sh xxx.jar application.yml restart

查看是否在运行

./boot.sh xxx.jar application.yml status

脚本说明(老鸟可以略过这一节)

1、第一句

#!/bin/bash

写在 .sh 脚本文件最开头第一行。
这个是必须要写的,linux系统不同的话,写法上可能会有一丢丢区别,我这里是CentOS7。

2、第二句

APP_NAME=$1
YUM_FILE_PATH=$2

声明了两个变量,指向 $1 和 $2。
$1 对应的是咱们启动命令的:

./boot.sh xxx.jar application.yml start/stop/restart/status

其中的xxx.jar这一部分。
bash解释器是按照空格进行命令的切割,而 xxx.jar 在第【1】位置,所以是$1 (第【0】位置是 ./boot)。
$2同理。
这两句话的意思就是,声明这俩变量,并且让APP_NAME=xxx.jar,让YUM_FILE_PATH=application.yml

3、第三句和第四句

[ -r jvm_opt ] && source jvm_opt

检查这个jvm_opt文件,如果存在并且可读,就把它的内容加载进来。

VM_OPT=${VM_OPTIONS:-Xms1g -Xmx1g -Xss256K -Xmn600m -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreTouch -XX:-UseLargePages -XX:-UseBiasedLocking}

声明一个VM_OPT变量,让它等于后面这个${VM_OPTIONS : …},这里面的VM_OPTIONS就是从jvm_opt文件中取出来的变量。
意思是:如果取到了,就让VM_OPT=VM_OPTIONS,如果没取到,就让VM_OPT等于冒号后面的这一长串值。

4、接下来就是六个自定义方法(也叫函数)

第一个方法,用于提示
usage() {
    echo app_name=$APP_NAME vm_opt=$VM_OPT yum=$YUM_FILE_PATH
    echo "Usage: ./boot.sh [APP_NAME] [YML_NAME] [start|stop|restart|status]"
    exit 1
}

此方法在脚本被非正常执行时触发,比如说你./boot.sh start就想执行,xxx.jar也不写
那它就提示你 “Usage: ./boot.sh [APP_NAME] [YML_NAME] [start|stop|restart|status]” 一个正常命令格式是什么。

第二个方法,用于判断是否已经在运行
is_exist(){
    # 获取PID
    PID=$(ps -ef |grep ${APP_NAME} | grep -v $0 |grep -v grep |awk '{print $2}')
    # -z "${pid}"判断pid是否存在,如果不存在返回1,存在返回0
    if [[ -z "${PID}" ]]; then
        # 如果进程不存在返回1
        echo "进程不存在"
        return 1
    else
        # 进程存在返回0
        echo "进程存在"
        return 0
    fi
}
第三个方法,用于启动jar包
start(){
    is_exist
    if [[ $? -eq "0" ]]; then
        echo "${APP_NAME} is already running, PID=${pid}"
    else
        nohup java -jar $VM_OPT -Dspring.config.location=$YUM_FILE_PATH $APP_NAME >log 2>&1 &
                PID=$(echo $!)
        echo "${APP_NAME} start success, PID=$! YUM_FILE_PATH=${YUM_FILE_PATH}"
    fi
}

其中,"is_exist"是调用了上面讲的第二个方法。
然后拿着 is_exist() 方法运行的结果(0或者1)来决定要不要启动。
这一段脚本总体意思也很简单,判断进程是否已经存在,如果存在就提示;不存在就静默启动,启动完了提示success。

其中:

nohup java -jar $VM_OPT -Dspring.config.location=$YUM_FILE_PATH $APP_NAME >log 2>&1 &

这一段就是在启动了。 “>” 代表输出,log代表同级目录下的日志文件log.file,如果启动后log文件不存在则会自动创建。
">log"意思是把程序的输出内容写到log这个文件中去。

顺便提一嘴奥

一个 > 号 “>”
会把之前的覆盖掉,也就是说,每次重启jar包,之前log中的内容就没了。
好处也很明显,不会造成文件膨胀,排查本次启动后问题时也会很方便。

两个 > 号 “>>”
在之前的文件内容的基础上,不断追加新的内容。

我springboot工程一般都用到日志框架,这些框架会把日志,按日期写入某个文件夹内的一个个文件中去,所以我一般脚本这个位置写 一个">“符号,也就是”>log"

继续看这段脚本:

nohup java -jar $VM_OPT -Dspring.config.location=$YUM_FILE_PATH $APP_NAME >log 2>&1 &

“2>&1” 意思是 把程序的 标准错误输出 也重定向到 标准输出。

在linux中,标准输入用0表示,标准输出用1表示,标准错误输出用2表示。

最后一个 “&” 代表静默启动,“别占用我控制台一直打印” 就这个意思。

第四个方法,用于停止jar包
stop(){
    is_exist
    if [[ $? -eq "0" ]]; then
        kill -9 ${PID}
        echo "${APP_NAME} process stop, PID=${PID}"
    else
        echo "There is not the process of ${APP_NAME}"
    fi
}

非常好理解:进程存在否?存在就杀掉进程然后提示;不存在就直接提示。

第五个方法,用于重启jar包
restart(){
    stop
        echo "${APP_NAME} 准备重启..."
        sleep 5
    start
}

也很好理解:先停止,睡5秒,再启动。

第六个方法,查看运行状态
status(){
    is_exist
    if [[ $? -eq "0" ]]; then
        echo "${APP_NAME} is running, PID=${PID}"
    else
        echo "There is not the process of ${APP_NAME}"
    fi
}

这个就不用说了,只是调用了一下 is_exist() 方法然后根据0或1的返回,给我们提示运行状态而已。

脚本的最后一段

case $3 in
"start")
        start
        ;;
"stop")
        stop
        ;;
"restart")
        restart
        ;;
"status")
       status
        ;;
        *)
        usage
        ;;
esac
exit 0

前面讲过,$3就是咱们启动命令:

./boot.sh xxx.jar application start/stop/restart/status

其中的 start / stop / restart / status 这个部分。

脚本根据我们输入的其中一个选项,执行不同的方法。

" *)usage ;; " 的意思是我们输入的东西不在【start / stop / restart / status】这个范围内,就会走 usage() 方法,也就是提示我们正常的格式。

“esac” 就是 “case” 反过来写,是脚本中的一种语法,类似于【 " if " 与 " fi "】。

“exit 0” 意思是运行正常退出脚本程序。

jar包运行后的log日志怎么看?

我一般用这几个命令

1、实时查看100行日志

tail -100f log

2、搜索日志中内容

more log

然后敲 “/”
再然后输入你要搜索的内容,回车。
如果输入错了,按 ctrl + backspace(退格) 往前删。

写在最后

简单好用,相当于一个雏形,支持高度diy。
但是要小心,别在脚本中写自己拿不准的指令。

diy举例

比如说你就想用springboot工程resources下的那个yml配置,不愿意把它提取出来,脚本改起来也很简单,只要找到 $, 把 $ 后面的数字改成你命令中对应的位置就ok。
比如:

vi boot.sh

先删掉 YUM_FILE_PATH=$2 这个变量(所有引用到这个变量的地方也给改改好奥)
把脚本最后的

case $3 in …

其中的$3

改成你 start/stop/restart/status 这个指令的位置

假如说你指令是这么写的:

./boot.sh xxx.jar start

那就把./boot.sh脚本中的所有 $3 改成 $2。
很明显嘛,你变短了,数字也就变少了。

话说回来,稍微有点规模的项目一般也用不着这玩意,docker、k8s集群部署会更省心。
就有时候一些工具类的小玩意用一下还是蛮不错的。


ok,完活!

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Linux 环境中,你可以使用 Shell 脚本来自动化执行 Git 拉取 Spring Boot 项目的操作,并将其打WAR 文件。以下是一个示例的 Shell 脚本: ```bash #!/bin/bash # 进入项目目录 cd /path/to/your/project # 拉取最新代码 git pull # 编译项目 javac -d target/classes src/main/java/*.java # 复制静态资源文件 cp -r src/main/resources/* target/classes/ # 创建 WEB-INF 目录并复制编译后的类文件 mkdir -p target/WEB-INF/classes cp -r target/classes/* target/WEB-INF/classes/ # 创建 web.xml 文件(根据实际需求自定义内容) echo '<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>Your Project</display-name> </web-app>' > target/WEB-INF/web.xml # 打WAR 文件 jar -cvf yourproject.war -C target . # 清理编译生成的文件 rm -rf target/classes target/WEB-INF echo "WAR 文件生成完成" ``` 在脚本中,你需要将 `/path/to/your/project` 替换成你实际的项目路径。执行该脚本后,它会自动拉取最新的代码,编译项目,复制静态资源文件,创建部署描述文件(`web.xml`),然后将项目打WAR 文件(`yourproject.war`)。最后,在完成打后,会打印出 "WAR 文件生成完成" 的提示信息。 请确保在执行脚本之前,已经正确安装了 Git、Java 和 Maven,并且配置了正确的环境变量。另外,根据你的项目需求,你可能需要根据实际情况进行一些调整和配置。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值