一、动静分离原理和使用场景
作用:系统加速(适用于中小型网站)。
把静态资源(比如 H5 和 CSS)直接放到 Nginx,不需要向后端请求。
原本是这样的(如图):
用户请求--Nginx 代理给 Tomcat(假设项目部署在 Tomcat 的 webapp/ 目录下,包含了 jar 包,jar 包有静态资源 static)。

出现问题:上传 static 可能失败、Tomcat 响应会很多非动态的请求,用户请求网页,会响应主页 index.html,然后返回资源,图片之类的。
比如打开 JD 首页,打开控制台就能看到非常多的请求:

QPS 大幅度增长,对于垃圾服务器,高并发肯定顶不住。
如果能把 static 前置到 Nginx 中,无需 Nginx 反向代理,就可以避免上述问题。
二、动静分离配置
效果演示
现在资源服务器(内网 IP 为 104)有这些:

现在配置 Nginx(内网 IP 为 101)的反向代理:proxy_pass 到 104 的 8080 端口,reload 后访问 101,会显示 104 的静态资源(但是 url 显示的还是 101,是后端的 104 提供资源)。
具体配置操作
在 Nginx(101)虚拟出几个目录存放 static,为了验证成果可以删去 104 的资源(可以在控制台删去浏览器的缓存)。
- 创建存储 html 文件的根目录
server{
listen 80;
server_name _;
root /etc/nginx/html;
index index.html;
location / {
proxy_pass http://192.168.44.108:8080;
}
# 下面再配置一个location
location /css { # 这里写的地址会拼接到根路径后
}
}
把 /css 文件夹传到配置的根路径下
reload 后就可以看到 css 资源了,此时没有图片,还未配置。
把相应的文件夹传入到 root 配置的目录下
server {
listen 80;
server_name _; # 默认的域名
root /etc/nginx/html; # 全局配置
# 默认首页文件
index index.html;
# 配置反向代理,动态请求通过Nginx转发到Tomcat
location / {
proxy_pass http://192.168.44.108:8080;
}
# 配置静态资源路径,可以直接通过url路径访问静态资源
location /css/ {
# 如果是根路径统一设置了 root,就不需要再次设置 root
# 因为 root /etc/nginx/html; 已经指定了根目录
# 所以 /css/ 会去查找 /etc/nginx/html/css/ 目录下的文件
}
location /images/ {
# 对于图片,直接通过 /images/ 路径访问
# 图片会直接从 /etc/nginx/html/images/ 目录提供
}
location /js/ {
# 同理,对于 JavaScript 文件,Nginx 会直接提供 /etc/nginx/html/js/ 下的文件
}
}
正则表达式配置动静分离
上面这样写 location 很麻烦,而且 /js 这样的优先级比 / 高,如果想要合并 location 为一个,需要正则表达式(不区分大小写):
server {
listen 80;
server_name _;
root /etc/nginx/html;
index index.html;
location / {
proxy_pass http://192.168.44.108:8080;
}
location ~* ^/(js|css|images)/ {
# 如果加了$就只匹配目录本身了,不会匹配目录下的文件
}
}
~ 启用正则,后面跟上 * 不区分大小写的正则匹配(这意味着 Nginx 会忽略请求 URI 的大小写差异,执行匹配时不考虑字母的大小写),^ 表示以此字符串为开头匹配,防止乱匹配。
一些补充的内容:
# 匹配以 /js/、/css/、/images/ 开头的所有请求
location ~* ^/(js|css|images)/ {
}
# 能匹配:/js/app.js、/css/style.css、/images/logo.png、/images/2024/banner.jpg
# 匹配以 /js/、/css/、/images/ 结尾的请求
location ~* ^/(js|css|images)/$ {
}
# 只能匹配:/js/、/css/、/images/
默认规则的优先级比较低,相比于 /,/js 是更高的,也就是更具体的优先级高。
用在 location 里:
~* ^/js/→ 路径必须从/js/开始~* /js/→ 路径只要包含/js/就匹配
* 在路径中才表示通配。
测试:用 V4 写了一下目录的文件并配置好了 Nginx 在 test 子域
测试服务页 | test.168kaguyachi.site
/var/www/test/
├── index.html
├── css/
│ └── style.css
├── js/
│ └── main.js
└── images/
└── (放图片)
大网站访问会逐步加载资源,而不是一口气,比如往下翻才会加载,也降低了 QPS。