本文讲解如何部署Spring Boot。
微信搜索关注《Java学研大本营》,加入读者群,分享更多精彩
Spring Boot 应用程序可以通过各种方法部署到生产系统中。在本文中,我们将通过以下 4 种方法逐步部署 Spring Boot 应用程序:
-
作为独立应用程序部署在 Java Archive (JAR) 中
-
部署在 Docker 容器中
-
部署在 NGINX Web 服务器后面——直接设置
-
在 NGINX Web 服务器后面部署——容器化设置
在 Java Archive (JAR) 中作为独立应用程序部署
Spring Boot 应用程序可以轻松打包到 JAR 文件中并作为独立应用程序部署。这是由spring-boot-maven-plugin完成的。创建 Spring 项目后,插件会自动添加到 pom.xml。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
要将应用程序打包到单个(fat)jar 文件中,请mvn package
在项目目录下运行 maven 命令。这会将应用程序打包到一个可执行的 jar 文件中,其中包含其所有依赖项(包括嵌入式 servlet 容器——如果它是一个 Web 应用程序)。要运行 jar 文件,请使用以下标准 JVM 命令java -jar <jar-file-name>.jar
。
在 Docker 容器中部署
在将应用程序部署到 Docker 容器之前,我们将首先将应用程序打包在一个(fat)JAR 文件中。这个过程前面已经解释过了,因此我假设我们有一个 jar 文件。
第一步,我们需要构建一个容器镜像。为此,我们首先在项目根目录中创建一个Dockerfile,如下所示:
# latest oracle openjdk is the basis
FROM openjdk:oracle
# copy jar file into container image under app directory
COPY target/demoApp.jar app/demoApp.jar
# expose server port accept connections
EXPOSE 8080
# start application
CMD ["java", "-jar", "app/demoApp.jar"]
请注意,在上面的代码片段中,我们假设应用程序 JAR 文件“ demoApp.jar”位于我们项目的目标目录下。我们还假设嵌入式 servlet 端口是 8080(这是 Tomcat 的默认情况)。
我们现在可以使用以下命令(从 Dockerfile 所在的位置)构建 Docker 映像:
docker image build -t demo-app:latest .
-t要构建的图像的名称和标签在哪里。构建镜像后,我们可以通过以下方式创建和运行容器:
docker container run -p 8080:8080 -d --name app-container demo-app
-p
将主机端口发布(映射)到容器端口(在这种情况下都是 8080)。选项-d
(分离)在后台运行容器,并--name
指定容器的名称。
部署在 NGINX Web 服务器后面——直接设置
配置 servlet 容器(如 Tomcat 或 Jetty)用于实际生产(即在端口 80 上运行,没有 root 用户和 SSL)可能不是直截了当的(但可行)。因此,建议在您的 Spring Boot 应用程序前使用 Web 服务器(例如 Nginx)。这可以通过两种方式完成;直接设置或容器化设置。在本节中,我们将演示直接设置。
在直接设置中,我们直接在 localhost 上运行 Nginx Web 服务器和 Spring Boot 应用程序(当然在不同的端口上)。我们让 Ngnix 将 REST 请求代理到 Spring Boot 应用程序。为了这:
-
通过在 Linux 上安装 Nginx Web 服务器
sudo apt-get install nginx
-
用文本编辑器打开文件
/etc/ngnix/sites-available/default
-
假设我们有两个 Spring Boot 应用程序需要代理。然后将文件中的“位置”块替换为两个 Spring Boot 应用程序的以下块。请注意,所有 Nginx-Java 配置都可以在这里找到。(https://www.nginx.com/resources/wiki/start/topics/examples/javaservers/)
location /app1 {
proxy_pass http://localhost:8080;
}location /app2 {
proxy_pass http://localhost:9000;
}
基于此,来的请求http://localhost/app1/
将被定向到/http://localhost:8080/
,来的请求http://localhost/app2/
将被定向到/http://localhost:9000/
。
负载均衡
如果您正在运行 Spring Boot 应用程序的多个实例,则可以启用 Nginx 以应用负载平衡。例如,如果我们有 3 个 app1 实例在端口 8080、8081 和 8082 上运行。我们可以在这些服务器之间进行负载均衡,如下所示:
打开文件/etc/ngnix/sites-available/default
并在文件顶部添加以下块(在服务器块之前):
# configure load-balancing
upstream backend {
server localhost:8080;
server localhost:8081;
server localhost:8082;
}
修改app1的proxy_pass参数如下:
location /app1 {
proxy_pass http://backend;
}
基于此,请求将http://localhost/app1/
被定向到或之一。/http://localhost:8080/
,/http://localhost:8081/
,/http://localhost:8082/
。
在 NGINX Web 服务器后面部署——容器化设置
在容器化设置中,我们将 Nginx Web 服务器和所有 Spring Boot 应用程序部署在单独的 Docker 容器上。我们让 Nginx(在自己的容器中运行)代理 REST 请求到 Spring Boot 应用程序容器。
我们首先将所有 Spring Boot 应用程序打包在(fat)jar 文件中(前面已经解释过)。此时,请注意通过在application.properties(或application.yml)文件中添加以下行来为每个 Spring Boot 应用程序设置单独的服务器端口和根上下文路径:
server.port=8082
server.servlet.context-path=/search-service
然后我们将生成的 jar 包部署在单独的 Docker 容器中(前面也解释过)。
例如,我们部署了四个 Spring Boot 应用程序;“分析服务”应用程序的单个实例和“搜索服务”应用程序的三个实例。搜索服务应用程序的三个实例将由 Nginx 进行负载平衡。我们的基本架构如下所示:
我们根据默认配置创建一个 Nginx 配置文件nginx.conf 。我们为每个服务添加负载平衡和代理信息,如下所示:
http {
upstream backend {
server search-service-1:8080;
server search-service-2:8081;
server search-service-3:8082;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
location /search-service {
proxy_pass http://backend/search-service;
}
location /analysis-service {
proxy_pass http://analysis-service:8083/analysis-service;
}
}
}
events { worker_connections 1024; }
基于此,来的请求http://localhost/search-service/
将被定向到 和/http://search-service-1:8080/search-service/
,/http://search-service-2:8081/search-service/
并且/http://search-service-3:8082/search-service/
来的请求http://localhost/analysis-service/
将被定向到/http://analysis-service:8083/analysis-service/
。
创建配置文件(nginx.conf)后,我们将在 Docker 容器中部署 Nginx Web 服务器。为此,我们创建一个Dockerfile,如下所示:
# latest nginx
FROM nginx
# copy custom configuration file
COPY nginx.conf /etc/nginx/nginx.conf
# expose server port
EXPOSE 80
# start server
CMD ["nginx", "-g", "daemon off;"]
我们为 Nginx Web 服务器构建一个 Docker 镜像,如下所示:
docker image build -t custom-nginx:latest .
一旦构建了所有 Docker 映像,就可以通过docker-compose up
在以下docker-compose.yml文件上运行命令来部署所有系统:
version: '3.7'
services:
nginx_server:
image: custom-nginx
ports:
- '80:80'
networks:
- demo-network
depends_on:
- "search-service-1"
- "search-service-2"
- "search-service-3"
- "analysis-service"
search-service-1:
image: search-service-1
ports:
- '8080:8080'
networks:
- demo-network
search-service-2:
image: search-service-2
ports:
- '8081:8081'
networks:
- demo-network
search-service-3:
image: search-service-3
ports:
- '8082:8082'
networks:
- demo-network
analysis-service:
image: analysis-service
ports:
- '8083:8083'
networks:
- demo-network
networks:
demo-network:
name: demo-network
有了这个,我们演示了部署 Spring Boot 应用程序的五种方法。部署的选择基于整体解决方案架构、目标平台的要求(如安全性和可用资源)。
推荐书单
《项目驱动零起点学Java》
《项目驱动零起点学Java》共分 13 章,围绕 6 个项目和 258 个代码示例,分别介绍了走进Java 的世界、变量与数据类型、运算符、流程控制、方法、数组、面向对象、异常、常用类、集合、I/O流、多线程、网络编程相关内容。《项目驱动零起点学Java》总结了马士兵老师从事Java培训十余年来经受了市场检验的教研成果,通过6 个项目以及每章的示例和习题,可以帮助读者快速掌握Java 编程的语法以及算法实现。扫描每章提供的二维码可观看相应章节内容的视频讲解。
《项目驱动零起点学Java》贯穿6个完整项目,经过作者多年教学经验提炼而得,项目从小到大、从短到长,可以让读者在练习项目的过程中,快速掌握一系列知识点。
马士兵,马士兵教育创始人,毕业于清华大学,著名IT讲师,所讲课程广受欢迎,学生遍布全球大厂,擅长用简单的语言讲授复杂的问题,擅长项目驱动知识的综合学习。马士兵教育获得在线教育“名课堂”奖、“最受欢迎机构”奖。
赵珊珊,从事多年一线开发,曾为国税、地税税务系统工作。拥有7年一线教学经验,多年线上、线下教育的积累沉淀,培养学员数万名,讲解细致,脉络清晰。
购买链接:https://u.jd.com/XwJWF2r
精彩回顾
微信搜索关注《Java学研大本营》
访问【IT今日热榜】,发现每日技术热点