Nginx应用案例篇一(资源优化压缩,跨域问题,防盗链)

发布于 2021-09-10  5.05k 次阅读


一,静态资源优化

Nginx对静态资源主要用三个属性进行优化:

  • sendfile on;
  • tcp_nopush on;
  • tcp_nodeplay on;

一,sendfile指令

sendfile:用来开启高效的文件传输模式 ,它底层调用系统内核的sendfile函数,避免了文件的多次拷贝,减少了用户态和内核态转换来提高静态文件传输效率

普通请求静态资源的过程:

  1. 客户端通过网络接口向服务端发送请求
  2. 操作系统将这些客户端的请求传递给服务器端应用程序
  3. 服务器应用程序处理请求
  4. 处理完成后,操作系统将处理得到的结果通过网络适配器传递给客户端

语法 sendfile on | off
默认值 sendfile off
配置位置 http块,server块,location块

二,tcp_nopush和tcp_nodelay指令

1,tcp_nopush:该指定必须在sendfile开启的状态才能打开,主要用于提示网络包的传输效率

语法 tcp_nopush on | off
默认值 sendfile off
配置位置 http块,server块,location块

2,tcp_nodelay:该指定必须在keep-alive路径开启的情况下才能生效,来提高网络包传输的'实时性'

语法 tcp_nodelay on | off
默认值 sendfile off
配置位置 http块,server块,location块

tcp_nopush在传输时相当于设置了一个缓冲区,当缓冲区满时才发送,这大大减少了网络开销

二,静态资源压缩

在数据的传输过程中为了进一步的优化,Nginx引入第三方压缩模块gzip,对传输的资源进行压缩减少数据的传输体积,提高传输的效率

在Nginx中对静态资源压缩可以在http块,server块,location块等三个块中

Nginx静态资源压缩主要涉及3个第三方模块:

  • ngx_http_gzip_module模块(nginx内置安装)
  • ngx_http_gzip_static_module模块
  • ngx_http_gunzip_module模块

一,Gzip模块配置指令

1,gzip指令:该指令用于开启或者关闭gzip功能,使用gzip都必须开启该功能

语法 gzip on | off
默认值 gzip off
配置位置 http块,server块,location块

2,gzip_type指令:该指令可以根据响应页的MIME类型选择性地开启gzip压缩功能

gzip_type所选择的值可以从mime.types文件中进行查找,也可以使用"*"代表所有

语法 gzip_types mime-type
默认值 gzip_types text/html
配置位置 http块,server块,location块

例:

http{
    gzip_types application/javascript
}

3,gzip_comp_level指令:该指令用于设置Gzip压缩的程度,级别从1-9,1表示要求程度最低,要求效率最高,9则相反,但是效率最低最费时间(一般压缩级别为6)

语法 gzip_comp_level level
默认值 gzip_comp_level 1
配置位置 http块,server块,location块

4,gzip_vary指令:该指令用于设置使用gzip进行压缩发送是否携带"Vary:Accept-Encoding"的响应头部,主要是告诉接收方,所发送的数据经过了Gzip压缩处理

语法 gzip_vary on|off
默认值 gzip_vary off
配置位置 http块,server块,location块

5,gzip_buffers指令:该指令用于处理请求压缩的缓冲区数量和大小

其中number指定nginx服务器向系统申请缓存空间个数,size指定每一个缓冲空间的大小,主要实现申请number个每个大小为size的缓冲区,这个值一般和操作系统相关,使用默认值即可

语法 gzip buffers number size
默认值 gzip_buffer 32 4k | 16 8K
配置位置 http块,server块,location块

6,gzip_disable指令:针对不同种类客户端发起的请求,可以选择性的开启和关闭gzip功能

regex:根据客户端的浏览器标志(user-agent)来设置,支持使用正则表达式,指定的浏览器标志不使用gzip,该指令可以排除一些明显不支持gzip的浏览器

语法 gzip_disable regex……
默认值 gzip_disable -
配置位置 http块,server块,location块

例:

gzip_disble "MSIE [1-6]\." 

7,gzip_http_version指令:针对不同的http协议版本,可以选择性地开启和关闭gzip功能

该指令使用gzip的http最低版本,该指令一般采用默认值即可

语法 gzip_http_version 1.0 | 1.1
默认值 gzip_http_version 1.1
配置位置 http块,server块,location块

8,gzip_min_length:该指令针对传输数据的大小,可以选择性地开启和关闭gzip功能

gzip压缩功能对大数据的压缩效果明显,但是如果要压缩的数据比较小的话,可能出现越压缩数据量越大的情况,因此需要根据响应内容的大小来决定是否使用gzip功能,响应页面的大小可以通过头信息中的content-Length来获取

注:如果Chunk编码动态压缩,该指令将被忽然,建议设置为1k以上

语法 gzip_min_length length
默认值 gzip_min_length 20
配置位置 http块,server块,location块

9,gzip_proxied指令:该指令设置是否对nginx服务器对后台服务器返回的结果进行gzip压缩

语法 gzip_proxied  off | expired |no-cache | no-store | private |no_last_modified |no_etag | auth |any 
默认值 gzip_proxied off
配置位置 http块,server块,location块

参数:

  • any:无条件启动压缩
  • auth:启用压缩,如果header头中不包含"ETag"头信息
  • off:关闭nginx服务器对后台服务器的返回结果进行gzip压缩
  • ……

二,Gzip和sendfile共存问题

Gzip的压缩是在应用程序中进行压缩的,但是开启sendfile之后,在读取磁盘上的静态资源文件的时候,可以减少拷贝次数,可以不经过应用程序的用户进程而将静态资源文件直接通过系统的网络设备直接进行发送,但是gzip要想对资源进行压缩则必须经过应用程序的用户进程,所以连者产生了冲突

对于共存问题gzip提供了ngx_http_gzip_static_module模块(需要单独安装)的gzip_static指令进行解决

一,添加ngx_http_gzip_static_module模块

1,查询当前nginx的配置参数

nginx -V

2,将nginx安装目录的sbin目录中的nginx启动文件进行更名

cd /usr/local/nginx/sbin
mv nginx nginxwql

3,进入nginx的源码包目录(usr是安装目录这里是你之前解压的目录)

cd /root/nginx/core/nginx-1.17.1

4,执行make clean清空之前编译的内容

make clean

5,使用configure来配置参数

./configure 这里要把nginx-v的内容进行添加 --with-http_gzip_static_module

6,使用make进行重新编译

make

7,将pbjs目录下的nginx二进制执行文件移动到nginx安装目录下的sbin目录中

mv ogjs/nginx /usr/local/nginx/sbin

8,执行更新命令

make upgrade

二,gzip_static指令解决共存问题

gzip_static:对静态文件进行提前压缩,检查与访问资源同名的.gz文件,response中以gzip相关的header返回.gz文件的内容

语法 gzip_static on|off always
默认值 gzip_static off
配置位置 http块,server块,location块

参数:

  • on:如果浏览器支持压缩文件,就进行压缩文件发送,不支持则发送源文件
  • off:关闭这一功能
  • always:不管浏览器支不支持,都以压缩包的形式进行发送

三,跨域问题

一,同源策略

同源策略本质上是一种由Netscape公司引入浏览器的一种保护策略,它是所有浏览器和WEB服务器都遵循的约定,当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,同源服务器可以直接正常访问目标资源,非同源服务器无法正常直接访问目标资源,会报跨域问题

同源标准:协议,域名(IP),端口三者相同即为同源

同源策略的目的:保证用户信息的安全,防止不良网站对资源的恶意窃取

非同源的限制:

  1. 无法获取非同源网页的DOM信息
  2. 无法读取非同源的Session,Cookie等响应头信息
  3. 向非同源地址发送AJAX请求目标资源,会出现拒绝访问和跨域错误

注:本质上无同源就无跨域

同源的判断:是否同源判断协议,域名(IP),端口三要素

URL1
URL2
说明
是否同源
http://wql.luoqin.ltd/nginx/wql.html
协议,域名,端口(默认80)都相同
http://wql.luoqin.ltd/nginx
http://wql.luoqin.ltd:6666/nginx
协议,域名相同,端口不同
http://wql.luoqin.ltd/nginx
https://wql.luoqin.ltd/nginx
域名,端口相同,协议不同
http://wql.luoqin.ltd/nginx
http://fq.luoqin.ltd/nginx
协议,端口相同,域名不同
http://wql.luoqin.ltd/nginx
http://luoqin.ltd/nginx
协议,端口相同,主域名相同,子域名不同

二,跨域问题

跨域问题就是非同源服务器互相调用资源出现的问题

跨域问题描述:有两台服务器,分别为A,B,如果从服务器A的页面发送异步AJAX请求到服务器B获取数据,如果服务器A和服务器B不满足同源策略则会出现跨域问题

一,Nginx演示跨域问题

分别部署两台虚拟机分别安装nginx真实演示挺麻烦,所有我们有不同的server块演示跨域问题

1,准备一个html文件发送ajax请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>跨域演示</title>
    <script src="jquery-3.2.1.min.js" type="application/javascript"></script>

    <script>
        $(function () {
            $("#wql").click(function () {

                //获取192.168.68.133:8888/getdata的json数据
                $.get("http://192.168.68.133:8888/getdata",function (data) {
                    alert(data);
                });
            });});
    </script>
</head>

<body>
<input type="button" id="wql" value="获取非同源数据"></body>
</body>
</html>

2,创建两个server块分别监听不同的端口(端口不同非同源)

#监听8888端口,提供/getdata返回json数据
server {
        listen       8888;
        server_name  192.168.68.133;
    
        location / {
            root   html;
            index  index.html index.htm;
        }
        location /getdata{
        default_type application/json;
        return 200 "WQL";
        }
    }
//监听80端口,获取html目录的fq.html页面
    server {
        listen 80;
        server_name 192.168.68.133;
        location /fq.html{
        root html;
}

3,浏览器演示

二,解决Nginx跨域问题

解决nginx跨域问题只需要通过add_header指令添加跨域头信息即可

add_header Access-Control-Allow-Origin IP地址;
add_header Access-Control-Allow-Methods 请求类型;
  • Access-Control-Allow-Origin:允许指定的服务器访问,*代表所有服务器都能跨域访问
  • Access-Control-Allow-Methods:允许什么请求访问

1,添加配置文件

location /getdata{

        add_header Access-Control-Allow-Origin http://192.168.68.133;

        add_header Access-Control-Allow-Methods GET,POST,PUT.DELETE;

        default_type application/json;

        return 200 "WQL";

        }

2,访问

四,Nginx防盗链

一,演示防盗链效果

分别从爱图网和京东找到两个图片链接,它们分别都是能访问的,我们写一个html,并把它放盗nginx中,进行访问

1,写一个html,加如两张图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>防盗链演示</title>
</head>
<body>
    <!--爱图网的图片-->
    <img src="http://img.aiimg.com/uploads/allimg/210820/63915-210R00H020.jpg">
    <!--京东的图片-->
    <img src="https://img11.360buyimg.com/ceco/s600x600_jfs/t1/126663/31/12341/83168/5f58b7fbE1e7b3333/f0c9c03054652024.jpg!q70.jpg">
</body>
</html>

2,将文件命名为wql.html并放到nginx的html目录中

3,配置nginx.cong的server块(添加)

server {
        listen 80;
        server_name 192.168.68.133;
        location /wql.html{
       root html;
}

4,访问

 

二,防盗链的原理

防盗链依赖于HTTP的头信息Referer,当浏览器向web服务器发送请求时,会携带referer,它包含原网页链接,通过这个这个告诉服务器你是从那个网页跳转过来

后台服务器根据获取到的Referer信息判断是否为自己信任的网站地址,如果是则通过访问,如果不是则返回403拒绝访问

三,nginx防盗链配置

nginx防盗链通过valid_refereres指令实现

valid_referers:nginx通过获取浏览器请求头中的referer的值,与valid_referers后面的内容进行匹配,如果匹配到就将$invalid_referer变量置为0,如果没有匹配到则将$invalid_referer置为1,匹配过程不区别大小写

语法 valid_referers none | blocked |server_names |string……
默认值 -
配置位置 server块,location块

参数:

  • none:如果请求头信息referer为空,允许访问(默认不允许)
  • blocked:在头信息中Referer不为空,但该值被防火墙或者代理伪装,如果不带http或https等协议头的资源允许访问
  • serevr_names:指定具体可访问的域名或者IP
  • string:支持正则表达式和*的字符串,如果是正则表达式,需要以~开头

例:指定域名www.wql.com和空referer才能访问

server {

    listen 80;
    server_name 192.168.68.133;
    location /{
    valid_referers nono blocked www.wql.com;
    if($invalid_referer){

    return 403;
}
    root html
}}