Nginx 前后端分离架构配置:静态托管、API 反向代理与 WebSocket集成

96 阅读4分钟

本次部署采用经典的 反向代理(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)。

处理逻辑

  1. Nginx 拦截到路径里包含 /api/
  2. proxy_pass 将请求转发给 webservers 组(即 8081 端口)。
  3. 注意路径替换:Nginx 会把 URL 中的 /api/ 替换为 /admin/,因为后端接口定义的路径是 /admin/...
  4. 示例
    • 客户端请求: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 连接请求时。

处理逻辑

  1. proxy_pass:将请求转发给后端的 WebSocket 地址。
  2. proxy_set_header:这是最关键的。它会在请求头里加上 Upgrade: websocket。如果不加这两行,后端会以为这只是普通的 HTTP 请求从而拒绝建立长连接。

结果:浏览器与后端建立了一条全双工的通信通道,用于实时消息推送。

3. 完整交互流程总结

在这个架构下,前端、Nginx、后端是这样配合的:

  1. 用户访问网页
    • 浏览器 -> Nginx (80端口) -> 读取硬盘文件 -> 返回 HTML 页面。
    • (此时后端不参与)
  2. 用户点击操作(如登录)
    • 浏览器 -> 发送 /api/ 请求 -> Nginx (80端口) -> 修改路径为 /admin/ -> 转发给后端 (8081端口) -> 返回结果。
  3. 来单提醒(WebSocket)
    • 浏览器 -> 发送 /ws/ 连接 -> Nginx (80端口) -> 添加协议升级头 -> 转发给后端 (8081端口) -> 建立长连接。
    • 之后后端有新消息,直接通过这个连接推送到浏览器。

通过这套配置,成功实现了前后端分离的部署,并且对外只暴露一个 80 端口,既规范又安全。