Nginx作为静态资源web服务时,通过接收客户端的静态资源请求,然后到静态文件存储位置获取对应的资源并返回给客户端,流程如下图所示:
我们常见的静态资源种类有哪些呢?
-浏览器端渲染:HTML、CSS、JS
-图片:JPEG、GIF、PNG
-视频:FLV、MPEG
-文件:TXT、等任意下载文件
Nginx作为静态资源服务的场景:CDN
在北京的用户请求的资源在北京时,速度会非常快。但是并不是所有资源都放在北京,可能有一天要请求的静态资源放在上海,这个时候,CDN的作用就来了。如果发现在北京的CDN缓存服务器上没有资源,就会向资源存储中心请求上海的资源,然后根据配置策略缓存在北京,Nginx可以完成这项任务。CDN具体是什么可以看看这篇文章:https://zhuanlan.zhihu.com/p/52362950?utm_source=wechat_session&utm_medium=social&utm_oi=631750531454996480
Nginx关于静态资源的相关配置
文件读取配置
sendfile on | off,默认sendfile是关闭的,可以配置在http,server,location,if in location中
多个包整合
tcp_nopush on | off,默认是关闭状态,可以在http,server,location中配置,它的作用是在sendfile开启的情况下,提高网络包的传输效率。什么意思呢,假设服务端收到请求,需要推送10个包,为了提高传输效率,这10个包不会一个一个返回给客户端,而是将10个包攒够了后一起返回回去。
网络包的实时性传输
tcp_nodelay on | off,默认开启,可以在http,server,location中配置,它的作用是在keepalive链接下,提高网络包的传输实时性。
压缩
gzip on | off,默认是关闭状态,可以在http,server,location,if in location中配置,作用是压缩传输。一般来说浏览器是可以对压缩后的内容进行解压的。
压缩级别
gzip_comp_level level;默认的压缩级别是1,可以在http,server,location中配置,级别配置的越高,压缩的越好,但是压缩会耗费服务端的计算资源,所以要控制好压缩级别
压缩对http协议的支持
gzip_http_version 1.0 | 1.1,默认对HTTP/1.1协议的请求才会进行gzip压缩,可以配置在http,server,location中配置。当用户想要读取一个1.html文件,首先会在目录中找寻1.html.gz是否存在,所以这就导致了磁盘资源的浪费,必须要存储两份文件。
压缩实战
实战1:压缩下载文件
步骤1:配置一个conf文件,这个时候gzip on先不打开:
location ~ .*\.(jpg|gif|png)$ {
#gzip on;
#gzip_http_version 1.1;
#gzip_comp_level 2;
#gzip_types text/plain application/javascript image/jpeg image/gif image/png;
root /usr/share/nginx/images;
}
location ~ .*\.(txt|xml)$ {
#gzip on;
#gzip_http_version 1.1;
#gzip_comp_level 1;
#gzip_types text/plain application/javascript image/jpeg image/gif image
/png;
root /usr/share/nginx/code;
}
location ~ ^/download {
gzip_static on;
tcp_nopush on;
root /opt/app/code;
}
步骤2:直接访问,我们可以看到请求的文本大小是68.7KB:
步骤3:取消gzip的相关注释
location ~ .*\.(jpg|gif|png)$ {
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript image/jpeg image/gif image/png;
root /usr/share/nginx/images;
}
location ~ .*\.(txt|xml)$ {
gzip on;
gzip_http_version 1.1;
gzip_comp_level 1;
gzip_types text/plain application/javascript image/jpeg image/gif image/png;
root /usr/share/nginx/code;
}
步骤4:再次访问:只有18.6KB了,说明我们压缩成功了。
Nginx缓存配置
在浏览器没有缓存的情况下,请求到响应的过程如下:
有缓存的情况如下:
校验缓存是否过期的机制有三个:
通过Expires、Cache-Control来判断
通过协议中Etag头信息来校验
通过Last-Modified头信息来校验
后两种要和服务端联系。LastModified精确到秒,如果说在一秒内改变了两次是无法判断过期的,Etag是通过一个特殊字符串来解决这个局限,所以优先被使用。我们可以看看浏览器是如何判断缓存是否过期的,流程图如下:
Nginx如何配置Expires
expires [modified] time; expires epoch | max | off,默认情况下是关闭的,可以配置在http,server,location,if in location中。这里多说一句,不是每个浏览器都会给max-age设置值,chrome浏览器的max-age始终是0,会强制去服务器拿资源。
我们先看一下没有expire的情况下,服务端的响应返回是什么:
Nginx.conf端配置:
location ~ .*\.(htm|html)$ {
expires 24h;
root /usr/share/nginx/code;
}
返回结果多了max-age,而且应答码是304:
Nginx防盗链
Nginx的防盗链是防止资源被盗用,有的同学会问为什么要防呢,你的网站不是给别人访问的么,但是有时候我们不希望自己的静态资源被竞争公司访问到,这个时候就需要使用防盗链了。防盗链的设置思路就是区别哪些请求是正常用户的请求。
使用方式:
location ~ .*\.(jpg|gif|png)$ {
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript image/jpeg image/gif image/png;
valid_referers none blocked 47.100.199.15;
if($invalid_referer) {
return 403;
}
root /usr/share/nginx/images;
}
该指令会根据Referer Header头的内容分配一个值为0或1给变量invalid_referer将被设置为1。none:表示无Referer值的情况。blocked:表示Referer值被防火墙进行伪装。
结果:
[root@slave2 conf.d]# curl -e "http://www.baidu.com" -I http://47.100.199.15/haha.png
HTTP/1.1 403 Forbidden
Server: nginx/1.16.0
Date: Sun, 19 May 2019 09:20:31 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
响应码403被拦截。