app.jar 的启动
在服务器上启动项目时最简单的启动项目方法是直接执行 java -jar app.jar 命令,或者使用 nohup 进入到后台运行 nohup java -jar app.jar & 。
但是当我们重新部署、重启项目时会比较麻烦,我们需要通过 ps -ef|grep app.jar 来找到我们项目执行时的进程ID PID ,然后再执行 kill -9 $PID 来杀掉当前正在运行的项目,之后再重新运行项目。
虽然只有几个简单的步骤,但还是稍微有点麻烦。整个过程:运行->上传新程序->查找当前程序PID->杀掉当前程序->重新运行,那我们能不能稍微简化一下上述过程,把中间查找PID和杀掉进程这两个不去掉,也把命令简化一下,变成:运行->上传新程序->重新运行 。
手动编写一个启动脚本:run.sh
此时我们最简单的方法就是写一个 SHELL 脚本 run.sh:
1 |
|
以上脚本能够有效的解决我们的问题,但是新问题又来了,如果想查看程序是否运行呢?我们想的肯定是直接执行命令 ps -ef|grep app.jar 查找这个程序是否正在运行,或者把查询运行状态的命令写进我们前面的脚本里面,然后执行 ./run.sh status 查询程序执行状态。
假如我们把查询状态、启动、停止这几个操作都写入到一个脚本中,并提供参数来调用,就需要修改脚本代码,此时我们的脚本是这样的:
1 |
|
此时我们有了四个可以执行的命令:
./run.sh start启动程序./run.sh status查询运行状态./run.sh stop停止运行./run.sh restart重启程序
此时我们就有了4个可以正常使用的命令,但是现在还不能直接设置程序在系统启动的时候随着系统启动,因为还需要做一些配置,最简单的就是修改 /etc/profile 文件加上启动命令,比较麻烦一点就是写一个启动脚本放到系统的 /etc/init.d/ 初始化路径中,然后把脚本加入到系统启动。
但同时我们上面的几个命令看起来是不是非常像Linux系统的系统服务呢?Linux系统服务也是有4个命令:
systemctl start service-name.service启动服务systemctl status service-name.service查询服务运行状态systemctl stop service-name.service停止服务systemctl restart service-name.service重启服务
那我们能不能把它改造成系统服务呢?我们该如何为自己的 SpringBoot 应用编写一个Linux系统服务呢?
service-name.service 示例
以下给出了一个示例 service-name.service 文件:
1 | # http://www.jinbuguo.com/systemd/systemd.unit.html |
service-name.env 文件参考
1 | # service-name 服务运行时环境变量(被 service-name.service 的 EnvironmentFile 加载) |
如何使 service-name.service 生效
该 service-name.service 文件存放在Linux系统的 /lib/systemd/system/ 路径下。
我们可以在我们的项目下存放该 service-name.service 文件,类似于以下目录结构:
1 | / |
然后在Linux系统中的项目路径下,可以通过 ln 把 service-name.service 文件链接到 /lib/systemd/system/ 路径下:
1 | cd project-dir |
接下来我们就可以使用 systemctl 来启动我们的 SpringBoot 应用了
systemctl start service-name.service启动应用systemctl status service-name.service查看应用启动状态systemctl restart service-name.service重启应用systemctl stop service-name.service停止应用
或者使用 service 命令来启动我们的 SpringBoot 应用
service service-name.service start启动应用service service-name.service status查看应用启动状态service service-name.service restart重启应用service service-name.service stop停止应用
service-name.service 解读
以下使用 单元 来表示一个系统服务 service
After=network.target在网卡启动之后启动当前单元Requisite=必须在一个单元启动成功后才启动当前单元Restart=on-failure在异常退出的时候重新启动单元RestartSec=30s重启单元前暂停的时间StandardOutput=null关闭单元的标准输出,实际上也就是抛弃ExecStart命令中在控制台产生的输出、日志记录WorkingDirectory=/app/service-name设置这个单元的工作路径,默认工作在/路径下,设置为存放app.jar的路径,这样可以使SpringBoot应用识别到路径下的配置文件并应用到运行环境中ExecStart=/usr/bin/java -jar /app/service-name/app.jar启动app.jar项目,直接使用java命令来启动,也不用把其放到后台进程中运行
其实还隐含了以下 [Service] 配置,但是并不需要我们进行特殊的配置也能产生相应的作用:
ExecRestart=重启单元时执行的重启应用命令,可以不配置,系统会自动先stop再startExecStop=停止单元时执行的停止应用命令,可以不配置,系统会自动kill掉当前单元中ExecStart运行的进程