公司动态

08-前后端分离项目部署:Vue前端打包部署+微服务反向代理实战

📅 2026/8/24 8:00:00
08-前后端分离项目部署:Vue前端打包部署+微服务反向代理实战
08-前后端分离项目部署Vue前端打包部署微服务反向代理实战大家好我是黒漂技术佬。前面我们搭了 HTTPS、拆了多域名、解决了跨域整套 Nginx 配置已经相当完整。但我们还差最后一步——怎么把真实的业务代码部署上去今天这篇咱们从 Vue 前端打包开始到 Nginx 静态文件服务再到微服务网关反向代理完整走一遍前后端分离项目的部署流程。全程实操直接跟。一、前后端分离部署架构——先厘清整体思路在传统 JSP/Thymeleaf 时代前端页面和后端逻辑混在一个 WAR 包里Tomcat 一跑全搞定。现在的做法已经完全不一样了浏览器 │ ▼ Nginx (反向代理 静态文件服务) ├── /index.html, /assets/* → 本地磁盘上的 Vue 打包产物 └── /api/* → proxy_pass → Spring Cloud Gateway → 各个微服务前端负责页面渲染和用户交互后端只输出 JSON 数据。Nginx 在这中间扮演流量调度员的角色静态资源直接从磁盘读取API 请求转发给后端网关。为什么要这样分独立部署、独立编译——前端改了 UI只发前端后端改了接口只发后端。不会因为改一个文字还要后端重新打包发版。静态资源走 Nginx 性能更优——Nginx 处理静态文件的能力远超 Tomcat/Jetty高并发下的内存占用和响应时间都是碾压级别的。网关统一入口——Spring Cloud Gateway或 Zuul在前面做鉴权、限流、路由Nginx 只需要转发到网关这一个点不用关心微服务节点的具体地址。二、Vue 项目打包——别让 dist 目录变成黑盒前端同学天天敲npm run dev但生产部署可不是npm run dev——那个是带 HMR 热更新的开发服务器性能差、不安全。最终部署的一定是build 之后的静态产物。Vue 项目打包流程# 安装依赖CI/CD 中这一步通常由构建流水线完成npminstall# 打包构建Vite 项目用 npm run buildWebpack 项目也是 buildnpmrun build# 产物在 dist/ 目录# dist/# ├── index.html ← 入口页面# ├── assets/# │ ├── index-abc123.js ← 带哈希的业务代码# │ ├── index-abc123.css ← 带哈希的样式# │ └── logo-abc123.png ← 带哈希的图片# └── favicon.ico你可能会疑惑为什么文件名都带一串哈希如abc123这是内容哈希 (Content Hash)Webpack/Vite 会根据文件内容生成唯一的哈希值。文件内容变了哈希就变文件名就跟着变。这样浏览器缓存机制就不怕了——旧的缓存不清除也没关系因为请求的是新文件名旧文件自然不会被加载。这种策略叫文件指纹是前端缓存管理的最佳实践。Vite 配置中的两个关键项// vite.config.jsexportdefaultdefineConfig({base:/,// 资源基础路径部署在根目录就用/build:{outDir:dist,// 输出目录assetsDir:assets,// 静态资源子目录sourcemap:false,// 生产环境关闭 sourcemap减少体积}})base参数非常关键——如果你的项目部署在admin.smartkaba.com的根目录填/就行如果部署在/admin/子路径下那必须写成base: /admin/否则所有 JS/CSS 的引用路径都会 404。打包完成后把 dist 目录整个丢到 Nginx 服务器上# 服务器上的操作scp-rdist/* rootserver:/var/www/admin-web/dist/# 或者 CI/CD 自动化rsync-avz--deletedist/ rootserver:/var/www/admin-web/dist/三、Nginx 静态文件服务 SPA 路由 404 问题基础的静态文件配置很好写server { listen 443 ssl http2; server_name admin.smartkaba.com; location / { root /var/www/admin-web/dist; index index.html; } }但这里有个深坑——SPA 路由刷新 404。Vue Router 默认使用 history 模式URL 看起来像普通网页admin.smartkaba.com/goods/list。用户直接在浏览器地址栏敲这个 URL 或者按 F5 刷新时浏览器会向 Nginx 请求/goods/list这个路径。但服务器上没有一个叫/goods/list的文件——只有index.html。Nginx 找不到文件返回 404。解决方案就是try_files指令location / { root /var/www/admin-web/dist; try_files $uri $uri/ /index.html; }try_files $uri $uri/ /index.html的逻辑是先尝试$uri请求/goods/list→ 找/var/www/admin-web/dist/goods/list这个文件 → 没有再尝试$uri/请求/goods/list/→ 找/var/www/admin-web/dist/goods/list/这个目录 → 没有兜底/index.html返回index.html让 Vue Router 接管前端路由前端路由的生命周期Nginx 返回index.html→ 浏览器解析 HTML → 加载 app.js → 初始化 Vue Router → Router 根据当前 URL 匹配到对应的组件 → 渲染页面。/goods/list这个不存在的文件路径到此被前端完美兜底。静态资源 404 也要注意如果你发现页面出来了但 JS/CSS 全报 404检查vite.config.js中的base配置——大概率是这里没和 Nginx 的 root 路径对齐。四、history 模式 vs hash 模式——部署上的关键差异Vue Router 有两种路由模式部署方式完全不同hash 模式URL 格式是admin.smartkaba.com/#/goods/list井号后面的内容不会发送给服务器。服务器永远只看到/→ 返回index.html→ Vue Router 解析 hash → 渲染对应页面。hash 模式天然不触发 404不用配 try_files。history 模式URL 格式是admin.smartkaba.com/goods/list美观、对 SEO 友好。但服务器必须配置 try_files 兜底否则手动刷新就 404。对比维度hash 模式history 模式URL 美观度有 # 号较丑干净美观SEO差搜索引擎忽略 # 后面内容良好服务器配置无需任何配置必须配置 try_files分享链接部分平台不支持 # 号正常管理后台内部使用不关心 SEO可以用 hash 模式省事用户端和小程序落地页必须用 history 模式否则影响搜索引擎收录和分享体验。我们售货柜系统后台用 hash用户端 Web 用 history——很实用。五、API 反向代理——从 Nginx 到 Spring Cloud 网关前面小一半篇幅都在搞前端部署但别忘了——后端服务是跑在微服务网关后面的。前端页面向/api/goods/list发了一堆请求Nginx 得把这些请求转发给网关。location /api/ { proxy_pass http://gateway:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 超时配置 proxy_connect_timeout 10s; proxy_read_timeout 30s; proxy_send_timeout 30s; # 缓冲配置对于代理下载长耗时操作 proxy_buffering on; proxy_buffer_size 16k; proxy_buffers 8 64k; proxy_busy_buffers_size 128k; }关键点解析proxy_pass尾部的斜杠http://gateway:8080/api/有斜杠表示把/api/截掉请求/api/goods/list到网关变成/goods/list。如果写成http://gateway:8080不带/api/那/api/goods/list就原封不动传给网关 —— 这取决于你们网关的路由规则是怎么配的和网关保持一致即可。通常网关对/api/**做了匹配所以这里带斜杠截掉。头信息透传X-Real-IP让后端知道客户端的真实 IPX-Forwarded-For记录完整的代理链X-Forwarded-Proto告诉网关原始请求是 HTTP 还是 HTTPS——网关在做重定向或生成链接时需要这个信息。超时与缓冲微服务调用可能比较慢proxy_read_timeout设 30 秒是比较中庸的值。如果是报表导出或数据量大的接口可以针对特定 location 加大超时。完整部署架构的流量链路用户浏览器 │ HTTPS: admin.smartkaba.com ▼ Nginx (443端口) ├── / → /var/www/admin-web/dist/index.html (静态文件) └── /api/ → proxy_pass http://gateway:8080/api/ │ ▼ Spring Cloud Gateway │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ goods-service order-service device-service (商品管理) (订单管理) (设备管理)Nginx → 网关 → 微服务这条链路通了整个前后端分离部署才算真正落地。六、部署后的验证清单部署完成后建议照着这个清单逐项检查首页能正常打开浏览器访问域名能看到 Vue 页面控制台无 404/500SPA 路由刷新不 404手动在地址栏输入一个子路由的完整 URL回车能正常显示API 请求能通页面上的数据列表正常加载Network 面板没有跨域错误HTTPS 锁是绿的证书在有效期内混合内容HTTP 的资源引用在 HTTPS 页面里不会触发警告WebSocket 长连接如果工控屏/ws/端点能正常建立连接不频繁断开后端获取到真实 IP查日志X-Real-IP是客户端 IP 而不是 Nginx 内网 IP总结前后端分离部署的核心就三件事Vue 打包产物丢给 Nginx 做静态服务、try_files解决 SPA 路由 404、proxy_pass把 API 请求反代到微服务网关。history 模式虽然好看但多一步服务器配置hash 模式貌不惊人但省心省力看场景选用。整套流程串起来你的无人售货柜系统就能流畅地把管理后台、用户端和设备接口全部跑在 Nginx 之上了。