Nginx动静分离的核心是让Nginx直接响应静态资源请求,仅将动态路径(如/api/、/login等)转发给Tomcat;需统一存放静态文件至独立目录,用location精准匹配并配置alias/root、缓存头及安全策略,禁用Tomcat静态服务以确保资源交付权移交。
Java 应用(如 Spring Boot、传统 WAR 包部署在 Tomcat)通常默认把静态资源(/static、/public、/resources 等目录下的 CSS/JS/图片)和动态接口混在一起发布。直接由 Tomcat 处理全部请求,会严重浪费线程资源。Nginx 动静分离的核心就是:让 Nginx 拦截并直接响应静态请求,只把真正需要 Java 处理的动态路径(如 /api/、/login、/*.do)转发给 Tomcat。
Java 项目上线前,建议将前端构建产物(如 Vue/React 打包后的 dist 目录)或后端静态资源统一提取出来,单独存放到服务器一个固定路径,例如:
/data/www/static/ —— 存放所有 CSS、JS、图片、字体、HTML 页面/data/www/upload/ —— 存放用户上传的图片等(需额外配置权限和安全策略)注意:不要把静态文件继续放在 Tomcat 的 webapps/ROOT/ 下,否则容易被 Nginx 和 Tomcat 同时匹配,造成冲突或绕过缓存。
在 Nginx 的 server 块中添加以下几类匹配规则,优先级从高到低,确保静态请求不落到 proxy_pass 分支:
/static/xxx.js,直接映射到本地目录location /static/ { alias /data/www/static/; }
location ~* .(js|css|png|jpg|jpeg|gif|ico|svg|woff2?|ttf|eot|html)$ { root /data/www/static; expires 1y; add_header Cache-Control "public, immutable"; }
location ~ /. { deny all; }
⚠️ 关键细节:alias 和 root 行为不同。用 alias /path/ 时,URI 中的路径名会被替换;用 root /path 时,URI 全路径会拼接到 root 后。别写反,否则 404。
避免使用笼统的 location / { proxy_pass http://tomcat; },那样会覆盖所有请求,包括本该由 Nginx 处理的静态资源。
location /api/ { proxy_pass http://127.0.0.1:8080/; }
location /admin/ { proxy_pass http://127.0.0.1:8080/; }
(注意末尾斜杠,决定是否重写路径)
location ~ .(do|action|jsp)$ { proxy_pass http://127.0.0.1:8080; }
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;
提升稳定性和安全性:
server.xml 中注释或删除 DefaultServlet 的映射,或设置 readonly="true",避免意外暴露sendfile on;
tcp_nopush on;
gzip on;
gzip_types text/css application/javascript application/json;
client_max_body_size 10m;(放在 http 或 server 块)
动静分离不是“多加几行配置”,而是把静态交付权从 Java 进程里收回来——Nginx 做它最擅长的事,Tomcat 只管业务逻辑。一次配置,性能常驻。