本次部署采用经典的 反向代理(Reverse Proxy) 模式。
流量入口:Nginx 监听宿主机的 80 端口。
前端应用:Vue 构建后的静态资源(HTML/CSS/JS),托管于 Nginx 本地。
后端服务:Spring Boot 应用运行于 8081 端口,不再直接对外暴露。
通信链路: HTTP 请求:由 Nginx 进行路径重写后转发。
WebSocket 连接:由 Nginx 处理握手并建立全双工 TCP 隧道。
1. Nginx 完整配置代码
这是我目前正在使用的配置。Nginx 监听 80 端口,后端 Tomcat 运行在 8081 端口。
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade{
default upgrade;
'' close;
}
upstream webservers{
server 127.0.0.1:8081 weight=90 ;
#server 127.0.0.1:8088 weight=10 ;
}
# 主服务器配置
server {
listen 80;
server_name localhost;
location / {
root html/sky;
index index.html index.htm;
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /opt/homebrew/var/www;
}
location /api/ {
proxy_pass http://webservers/admin/;
}
location /user/ {
proxy_pass http://webservers/user/;
}
# WebSocket
location /ws/ {
proxy_pass http://webservers/ws/;
proxy_http_version 1.1;
proxy_read_timeout 3600s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}
}
}
2. 配置详解:各部分的作用
第一部分:Server 核心路由块
server {
listen 80;
server_name localhost;
# ... locations ...
}
Nginx 监听 80 端口,拦截所有发往 localhost 的请求,并根据 URI 前缀 进行路由分发。
第二部分:静态资源托管 加载前端页面 (Location /)
location / {
root html/sky;
index index.html index.htm;
}
触发条件:当你在浏览器输入 http://localhost 时
处理逻辑:Nginx 不会去问后端,而是直接去电脑硬盘的 html/sky 目录下,找到 index.html 文件发送给浏览器,然后浏览器显示出网页界面。
第三部分:定义后端地址 (Upstream)
upstream webservers{
server 127.0.0.1:8081 weight=90 ;
}
作用:给运行在 8081 端口的 Java 后端起个名字叫 webservers。
好处:以后如果后端换了端口或增加了服务器,只需要改这里,下面的配置不用动。
第四部分:API 反向代理 转发业务接口 (Location /api/)
location /api/ {
proxy_pass http://webservers/admin/;
}
触发条件:当前端代码发起登录或查询等请求时(如 http://localhost/api/employee/login)。
处理逻辑:
- Nginx 拦截到路径里包含
/api/。 proxy_pass将请求转发给webservers组(即 8081 端口)。- 注意路径替换:Nginx 会把 URL 中的
/api/替换为/admin/,因为后端接口定义的路径是/admin/... - 示例:
- 客户端请求:
http://localhost/api/employee/login - Nginx 转发:
http://127.0.0.1:8081/admin/employee/login
- 客户端请求:
结果:Java 后端收到请求,处理业务,返回数据。
第五部分:用户端接口转发
location /user/ {
proxy_pass http://webservers/user/;
}
逻辑:同上,将 /user/ 开头的请求转发到后端的 /user/ 模块,实现了管理端与用户端流量的物理隔离与逻辑统一。
第六部分:转发 WebSocket (Location /ws/)
location /ws/ {
proxy_pass http://webservers/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
}
触发条件:前端发起 ws://localhost/ws/xxx 连接请求时。
处理逻辑:
proxy_pass:将请求转发给后端的 WebSocket 地址。proxy_set_header:这是最关键的。它会在请求头里加上Upgrade: websocket。如果不加这两行,后端会以为这只是普通的 HTTP 请求从而拒绝建立长连接。
结果:浏览器与后端建立了一条全双工的通信通道,用于实时消息推送。
3. 完整交互流程总结
在这个架构下,前端、Nginx、后端是这样配合的:
- 用户访问网页:
- 浏览器 -> Nginx (80端口) -> 读取硬盘文件 -> 返回 HTML 页面。
- (此时后端不参与)
- 用户点击操作(如登录):
- 浏览器 -> 发送
/api/请求 -> Nginx (80端口) -> 修改路径为/admin/-> 转发给后端 (8081端口) -> 返回结果。
- 浏览器 -> 发送
- 来单提醒(WebSocket):
- 浏览器 -> 发送
/ws/连接 -> Nginx (80端口) -> 添加协议升级头 -> 转发给后端 (8081端口) -> 建立长连接。 - 之后后端有新消息,直接通过这个连接推送到浏览器。
- 浏览器 -> 发送
通过这套配置,成功实现了前后端分离的部署,并且对外只暴露一个 80 端口,既规范又安全。