视频加载失败

【Linux】Linux环境下运行jar包的几种方式

2309 字
12 分钟
【Linux】Linux环境下运行jar包的几种方式

方式一(java -jar jar包名)#

Terminal window
# 命令格式:java -jar jar包名
[root@localhost test_jar]# java -jar test_jar-1.0-SNAPSHOT.jar

分析: 执行此命令的时候,当前窗口被锁定,无法进行其它操作,直到main方法执行完毕,当前窗口才解除锁定。
缺点: 锁定窗口。当然,我可以通过CTRL + C打断程序运行,或直接关闭窗口,程序退出,不过在实际的工作环境中,是绝对不会允许这种粗暴的方式终止的运行,毕竟我们的项目都是给用户提供服务的,程序要是退出了,公司还营不营业了。

方式二(java -jar jar包名 &)#

Terminal window
命令格式:java -jar jar包名 &
[root@localhost test_jar]# java -jar test_jar-1.0-SNAPSHOT.jar &

分析: &代表在后台运行。优点是当前ssh窗口不被锁定,但是当窗口关闭时,程序终止运行。
那么我们就会想,如何继续改进,让窗口关闭时,程序仍然运行呢?

方式三#

方式三主要是引入nohup命令,具体使用主要包括下面三种方式。

命令格式:nohup java -jar jar包名 &#

Terminal window
# 命令格式:nohup java -jar jar包名 &
[root@localhost test_jar]# nohup java -jar test_jar-1.0-SNAPSHOT.jar &

nohup 意思是不挂断运行命令 ,当账户退出或终端关闭时,程序仍然运行。
当用 nohup 命令运行jar包时,缺省情况下该应用的所有输出被重定向到nohup.out的文件中,除非另外指定了输出文件。

命令格式:nohup java -jar jar包名 > 文件名 &#

Terminal window
# nohup java -jar jar包名 > 文件名 &
[root@localhost test_jar]# nohup java -jar test_jar-1.0-SNAPSHOT.jar > test.txt &

command >test.file 是将commandd test.flie文件,即输出内容不打印到屏幕上,而是输出到 test.file文件中

命令格式: nohup java -jar jar包名 >output 2>&1 &#

Terminal window
# nohup java -jar jar包名 >output 2>&1 &
[root@localhost test_jar]# nohup java -jar test_jar-1.0-SNAPSHOT.jar >output 2>&1 &

命令格式:nohup java -jar spring-boot-demo.jar > /dev/null 2>&1 &#

不输出日志

方式四:脚本方式#

#!/bin/bash
#这里可替换为你自己的执行程序,其他代码无需更改
APP_NAME=test_jar-1.0-SNAPSHOT.jar
#使用说明,用来提示输入参数
usage() {
echo "Usage: sh 脚本名.sh [start|stop|restart|status]"
exit 1
}
#检查程序是否在运行
is_exist(){
pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' `
#如果不存在返回1,存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
#启动方法
start(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is already running. pid=${pid} ."
else
nohup java -Xmx512m -Xms512m -jar $APP_NAME > ./logs/`log+%Y-%m-%d`.txt 2>&1 &
echo "${APP_NAME} start success"
fi
}
#停止方法
stop(){
is_exist
if [ $? -eq "0" ]; then
kill -9 $pid
else
echo "${APP_NAME} is not running"
fi
}
#输出运行状态
status(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is running. Pid is ${pid}"
else
echo "${APP_NAME} is NOT running."
fi
}
#重启
restart(){
stop
start
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac

附录一: nohup 和 &#

使用 & 后台运行程序:

  • 结果会输出到终端
  • 使用Ctrl + C,程序免疫
  • 关闭session,程序关闭

使用nohup运行程序

  • 结果默认会输出到nohup.out
  • 使用Ctrl + C,程序关闭
  • 关闭session,程序免疫

平日线上经常使用nohup和&配合来启动程序

附录二:> /dev/null 2>&1#

  • > 标准重定向符,允许我们创建一个 0KB的空文件。它通常用于重定向一个命令的输出到一个新文件中。在没有命令的情况下使用重定向符号时,它会创建一个文件。
  • /dev/null 可以看作黑洞,等价于一个只写文件。所有写入它的内容都会永远丢失,尝试从它那儿读取内容则什么也读不到。也就是将所有产生的日志将被丢弃
  • 2>&1符号>&是一个整体代表将标准错误2重定向到标准输出1,如果是2>1的话,代表将标准错误输出到文件1,而不是重定向到标准输出流

先了解下1和2在Linux中代表什么
当Linux执行一个程序时,会自动打开三个流

  • 0:标准输入流(默认是键盘)
  • 1:标准输出流(默认是屏幕)
  • 2:标准错误流(默认是屏幕)
名称代码操作符java中表示Linux中文件描述符
标准输入(stdin)0< 或 <<System.in/dev/stdin -> /proc/self/fd/0 -> /dev/pts/0
标准输出(stdout)1>, >>, 1> 或 1>>System.out/dev/stdout -> /proc/self/fd/1 -> /dev/pts/0
标准错误输出(stderr)22> 或 2>>System.err/dev/stderr -> /proc/self/fd/2 -> /dev/pts/0

批量启动、停止jar包#

#!/bin/bash
# 端口号
PORTS=(9500 9600 9801 9802 9803 9804 9805 9901 9902)
# 系统模块
MODULES=(gateway auth system job gen file risk supervise ssologin)
# 系统模块名称
MODULE_NAMES=(网关模块 鉴权模块 系统管理模块 定时任务模块 代码生成模块 文件管理模块 风险预警模块)
# jar包数组
JARS=(catsticloud-gateway.jar catsticloud-auth.jar catsticloud-modules-system.jar catsticloud-modules-job.jar catsticloud-modules-gen.jar catsticloud-modules-file.jar catsticloud-modules-risk.jar catsticloud-supervise.jar catsticloud-modules-ssologin.jar)
# jar包路径
JAR_PATH='/home/yunwei/gonggonganquan/jar'
# 日志路径
LOG_PATH='/home/yunwei/gonggonganquan/jar/logs'
start() {
local MODULE=
local MODULE_NAME=
local JAR_NAME=
local command="$1"
local commandOk=0
local count=0
local okCount=0
local port=0
for((i=0;i<${#MODULES[@]};i++))
do
MODULE=${MODULES[$i]}
MODULE_NAME=${MODULE_NAMES[$i]}
JAR_NAME=${JARS[$i]}
PORT=${PORTS[$i]}
if [ "$command" == "all" ] || [ "$command" == "$MODULE" ];then
commandOk=1
count=0
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
if [ -n "$PID" ];then
echo "$MODULE---$MODULE_NAME:已经运行,PID=$PID"
else
exec nohup java -jar $JAR_PATH/$JAR_NAME > /dev/null 2>&1 &
PID=`netstat -apn | grep $PORT | awk '{print $7}' | cut -d/ -f 1`
while [ -z "$PID" ]
do
if (($count == 30));then
echo "$MODULE---$MODULE_NAME:$(expr $count \* 10)秒内未启动,请检查!"
break
fi
count=$(($count+1))
echo "$MODULE_NAME启动中.................."
sleep 10s
PID=`netstat -apn | grep $PORT | awk '{print $7}' | cut -d/ -f 1`
done
okCount=$(($okCount+1))
echo "$MODULE---$MODULE_NAME:已经启动成功,PID=$PID"
fi
fi
done
if(($commandOk == 0));then
echo "第二个参数请输入:all|gateway|auth|system|job|gen|file|risk|supervise|ssologin"
else
echo "............本次共启动:$okCount个服务..........."
fi
}
stop() {
local MODULE=
local MODULE_NAME=
local JAR_NAME=
local command="$1"
local commandOk=0
local okCount=0
for((i=0;i<${#MODULES[@]};i++))
do
MODULE=${MODULES[$i]}
MODULE_NAME=${MODULE_NAMES[$i]}
JAR_NAME=${JARS[$i]}
if [ "$command" = "all" ] || [ "$command" = "$MODULE" ];then
commandOk=1
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
if [ -n "$PID" ];then
echo "$MODULE---$MODULE_NAME:准备结束,PID=$PID"
kill -9 $PID
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
while [ -n "$PID" ]
do
sleep 3s
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
done
echo "$MODULE---$MODULE_NAME:成功结束"
okCount=$(($okCount+1))
else
echo "$MODULE---$MODULE_NAME:未运行"
fi
fi
done
if (($commandOk == 0));then
echo "第二个参数请输入:all|gateway|auth|system|job|gen|file|risk|supervise|ssologin"
else
echo "............本次共停止:$okCount个服务............"
fi
}
status() {
local MODULE=
local MODULE_NAME=
local JAR_NAME=
local command="$1"
local commandOk=0
local count=0
local okCount=0
local port=0
for((i=0;i<${#MODULES[@]};i++))
do
MODULE=${MODULES[$i]}
MODULE_NAME=${MODULE_NAMES[$i]}
JAR_NAME=${JARS[$i]}
PORT=${PORTS[$i]}
if [ "$command" == "all" ] || [ "$command" == "$MODULE" ];then
commandOk=1
count=$(($i+1))
PID=`ps -ef |grep $(echo $JAR_NAME | awk -F/ '{print $NF}') | grep -v grep | awk '{print $2}'`
if [ -n "$PID" ];then
echo "$MODULE---$MODULE_NAME:已经运行,PID=$PID"
okCount=$(($okCount+1))
else
echo "$MODULE---$MODULE_NAME:未运行"
fi
fi
done
if(($commandOk == 0));then
echo "第二个参数请输入:all|gateway|auth|system|job|gen|file|risk|supervise|ssologin"
else
echo "............共:$count 个服务,运行中$okCount个服务..........."
fi
}
case "$1" in
start)
start "$2"
;;
stop)
stop "$2"
;;
status)
status "$2"
;;
restart)
stop "$2"
sleep 3s
start "$2"
;;
*)
echo "第一个参数请输入:start|stop|restart|status"
exit 1
;;
esac

启动:

Terminal window
## 启动所有
./start.sh start all
## 停止所有
./start.sh stop all
## 重启所有
./start.sh restart all
## 启动某一个 这里的gateway与sh中的module中定义的一样即可
./start.sh restart gateway

问题1:-bash: ./start.sh: Permission denied\ 原因: 无权限 解决方法: chmod +x ./文件名.sh

问题2:bad interpreter\:No such file or directory的错误

原因: .sh脚本在windows系统下编写的,所以可能有不可见字符,从上图错误提示来看,很有可能脚本文件是DOS格式的,即每一行的行尾以\r\n来标识, 其ASCII码分别是0x0D, 0x0A。 解决方法:

  • 通过vim filename 或者vi filename 进入编辑,即我这是vim startup\_heartbeat.sh
  • 然后通过shift+:进入命令模式。接着通过命令set ff 或者 set fileformat 查看文件格式,即我这如下图:从中可以看到我这文件格式是dos
  • 修改文件格式dos为unix。通过命令set ff=unixset fileformat=unix修改,然后再执行set ff 或者 set fileformat,查看是否修改成功。即如下图所示
  • 启动命令,发现正常启动,至此完毕。

服务开机自启#

一、新建jar包启动sh文件 新建startup.sh脚本文件,启动项目jar包

nohup java -jar test.jar >/dev/null 2>&1 &

二、设置自动启动命令 1.进入rc.d目录 执行cd /etc/rc.d 命令,进入rc.d目录

如图所示(示例):

2.修改rc.local文件内容 执行命令 vi rc.local,然后按下键盘上的【i】键进入修改模式

在末尾加上如下命令:

Terminal window
#进入项目目录
cd /home/test`
#执行sh文件
sh /home/test/startup.sh

然后先按下【esc】键,再按下【:】键,在光标闪烁处输入:wq。按回车,完成修改后,执行相应命令,设置执行权限,重启服务器,验证即可。

Terminal window
chmod +x /etc/rc.d/rc.local
chmod +x /home/test/startup.sh

有时服务器重启服务很多时,可能需要延迟启动,可以在之前的命令前加上sleep 60命令延迟启动

Terminal window
sleep 60
cd /home/test
sh /home/test/startup.sh

服务方式启动#

Terminal window
可以添加一个 systemd的服务 基本上可以如图进行设置
一般位于 /etc/systemd/system/ 下面
比如可以建立一个文件为 app.service
可以使用 systemctl enable app 设置开机自动启动
然后使用systemctl start app 来启动服务
Terminal window
[Unit]
Description = Redis Server
After = network.target
[Service]
ExecStart=/app/startup.sh
ExecStop=/usr/bin/kill -15 $MAINPID
Restart = always
[Install]
WantedBy = multi-user.target

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
【Linux】Linux环境下运行jar包的几种方式
https://blog.huhaha.vip/posts/bf223232/
作者
小王的博客
发布于
2024-05-21
许可协议
CC BY-NC-SA 4.0
相关文章智能推荐
1
Linux系统Tomcat启动指定JDK版本
Linux在linux系统上启动tomcat指定jdk版本,多版本环境
2
【Linux】manjaro 环境配置
Linux本文《Manjaro 环境配置》详细介绍了在Manjaro Linux系统中进行环境配置的各种方法。文章首先介绍了常用的Pacman包管理命令,包括软件的安装、更新、删除等操作。这些内容对于初学者和有一定经验的用户都非常有帮助,能够快速搭建一个高效、美观的Manjaro环境。
3
【Linux】Libgdiplus安装
Linux在CentOS 7上安装libgdiplus的过程,以解决ASP.NET Core MVC项目在处理图片时遇到的The type initializer for ‘Gdip‘ threw an exception错误。首先,通过安装yum-utils和epel-release来获取必要的工具和仓库支持。
4
【Linux】Nacos 问题
Linux本文《【Linux】Nacos 问题》详细记录了在Linux环境下遇到的Nacos服务连接问题及其解决方法。文章还介绍了如何配置Nacos服务的开机自启动,确保服务在系统重启后能够自动运行。这些内容对解决Nacos连接问题和提高系统稳定性非常有帮助。
5
【Linux】常用命令
Linux本文档《【Linux】常用命令》详细列出了Linux系统中常用的命令及其用法,涵盖了从基本命令、关机操作、文件和目录管理、文件搜索、文件系统的挂载与卸载、磁盘空间管理、文件权限设置、文件的特殊属性、打包和压缩文件、RPM包管理、YUM软件包升级器、DEB包管理、查看文件内容、文本处理、字符设置和文件格式转换等操作。
随机文章随机推荐

评论区

Profile Image of the Author
小王的博客
一个上了年纪的猿人.
分类
标签
最新动态
站点统计
文章
209
分类
15
标签
161
总字数
478,322
运行时长
0
最后活动
0 天前
站点信息
构建平台
Vercel
博客版本
Firefly v6.16.7
文章许可
CC BY-NC-SA 4.0
文章目录