今天下午为这篇文章做提纲的时候,听到程璧的《我想和你虚度时光》,心底出现一种感觉,那就是做喜欢的事儿或者和自己喜欢的人待在一起,哪怕时间被浪费了,也会很开心,也不会有任何怨言。人这一生最可怕的就是被责任绑架。
虚度,我还要这样。想和你互相浪费,一起虚度短的沉默长的无意义,一起消磨精致而苍老的宇宙。
0 前言
在上一篇文章中,我们实现了一个接口,并通过本地运行的方式将项目运行起来并且成功访问。那我们如何在服务器上运行我们的项目呢?
1 如何部署SpringBoot项目
一般来说,一个Spring项目的运行可以打包成jar通过java -jar xxxx.jar来运行,也会选择打包成war借助容器来运行。
下面我们总结一下到目前为止常用的打包部署方式。
1.0 传统jar
在上一篇文章的基础上我们可以通过点击Idea 的Maven工具栏中的package指令进行编译打包,最终会在项目的target目录中生成 s001-0.0.1-SNAPSHOT.jar文件,之后我们就可以上传这个文件到服务器使用java -jar s001-0.0.1-SNAPSHOT.jar进行运行。
手动运行jar常见的方式有如下几种
# 直接运行,结束ssh会话时项目也会关闭
java -jar s001-0.0.1-SNAPSHOT.jar
# 使用 setsid 将java进程放置后台(该方式虽然在后台运行了java项目,但是会将输出流重定向到当前会话)
setsid java -jar s001-0.0.1-SNAPSHOT.jar
#使用 nohub + & 将java进程放置后台(会将输出重定向到文件 nohup.out)
nohup java -jar s001-0.0.1-SNAPSHOT.jar &
#使用 nohub + & 将java进程放置后台(不生成文件的方式)
nohup java -jar s001-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &
我们可以看到项目在8080端口成功运行了,我们就可以通过网页请求到我们写好的接口。
tips: 这里需要提前在服务器安装 Java运行环境(需要和项目编辑环境匹配,当前Demo项目需要先安装 jdk 17),同时需要在服务器放通需要的端口(后续文章会详细讲解)。
1.1 war
在我们的s001的基础上要改成war部署方式需要修改pom.xml文件 添加
<!-- 在 project 节点下新增,指定打包方式为 war -->
<packaging>war</packaging>
<!-- 在 dependencies 节点下新增,用于在打包war的时候排出项目内依赖的tomcat相关包,同时又不影响 开发环境无tomcat的运行方式 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
在 S001Application 类下新增 S001ServletInitializer 用于tomcat运行
package com.itranlin.blog.example.s001;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* @author : itranlin
* @since : 2023/1/3 23:25
*/
public class S001ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
builder.sources(S001Application.class);
return super.configure(builder);
}
}
使 S001Application 继承 S001ServletInitializer
package com.itranlin.blog.example.s001;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author itranlin
* @since : 2022/12/31 20:05
*/
@SpringBootApplication
public class S001Application extends S001ServletInitializer{
public static void main(String[] args) {
SpringApplication.run(S001Application.class, args);
}
}
使用maven 的package 打包之后将war放到tomcat的apps目录下启动tomcat
之后我们就能访问到我们的接口啦!
1.2 docker
1.2.0 直接打包到目标docker环境
如果docker与代码在同一位置(指同一计算机),则可以直接通过maven运行
mvn spring-boot:build-image
就能在本机的docker中生成对应的image
当出现
Successfully字样的时候就表示生成镜像了
1.2.1 发布到私有docker仓库
将S001项目发布到docker仓库仅需要在pom.xml文件中添加几行配置,如下
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<!-- 关键配置 {仓库域名}/{项目组}/{项目名}:{tag} -->
<name>docker.nexus.oracle.itranlin.com/demo-blog/${project.artifactId}</name>
<!-- 需要发布 -->
<publish>true</publish>
</image>
<docker>
<publishRegistry>
<!-- 私有库账号 -->
<username>itranlin</username>
<!-- 私有库密码 -->
<password>xxxxxxx</password>
</publishRegistry>
</docker>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
然后运行
mvn spring-boot:build-image
当出现如图所示
BUILD SUCCESS字样的时候则表示发布成功了
将项目发布到docker或私有库之后就可以简单通过docker命令进行项目运行了
docker run --name s001 -d -it -p 8080:8080 docker.nexus.oracle.itranlin.com/demo-blog/s001:0.0.1-SNAPSHOT
1.3 executable Jar
该方式与第一种方式没有本质上的却别,只是在运行项目的时候可以省略 命令中的java -jar部分,而实现这种方式只需要在maven的配置文件中添加一个配置即可。
打包上传服务器后就可以直接把它当作可是执行文件来运行。
tips: 这里与第一种方式一样需要提前在服务器安装 Java运行环境(需要和项目编辑环境匹配,当前Demo项目需要先安装 jdk 17),同时需要在服务器方通需要的端口(后续文章会详细讲解)。
1.4 对于Jar和executable Jar在Linux中的一些其他玩法
在本文中介绍了常用的jar的启动方式,对于启动jar的项目个人建议将它注册成系统服务,这样在一定程度上减少运维的工作量的同时也稍微提高了一点点高可用。
在系统的/etc/systemd/system中新建文件s001.service并将一下内容写入文件
[Unit]
Description=myapp
After=syslog.target
[Service]
User=root
# 此处为实际运行项目的命令,如果是executable Jar则不用写java -jar
ExecStart=java -jar /root/blog-test/s001-0.0.1-SNAPSHOT.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
然后使用下面命令将其设置为开机自启
systemctl enable s001
再使用下面命令运行项目
systemctl start s001