1、文章背景

17年左右刚参加工作时的时候接触的第一个项目是采用SSM开发的,那个时候公司项目一般的部署方式为打war包放到tomcat上,使用tomcat bin下的各种脚本去管理tomcat服务。后来主流开发渐渐的往的springboot靠拢,从之前的打war包上传tomcat中到打jar包直接运行。这中间我一直感觉很不方便,一直在找一种比较方便的单包小项目管理方案。

2、jar包管理1.0

刚接触springboot时,网上的各种博文都是教你使用nohup去管理。

nohup java -jar xxx.jar -jvm parameter &

nohup:英文全称no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。 nohup 命令,在默认情况下(非重定向时),会输出一个名叫nohup.out 的文件到当前目录下,如果当前目录的nohup.out 文件不可写,输出重定向到$HOME/nohup.out 文件中。

这样有一个问题就是:你需要记住每个jar包的放置位置,每次操作都要先进到这个目录。并且需要额外的保护措施来避免服务死掉之后无法自行恢复。

3、jar包管理2.0

spring官网有一个文档叫做 Deploying Spring Boot Applications 这里面的2.2.2. Installation as a systemd Service中介绍了如何将jar作为系统服务去运行,他提供的例子比较简单。

[Unit]
Description=myapp
After=syslog.target

[Service]
User=myapp
ExecStart=/var/myapp/myapp.jar
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

我们可以参考这个 文档 根据需要去填充你的.service文件。
service文件配置完成之后需要执行

systemctl daemon-reload #刷新服务

systemctl start/stop/restart xxx.service #启动停止重启服务

这里还有一个比较好用的功能:比如我们的jar放在/usr/local/app/xxx.jar
我们只要在此jar包同目录下创建xxx.conf即/usr/local/app/xxx.conf,这个文件就可以作为环境变量配置文件,可以export你想要的环境变量,配合项目yml中${ENV_KEY}使用。例如:

export SERVER_ACTIVE=prod
export SERVER_PORT=8080
export DB_HOST=172.17.20.7
export DB_PORT=65432
export JAVA_OPTS="-Xmx5440M -Xms5440M -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M -XX:+UseG1GC -XX:MaxGCPauseMillis=100"

⚠️⚠️⚠️ pom.xml文件中spring-boot-maven-plugin的配置块中需要配置executable可执行为true。整体修改后的效果类似这样:

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.8</version>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>

4、优化jar包大小

在构建单jar包时,因为所有的依赖和代码都构建到一个jar包中导致容量过大,并且在项目迭代时依赖一般没有很大的改动,所以就需要配置maven将依赖和代码分开构建,这样每次构建出的代码包只有不到1M的大小,能很方便的上传。依赖有增删的可以直接在依赖文件夹中操作。

补充:

pm2或同类型进程管理工具(supervisor等)

pm2是一个nodejs的进程管理工具,可以很方便的管理nodejs进程,但是也可以管理java进程。pm2的安装和使用可以参考 pm2官网 。pm2的优点是可以很方便的管理多个进程,下面简单讲一下安装和使用。

# 安装nvm 用来安装和管理nodejs
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash
# 安装nodejs
nvm install node
# 全局安装pm2
npm install pm2 -g
# 根据回显信息执行命令后可以配置pm2自启动
pm2 startup

安装完成后,如果是守护不太复杂的可执行程序可以直接 pm2 start ./program --name name -- --arg arg,–后面的参数会传递进去。

如果是java这种启动比较复杂的程序,可以先写个js文件,然后通过 pm2 start app.js 来启动。

# 写app.js
{
"name": "app",
"script": "/usr/bin/java", # java可执行文件路径
"args": [
"-jar",
"/usr/local/app.jar", # jar包路径
"--spring.profiles.active=prod"
],
"exec_interpreter": "",
"exec_mode": "fork",
"error_file" : "/var/logs/app-error.log",
"out_file" : "/var/logs/app.log"
}

常用命令:

pm2 list # 查看当前所有进程的状态
pm2 start app # 启动app进程
pm2 stop app # 停止app进程
pm2 restart app # 重启app进程
pm2 delete app # 删除app进程
pm2 monit # 查看当前所有进程的资源占用情况
pm2 log # 查看当前所有进程的日志

pm2还有很多功能,比如:负载均衡、日志分割、可视化监控等,可以根据自己的需求去官网学习使用。