负责接收静态资源请求,根据url从文件存储中获取并返回给客户端,常用于动静分离。
静态资源是指无需服务器动态生成的文件资源,比如视频、html、图片等。
针对静态资源的配置,主要有两个切入点:
针对内容压缩
sendfile、tcp_nopush、tcp_nodelay
# sendfile,文件零拷贝读取
Syntax: sendfile on|off;
Default: sendfile off;
Context: http, server, location, if in location
# tcp_nopush
# 当使用sendfile时,tcp_nopush才起作用,于tcp_nodelay是互斥的
# 开启后,有数据包不会立即传送出去,而是等到等待传送的数据包达到最大时,一次性传输出去,有利于解决网络阻塞
Syntax: tcp_nopush on|off;
Default: tcp_nopush off;
Context: http, server, location
# tcp_nodelay
# 无等待,立即发送包,在实时性高的情况下可以开启,与tcp_nopush互斥
# 默认开启
# 常用于keepalive 连接下,提高网络包的传输实时性
Syntax: tcp_nodelay on|off;
Default: tcp_nodelay on;
Context: http, server, location
http_gzip_static_module
此模块用于预读gzip压缩文件:
location ~ ^/download {
# 开启此功能
gzip_static on;
root /usr/share/nginx/gzipfile;
}
在请求/download/index.html
的时候,此模块会先从root下寻找文件index.html.gz
,如果找不到才会去寻找index.html
文件。
gz文件需要预先生成,生成可以使用gzip
命令:
gzip ./index.html
> ls
index.html.gz
那么在浏览器请求/download/index.html
,会展示index.html.gz
解压后的html文件的内容。
http_gunzip_module
部分浏览器不支持gzip压缩,可以使用此模块,此处不再演示。
示例配置
server {
listen 80;
server_name 116.62.103.228 jeson.imooc.com;
# 打开`sendfile`零拷贝机制
sendfile on;
# 多个包打包在一起,一起发送,大文件推荐打开, 可提高网路包的传输效率
#tcp_nopush on;
# 实时发送,在是实时性较高的需求中,需要打开(需要连接是keepalived长连接)
#tcp_nodelay on
#charset koi8-r;
access_log /var/log/nginx/log/static_access.log main;
# 图片资源匹配
location ~ .*\.(jpg|gif|png)$ {
# 打开gzip压缩,发送之前会对资源进行gzip压缩,浏览器接收到时会进行解压,效果可以比对文件传输的大小
gzip on;
# gizp的http协议的版本
gzip_http_version 1.1;
# 压缩比
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
root /usr/share/nginx/img;
}
# 文本资源匹配
location ~ .*\.(txt|xml)$ {
# 文本压缩比图片压缩更有效果
gzip on;
gzip_http_version 1.1;
gzip_comp_level 1;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
root /usr/share/nginx/doc;
}
# download开头的路径匹配
location ~ ^/download {
# 来自 http_gzip_static_module,具有预读gzip功能,需要预先将文件压缩放入磁盘
gzip_static on;
tcp_nopush on;
root /usr/share/nginx/gzipfile;
}
#error_page 404 /404.html;
error_page 500 502 503 504 404 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
浏览器缓存
使用浏览器缓存静态资源的两个好处:
HTTP协议缓存支持
HTTP1.1 最大期限,用于替代1.0,超过最大期限会失效
最后修改时间校验比较,值为时间,只能精确到秒,秒级别的更新无效
判断Etag是否过期,类似Last-Modified,是一个信息摘要字符串,不同就说明已经过期
Etag 与 Last-Modified 缓存策略下,当缓存处于有效状态时,请求静态资源的响应状态将会变为304。nginx默认采用此种缓存方式
Expire与Cache-Control 的优先级大于 Last-Modified 和 Etag。
expires 配置浏览器缓存
# expires 语句会为响应添加 Cache-Control、Expires头
# time代表缓存时间周期
Syntax: expires [modified] time;
expires epoch | max | off;
Default: expires off;
Context: http, server, location, if in location
示例配置
location ~ .*\.(htm|html)$ {
# 缓存有效期为1天
expires 24h;
root /usr/share/nginx/html;
}
此时可以看到,Cache-Control
已经变为86400
,单位为秒,即24h
。
跨域访问
浏览器是不允许ajax
跨域访问,但是JS
等资源有可能位于CDN中,并且域名不同,此时就需要nginx的跨域访问支持。虽然跨域访问不安全(CSRF攻击),但是出于软件结构设计、业务形态等种种原因,仍需要跨域访问支持。
HTTP对跨域的支持
HTTP协议提供了Access-Control-Allow-Origin
头,此头的值由服务端返回给客户端,告诉客户端可以进行跨站访问。
# 给当前响应添加头,name代表头名称,value代表值
Syntax: add_header name value [always];
Default:
Context: http, server, location, if in location
示例配置
location ~ .*\.(htm|html)$ {
add_header Access-Control-Allow-Origin http://www.baidu.com;
# add_header Access-Control-Allow-Origin *; # 所有都可以跨域,会发生CSRF攻击
add_header Access-Control-Allow-Methods GET,POST,PUT,OPTIONS;
root /usr/share/nginx/html;
}
防盗链
防盗链就是防止网站资源被盗用:
防盗链的设置思路
基于http_refer防盗链
$http_refer
代表此请求来源处,如果此请求不是本网站的,就不允许访问,这样就能防止其他网站使用自己网站的图片、视频等资源。
# 校验refer是否合法,此处可配置多个值,使用空格隔开
# none:允许没有refer信息
# blocked: 允许refer信息不是标准的uri(不是以http://域名开头)
# servernames 允许的ip、域名
# 还支持正则匹配
Syntax: valid_referers none|blocked|servernames|regex ...;
Default:
Context: server, location
示例配置
# 图片资源匹配
location ~ .*\.(jpg|gif|png)$ {
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 允许请求没有refer信息
# 允许不标准的refer信息
# 允许ip为 192.168.173.165 的请求
# 其他都不允许,返回403
valid_referers none blocked 192.168.173.165;
if ($invalid_referer) {
return 403;
}
root /usr/share/nginx/img;
}
动静分离
动静分离是指,通过中间件将动态请求与静态请求分离,从而分离资源,减少不必要的请求消耗,减少请求延时。
在动静不分离之前,一个静态请求需要经过一下几个部分才能获取到:
中间件(Nginx) -> 程序框架(Spring) -> 程序逻辑 -> 数据资源
在东京分离之后,静态请求将会直接由中间件处理,所以效率更高:
并且,如果一方出现问题,另一方不会受到影响。
动静分离配置不再演示