欢迎光临
我们一直在努力

分布式系统开发(6)——项目打包部署与Nginx代理前端

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}

系列文章: 分布式系统开发(1)——MinIO 对象存储 分布式系统开发(2)——Redis 缓存与分布式锁

分布式系统开发(3)——RabbitMQ独立模块

分布式系统开发(4)——Dubbo+Zookeeper(RPC服务)

分布式系统开发(5)——整合所有组件

分布式系统开发(6)——项目打包部署与Nginx代理前端

本文在 分布式系统开发(5)——整合所有组件 基础上,进行打包和部署工作。

1. 后端打包

1.1 打包过程和原理

Maven多模块打包流程:

执行 mvn clean install
↓
1. 按依赖顺序编译各模块
ds-api → common → ds-rabbit → ds-provider & ds-consumer
↓
2. 将每个模块打成 JAR 包
├── ds-api-1.0-SNAPSHOT.jar (接口库)
├── common-1.0-SNAPSHOT.jar (工具库)
├── ds-rabbit-1.0-SNAPSHOT.jar (MQ库)
├── ds-provider-1.0-SNAPSHOT.jar (可执行JAR) ← 包含所有依赖
└── ds-consumer-1.0-SNAPSHOT.jar (可执行JAR) ← 包含所有依赖
↓
3. 安装到本地 Maven 仓库 (~/.m2/repository)
供其他模块引用

Spring Boot打包做了什么

spring-boot-maven-plugin 的作用:
├── 把你的代码打包进去
├── 把所有依赖的 JAR 包也打包进去(BOOT-INF/lib/)
├── 添加启动器(Main-Class、Start-Class)
└── 生成可执行的 Fat JAR(胖包)

所以生成的 JAR 包很大(30-40MB),因为包含了运行所需的一切。

模块target 内容是否需要
common/target/ common-1.0-SNAPSHOT.jar ❌ 普通库,被其他模块依赖
ds-api/target/ ds-api-1.0-SNAPSHOT.jar ❌ 接口定义,被其他模块依赖
ds-rabbit/target/ ds-rabbit-1.0-SNAPSHOT.jar ❌ 被 ds-consumer 依赖
ds-provider/target/ ds-provider-1.0-SNAPSHOT.jar ✅ 可执行JAR
ds-consumer/target/ ds-consumer-1.0-SNAPSHOT.jar ✅ 可执行JAR

这个项目是分布式项目,主要由三部分构成,ds-provider、ds-consumer、ds-rabbit模块,原则上这三个模块可以独立打包,独立部署。但是本文在ds-consumer已经整合了RabbitMQ功能,所以只打包ds-provier、ds-consumer两个包。

(所以,我们只在ds-provider、ds-consumer两个模块加了build标签)

1.2 修改代码

先打开根目录的pom.xml,增加打包内容

在这里插入图片描述 添加完后,整个pom.xml参考如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>com.guo</groupId>
<artifactId>ds-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>ds-rabbit</module>
<module>ds-api</module>
<module>ds-provider</module>
<module>ds-consumer</module>
<module>common</module>
</modules>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/>
</parent>

<properties>
<java.version>17</java.version>
<minio.version>8.4.3</minio.version>
<dubbo.version>3.3.0</dubbo.version>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
</dependency>
<!– Dubbo 核心依赖 –>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!– Dubbo 依赖的 ZooKeeper 客户端(Curator) –>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.2.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

修改provider的依赖文件,增加打包相关配置 在这里插入图片描述 增加完后,这个模块的代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.guo</groupId>
<artifactId>ds-demo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>ds-provider</artifactId>

<dependencies>
<!— Dubbo starter —>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.guo</groupId>
<artifactId>ds-api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<!–打包相关配置 —>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

然后,修改consumer模块的内容,增加打包相关配置 在这里插入图片描述 consumer模块的pom.xml的配置内容参考如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.guo</groupId>
<artifactId>ds-demo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>ds-consumer</artifactId>

<dependencies>
<!– Dubbo starter –>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.guo</groupId>
<artifactId>ds-api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.guo</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.guo</groupId>
<artifactId>ds-rabbit</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

1.3 打包

打开右侧的maven,找到ds-demo(这个是根目录) 然后,双击下面的install (就是mvn clean install 命令) 在这里插入图片描述 然后,下面的控制台开始输出内容。

在这里插入图片描述

先找到provier模块的包,在当前模块的 target目录下 这个ds-provider-1.0-SNAPSHOT.jar就是打包后的,可以把它放到服务器上 在这里插入图片描述

找到consumer模块的包,在当前模块的target目录下。 这个ds-consumer-1.0-SNAPSHOT.jar就是打包后的,可以复制它到服务器上。 在这里插入图片描述

打包完后,我们有 了两个jar包,我们复制一下这两个jar包到一个文件夹(这个文件夹一般是服务器上的,但是为了测试目前就放到windows上某一个文件夹)

在这里插入图片描述 这里,如果你觉得名字太长可以简单修改一下jar包的名字。

2.前端打包与nginx代理

正常情况下, 前端一般是一个项目,比如vue,需要先执行前端的打包命令(一般是npm run build),将项目打包,然后再部署到nginx中。本项目的前端目前只有一个html页面。不用额外打包,直接挂载到nginx中即可。 找到上一章节的upload.html。 这个upload.html的参考代码如下:

<!–启动所有模块后,运行此文件,注意端口号–>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MinIO 上传下载工具</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: "Microsoft Yahei", sans-serif;
}
body {
padding: 30px;
max-width: 900px;
margin: 0 auto;
}
.box {
margin-bottom: 20px;
}
h3 {
margin-bottom: 12px;
color: #222;
}
label {
display: inline-block;
margin: 8px 0 4px;
}
input[type="text"],
input[type="file"] {
width: 100%;
padding: 8px 10px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
}
button {
margin-top: 12px;
padding: 8px 20px;
background-color: #1677ff;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background-color: #0958d9;
}
/* 分割线 */
.divider {
border: none;
border-top: 2px solid #eee;
margin: 30px 0;
}
/* JSON 结果展示区 */
#uploadResult {
margin-top: 15px;
padding: 12px;
background: #f6f8fa;
border-radius: 4px;
min-height: 60px;
white-space: pre-wrap;
font-family: Consolas, monospace;
font-size: 13px;
color: #333;
}
</style>
</head>
<body>
<!— 上半部分:头像上传 —>
<div class="box">
<h3>用户头像上传</h3>
<label>上传接口地址:</label>
<input type="text" id="uploadUrl" value="http://localhost:8084/api/user/avatar">

<form id="uploadForm" enctype="multipart/form-data">
<label>用户ID:</label>
<input type="text" name="userId" id="userIdInput" placeholder="请输入用户ID">

<label>选择文件:</label>
<input type="file" name="file" id="fileInput">
<br>
<button type="submit">开始上传</button>
</form>

<!— 上传返回 JSON 展示区域 —>
<div id="uploadResult"></div>
</div>

<!— 中间分割线 —>
<hr class="divider">

<!— 下半部分:文件下载 —>
<div class="box">
<h3>文件下载</h3>
<label>文件下载地址:</label>
<input type="text" id="downloadUrl" placeholder="请输入文件下载链接">
<br>
<button id="downloadBtn">开始下载</button>
</div>

<script>
// 上传逻辑
const uploadForm = document.getElementById('uploadForm');
const uploadUrl = document.getElementById('uploadUrl');
const uploadResult = document.getElementById('uploadResult');

uploadForm.addEventListener('submit', async function (e) {
e.preventDefault();
const url = uploadUrl.value.trim();
if (!url) {
uploadResult.innerText = '请填写上传接口地址';
return;
}

try {
const formData = new FormData(this);
const res = await fetch(url, {
method: 'POST',
body: formData
});

const data = await res.json();
// 格式化 JSON 展示
uploadResult.innerText = JSON.stringify(data, null, 2);
} catch (err) {
uploadResult.innerText = `请求异常:${err.message}`;
}
});

// 下载逻辑
const downloadUrl = document.getElementById('downloadUrl');
const downloadBtn = document.getElementById('downloadBtn');

downloadBtn.addEventListener('click', function () {
const url = downloadUrl.value.trim();
if (!url) {
alert('请填写下载地址');
return;
}
// 打开新标签页/直接触发浏览器下载
window.open(url, '_blank');
});
</script>
</body>
</html>

找到nginx配置,把这个文件放到ngingx目录中,

在这里插入图片描述

把upload.html放到这里面 然后打开conf文件夹,修改nginx.conf

在这里插入图片描述

在这里插入图片描述

改成下面这样:

在这里插入图片描述

3.测试场景一

3.1 场景描述:

只有一个电脑,这台电脑上部署 前端、后端Spring Boot和各种服务(比如minio、 redis)。这是我们的默认场景。 过程:

3.2 启动服务

minio、rabbitMQ、zookeeper、redis等服务全部启动

注意本地JDK问题,我们的项目是在IDEA中用的JDK17,现在要运行打包的代码,那么本身(服务器)环境也要是JDK17,保持一致。

3.3 启动后端:

我们 把刚才打包好的两个jar包,复制到一个文件夹中,然后在文件处按住 shift+鼠标右键。 在这里插入图片描述 然后选择”在此处打开Power shell窗口“ 在这里插入图片描述

先输入第一个指令,启动provider包

java -jar ds-provider-1.0-SNAPSHOT.jar

在这里插入图片描述

在这里插入图片描述 然后,上面的窗口不要关掉。

再在空白处 按住shift+鼠标右键,选择 ”在此处打开powershell窗口“ 然后再输入

java -jar ds-consumer-1.0-SNAPSHOT.jar

在这里插入图片描述

在这里插入图片描述

3.5 启动前端

双击ngingx.exe,它会一闪而过,这是正常的。 在这里插入图片描述

3.6 测试

在浏览器中打开localhost:8085 (因为前面nginx.conf中配置的端口是8085)

在这里插入图片描述

在浏览器中打开localhost:8085 ,就会看到下面的界面

在这里插入图片描述

先填写用户ID,再从本地上传一个文件,然后,点击”开始上传“ 在这里插入图片描述

根据网络情况,然后就可以看到返回的信息了。 在这里插入图片描述

注意,文件下载功能不好用,因为代码里面没写文件下载的代码。

4.测试场景二

4.1 场景描述

现在有两台电脑,两台电脑叫A和B,通过局域网连接。 A电脑的IP,通过ipconfig查看是192.168.66.188 在这里插入图片描述

B电脑的IP,通过ipconfig查看是192.168.66.216 在这里插入图片描述

A电脑ping一下B电脑,看是否连通 在这里插入图片描述 B电脑ping一下A电脑,看是否连通 在这里插入图片描述

电脑A放后端Spring Boot和各种服务。电脑B存放Nginx相关(配置和第2部分:前端打包与nginxd代理完全一致)

ping不通的,关闭防火墙。

在这里插入图片描述

4.2 启动服务

注意,一定要先 切换网络,再启动服务。 电脑A先启动各种服务(redis、RabbitMQ、Dubbo等) 保持默认配置即可。

4.3 启动后端

整个后端都在电脑A上。

跟上面的操作一样,找到打包好的jar包 、在这里插入图片描述 按住shift+鼠标右键, 然后选择"在此处打开Power shell窗口",然后执行第一个命令

java -jar ds-provider-1.0-SNAPSHOT.jar

在这里插入图片描述 然后,上面的窗口最小化。

再次按住shift+鼠标右键,然后选择”在此处打开Power shell窗口“,然后执行第二个命令

java -jar ds-consumer-1.0-SNAPSHOT.jar

这个窗口也最小化。

在这里插入图片描述

4.3 启动前端

前端在电脑B上,配置方式和上面的一样(upload.html也需要放到nginx中html文件夹下面) 在这里插入图片描述

电脑B上的ngingx.conf配置文件,可以参考下面内容(注意端口号):

在这里插入图片描述

然后,再电脑B上启动nginx,打开浏览器,访问

localhost:8085

8085是nginx设置的端口。

4.4 测试

在B电脑,打开网站localhost:8085,

然后在下面的”上传接口地址“栏,写上

http://192.168.66.188:8084/api/user/avatar

这里的地址,就是A电脑的地址和端口。 然后输入用户ID,再选择文件,然后点击”开始上传“ 就可以看到上传成功了。 在这里插入图片描述

5.测试场景三

5.1 场景描述

现在有两台电脑,两台电脑叫A和B,通过局域网连接。 A电脑的IP,通过ipconfig查看是192.168.66.188 在这里插入图片描述

B电脑的IP,通过ipconfig查看是192.168.66.216 在这里插入图片描述

A电脑ping一下B电脑,看是否连通 在这里插入图片描述 B电脑ping一下A电脑,看是否连通 在这里插入图片描述

电脑A放各种服务。电脑B放前后端。

ping不通的,关闭防火墙。

在这里插入图片描述

5.2 修改RabbitMQ

RabbitMQ默认的guest账号和密码,只允许本地登录,我们使用上面的方式会报错”User can only log in via localhost“,有两种解决办法,一种是修改本地guest账号的权限,另外一种是新建账号。实际开发中一般采用第二种方法。

关于创建用户的方式也有两种,一种是使用命令行的方式, 另外一种是使用界面。前面的文章中,已经安装完RabbitMQ的界面插件了,所以直接登录访问即可,采用第二种方式。

http://localhost:15672/

用户名和密码,默认guest 在这里插入图片描述 点击”Admin“这个选项卡 在这里插入图片描述 然后,点击下面的”Add a user“ 在这里插入图片描述 然后,输入Username。这里输入admin password输入123456,一共输入2次。 右侧,选”Admin“ 然后,点击下面的”Add user“ 在这里插入图片描述 输入完了后,页面就能看到刚才添加的admin用户。 然后,点击”admin“ 在这里插入图片描述 可以看到 配置权限界面。 然后点击下图的”Set permission“按钮。

在这里插入图片描述 点击完了,页面会出现下面的内容,可以看到当前的权限。 在这里插入图片描述

5.3 修改redis配置

主要绑定IP的问题。 打开Redis配置文件,redis.windows.conf 在这里插入图片描述 找到bind 127.0.0.1 在这里插入图片描述 注释掉后,界面如下。 在这里插入图片描述 然后,保存一下文件,重启redis。

5.2 修改代码

因为后端代码和服务不在一块,所以后端代码不能访问localhost了,需要访问电脑A的地址。

需要找到配置文件中的localhost。

点击IDEA的右上角的放大镜。

在这里插入图片描述 把下面这些都改成A服务器的地址(192.168.66.188) 在这里插入图片描述 也可以参考下面一个一个修改:

(1)provider模块 在这里插入图片描述

provider模块的配置文件修改完后如下:

server:
port: 8090 # HTTP 管理端口(健康检查等)

dubbo:
application:
name: demo–provider # 服务名称,在注册中心显示
registry:
address: zookeeper://192.168.66.188:2181 # 注册中心地址
protocol:
name: dubbo
port: 20880 # Dubbo 服务端口

(2) 修改consumer模块的yml文件。

在这里插入图片描述 修改完后的配置文件参考如下:

server:
port: 8084 # 消费者 HTTP 服务端口

dubbo:
application:
name: demo–consumer
qos-enable: false # 禁用 QoS 服务,避免端口冲突
registry:
address: zookeeper://192.168.66.188:2181
consumer:
check: false # 启动时不检查服务提供者是否存在(避免启动报错)
#timeout: 5000 # 全局调用超时5秒,覆盖默认1000ms
minio:
endpoint: http://192.168.66.188:9000
access-key: minioadmin
secret-key: minioadmin
bucket: online–file # 默认桶名称(可自定义)
connect-timeout: 60s
write-timeout: 60s
read-timeout: 60s

spring:
data:
redis:
host: 192.168.66.188
port: 6379
timeout: 5000ms
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
rabbitmq:
host: 192.168.66.188
port: 5672
username: admin
password: 123456
virtual-host: /

(3) 修改rabbitMQ模块

在这里插入图片描述

配置文件如下:

server:
port: 8083

spring:
rabbitmq:
host: 192.168.66.188
port: 5672
username: admin
password: 123456
virtual-host: /

(4)修改根目录的pom.xml

需要在pom.xml增加一个

<skipTests>true</skipTests>

这个表示跳过测试, 不然的话,因为需要连RabbitMQ,会报错。 在这里插入图片描述

5.3 重新打包

找到根目录的 ”生命周期“,双击”install“ 在这里插入图片描述

然后,还是把ds-porvider模块的target目录下的 这个 xxx.jar 复制到B电脑上。 在这里插入图片描述 再把 ds-consumer模块的xxx.jar复制到B服务器上。 在这里插入图片描述

5.4 启动服务

注意,一定要先 切换网络,再启动服务。 在A电脑中启动各种服务(redis、RabbitMQ、Dubbo等) 保持默认配置即可。

5.5 启动后端

现在前端和后端都在B电脑上。 电脑B开两个cmd。和上面的流程一样。 在存放jar包的地方,按住shift+鼠标右键,然后选择”在此处打开PowerShell窗口“

分别输入下面的两个命令,启动两个jar包

java -jar ds-provider-1.0-SNAPSHOT.jar

java -jar ds-consumer-1.0-SNAPSHOT.jar

下图是在B电脑上启动后的界面。 在这里插入图片描述

5.6 启动前端

前端的配置和前面一样,不用更改,打开浏览器,输入

localhost:8085

5.7 测试

这里上传接口地址是:

http://localhost:8084/api/user/avater

这里访问localhost:8084是因为后端就在B电脑上。

然后输入用户ID,再选择一个文件。

然后点击”开始上传“ (根据网络条件,稍微等一下)

在这里插入图片描述

就可以看到上传成功了,右侧consumer窗口下方可以看到上传成功后,输出的一些内容。

场景三打包的jar分享: 场景三打包链接: (1) 百度网盘:通过网盘分享的文件:场景三打包 链接: https://pan.baidu.com/s/1WAmDCief_K0q73HLW2fjRg?pwd=cyae 提取码: cyae

(2)夸克网盘:

我用夸克网盘给你分享了「场景三打包」,点击链接或复制整段内容,打开「夸克APP」即可获取。 /50573b4iVa😕 链接:https://pan.quark.cn/s/f5bdc14db6a0?pwd=Nd4g 提取码:Nd4g

赞(0)
未经允许不得转载:171主机测评 » 分布式系统开发(6)——项目打包部署与Nginx代理前端
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址