Nginx 进阶篇

Posted A-L-Kun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx 进阶篇相关的知识,希望对你有一定的参考价值。

Nginx 进阶篇

五、 服务配置

经过前面的操作,我们会发现,如果想要启动、关闭或重新加载nginx配置文件,都需要先进入nginx的安装目录的sbin目录,然后使用nginx的二进制可执行文件来操作,相对来说比较繁琐,那这块该如何优化呢?另外如果我们想要吧Nginx设置成随着服务器启动就自动完成启动操作,又该如何实现?

1、 配置成系统服务

把Nginx应用服务器设置成为系统服务,方便对Nginx服务的启动和停止等相关操作,具体实现步骤:

  1. 添加服务:

    cat << EOF > /usr/lib/systemd/system/nginx.service 
    [Unit]
    Description=nginx web service
    Documentation=http://nginx.org/en/docs/
    After=network.target
     
    [Service]
    Type=forking
    PIDFile=/usr/local/nginx/logs/nginx.pid
    ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
    ExecStart=/usr/local/nginx/sbin/nginx
    ExecReload=/usr/local/nginx/sbin/nginx -s reload
    ExecStop=/usr/local/nginx/sbin/nginx -s stop
    PrivateTmp=true
     
    [Install]
    WantedBy=default.target
    EOF
    
  2. 修改文件的权限:

    chmod 755 /usr/lib/systemd/system/nginx.service
    
  3. 常用命令:

    启动: systemctl start nginx
    停止: systemctl stop nginx
    重启: systemctl restart nginx
    重新加载配置文件: systemctl reload nginx
    查看nginx状态: systemctl status nginx
    开机启动: systemctl enable nginx
    

如果是使用yum来安装的话,则已经配置好这些

2、 配置环境变量

前面我们介绍过nginx安装目录下的二进制可执行文件nginx的很多命令,要想使用这些命令前提是需要进入sbin目录下才能使用,很不方便,如何去优化呢?我们可以将二进制可执行文件加入到系统环境变量中,这样的话,在任何目录都可以使用nginx对应的相关命令。

cat << EOF >> /etc/profile
export PATH="$PATH:/usr/local/nginx/sbin"
EOF
source /etc/profile
nginx -v

六、 部署静态资源

1、 概述

上网去搜搜索访问资源对于我们并不陌生,通过浏览器发送一个HTTP请求实现从客户端发送请求到服务器端获取所需要的内容后并把内容回显展示在页面的一个过程。这个时候,我们所请求的内容分为两种类型:一类是静态资源,一类是动态资源。

  • 静态资源即指在服务器端真实存在并且能够拿来展示的一些文件,比如常见的html,css,js,image,video等
  • 动态资源即指在服务端真实存在但是要想获得需要经过一定的业务逻辑处理,根据不同的条件展示在页面不同的内容,比如说报表数据展示,根据当前登录用户展示相关具体数据等资源

2、 配置指令

指令可以通过官方文档来进行学习:https://nginx.org/en/docs/

2.1 listen

listen指令:用来配置监听端口

语法 默认值 位置
listen address[:port] [default_server]...
listen port [default_server]...
`listen *:80 *:8000`

listen的设置比较灵活,default_server属性是标识符,用来将此虚拟主机设置成默认主机。所谓默认主机指的是如果没有匹配到对应的address:port,则会默认执行的。如果不指定默认使用的是第一个server

server 
	listen 8080;
	server name 127.0.0.1;
	location / 
		root html
		index index.html;
	

server 
	listen 8080 default_server;  # 设置为默认的服务,但所有服务不匹配时,会使用这个服务

2.2 server_name

server_name指令:用来设置虚拟主机服务名称

127.0.0.1locahost,域名

语法 默认值 位置
server_name name ...; server_name: ""; server

关于server_name的配置方式有三种,分别是:

  • 精确匹配

    server 
    	listen 80;
    	server_name www.liuzhongkun.com www.liuzhongkun.cn;
    	...
    
    
  • 通配符匹配

    server 
    	listen 80;
    	server_name *.liuzhongkun.*;  # 注意,通配符只能出现在首段或者尾端,不能出现在中间位置
    
    
  • 正则表达式匹配

    其可以使用正则表达式,并且使用~最为正则表达式字符串的开始标记。

    server 
    	listen 80;
    	server_name ~^www\\.(\\w+)\\.com$;  # 注意,~后面不能加空格
    	...
    	location / 
    		return 200 "==>access==>>$1";  # 这个$1获取上面正则匹配的括号里面的东西
    	
    
    
  • 匹配执行顺序

    由于server_name指令支持通配符和正则表达式,因此在多个虚拟主机的配置文件中,可能会出现一个名称被多个虚拟主机匹配成功的情况。

    1. 准确匹配的server_name
    2. 通配符在开始时匹配server_name
    3. 通配符在结束时匹配server_name
    4. 正则表达式匹配server_name
    5. 被默认的default_server处理,如果没有指定默认,则找第一个server

2.3 location

location指令:用来设置请求的url

语法 默认值 位置
`location [= ~ ~*

uri变量是待匹配的请求字符串,可以不包含正则表达式,也可以包含正则表达式,那么nginx服务器在搜索匹配location的时候,是先使用不包含正则表达式进行匹配,找到一个匹配度最高的一个,然后在通过包含正则表达式的进行匹配,如果能匹配到直接访问,匹配不到,就使用刚才匹配度最高的那个location来处理请求。。

属性介绍:

  • 不带符号,,要求必须以指定模式开始

    server 
    	listen 80;
    	server_name 127.0.0.1;
    	location /abc 
    		default_type text/plain;
    		return 200 "access success";
    	
    
    # 127.0.0.1/abc 
    # 127.0.0.1/abc?p=1 
    # 127.0.0.1/abc/  
    
  • =:用于不包含正则表达式的uri前,必须与指定的模式精确匹配

    server 
    	listen 80;
    	server_name 127.0.0.1;
    	location =/abc 
    		default_type text/plain;
    		return 200 "access success";
    	
    
    # 127.0.0.1/abc 
    # 127.0.0.1/abc?p=1 
    # 127.0.0.1/abc/ 这个是访问不到的
    
  • ~[*]:用于表示当前uri中包含了正则表达式,并且区分大小写;如果加了星号,则其为不区分大小写的

    server 
    	listen 80;
    	server_name 127.0.0.1;
    	location ~^/abc\\w$ 
    		default_type text/plain;
    		return 200 "access success";
    	
    
    # 127.0.0.1/abc 
    # 127.0.0.1/abcf
    # 127.0.0.1/abc?p=1 
    # 127.0.0.1/abc/ 这个是访问不到的
    
  • ^~:用于不包含正则表达式的uri前,功能和不加符号的一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了

2.4 root

root:设置请求的根目录

语法 root path
默认值 root html
位置 http、server、location

path:其为Nginx服务器接收到请求以后查找资源的根目录路径

2.5 alias

其作用为用来更改location的URI

语法 默认值 位置
alias path - location

path:其为修改后的根目录

比如:

  1. /usr/local/nginx/html目录下创建一个images目录,并在目录下放入一张图片1.png

    location /images 
    	root html;
    
    

    访问图片的路径为:http:locahost/images/1.png

  2. 如果把root改为alias

    location /images 
    	alias html;
    
    

    再次访问该地址时,页面会出现404的错误,查看日志会法案现是因为地址不对,其访问的地址为:/usr/local/nginx/html/1.png,如果需要修改的话,则:alias html/images

root的处理结果就是:root 路径+ location 路径

alias的处理结果就是:使用 alias 路径替换 location 路径

2.6 index

index:设置网站的默认首页

语法 默认值 位置
index file... index index.html http、server、location

index后面可以跟多个设置,如果访问的时候没有指定具体访问的资源,则会依次进行查找,找到第一个为止。

如:

location / 
            root   html;
            index  index.html index.htm;
        

访问该location的时候,可以通过 http://localhost:port/,地址后面如果不添加任何内容,则默认依次访问 index.html、index.htm ,找到第一个来进行访问。

2.7 error_page

error_page:设置网站的错误页面

语法 默认值 位置
error_page code ...[=[response]] uri; - htttp、server、location ...

当出现对应的响应code之后,如何来处理;

  • 可选项=[response]的作用是用来将对应代码更改为另外一个响应,这个是修改返回的响应状态码
  • 如:error_page 404 =200 http://www.baidu.com

比如:

  1. 指定具体的网址:

    error_page 404 http://www.baidu.com;
    
  2. 进行重定向:

    server 
        error_page 500 502 503 504 /50x.html;
        location =/50x.html 
        	root html;
        
    
    
  3. 使用location的#符号完成错误信息提示:

    server 
    	error_page 404 @jump_to_error;
        location @jump_to_error 
        	default_type text/plain;
            return 404 \'Not Fount Page...\'
        
    
    

3、 静态资源优化配置语法

Nginx 对静态资源如何进行优化配置。这里从三个属性配置进行优化:

sendfile on;
tcp_nopush on;
tcp_nodeplay on;
  1. sendfile:用来开启高效的文件传输模式

    语法 默认值 位置
    sendfile on | off; sendfile off; http、server、location

    请求静态资源的过程:客户端通过网络接口向服务端发送请求,操作系统将这些客户端的请求传递给服务端应用程序,服务端应用程序会处理这些请求,,请求处理完成以后,操作系统还需要将处理得到的结果通过网络适配器传递回去。

  2. tcp_nopush:该指令必须在 sendfile 打开的状态下才会生效,主要是用来提升网络包的传输效率。

    语法 默认值 位置
    tcp_nopush on | off; tcp_nopush off; http、server、location
  3. tcp_nodelay:该指令必须在 keep-alive 连接开启的情况下才生效,来提高网络包传输的实时性。

    语法 默认值 位置
    tcp_nodelay on | off; tcp_nodelay on; http、server、location

这三个指令都开启的好处是,sendfile 可以开启高效的文件传输模式,tcp_nopush 开启可以确保在发送到客户端之前数据包已充分填满,tcp_nodelay 强制套接字发送数据包。

4、 静态资源压缩模块

在 Nginx 配置文件中可以通过配置 gzip 来对静态资源进行压缩,相关的指令可以配置在 http、server、location 中,Nginx可以通过:

ngx_http_gzip_module 
ngx_http_gzip_static_module
ngx_http_gungzip_module

4.1 Gzip 模块配置指令

接下来所学习的指令都来自于 ngx_http_gzip_module 模块,该模块会在 Nginx 安装的时候内置到 Nginx 的安装环境中,也就是说,我们可以直接使用这些命令:

  1. gzip 命令:

    语法 默认值 位置
    gzip on | off; gzip off; http、server、location ...

    只有这个指令处于打开状态,下面的指令才有效果

  2. gzip_types:该指令可以根据响应也的 MIME 类型选着性地开启 Gzip 压缩功能

    语法 默认值 位置
    gzip_types mime-type ...; gzip_types text/html; http、server、location

    所选择的值也可以使用 * 号来替代,开发过程中不建议这样使用。

  3. gzip_comp_level:该指令用于设置 Gzip 压缩程度,级别为 1~9 ;程度最低,则效率最高。

    语法 默认值 位置
    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:该指令用于处理请求压缩的缓冲区数量和大小。

    语法 默认值 位置
    gzip_buffers number size; gzip_buffers 32 4k | 16 8k; http、server、location

    参数:

    • number:指定Nginx服务器向系统申请缓存空间个数
    • size:每个缓存空间的大小
  6. gzip_disable:针对不同种类客户端发起的请求,可以选择性的开启或关闭 Gzip 功能

    语法 默认值 位置
    gzip_disable regex ...; - http、server、location

    regex:根据客户端的浏览器请求头来设置,支持使用正则表达式,如:gzip_disable "MSIE [1-6]\\.";

  7. gzip_http_version:针对不同的 HTTP 协议版本,可以选择性地开启或关闭 Gzip 功能

    语法 默认值 位置
    gzip_http_version 1.0 | 1.1; gzip_http_version 1.1; http、server、location
  8. gzip_min_length:该指令针对传输数据的大小,可以选择性地开启或关闭 Gzip 功能

    语法 默认值 位置
    gzip_min_length length; gzip_min_length 20; http、server、location

    Gzip 压缩功能对大数据的压缩效果明显,但是如果压缩的数据比较小的话,可能会出现压缩数据量越大的情况,这个单位是 bytes。

  9. gzip_proxied:该指令设置是否对服务端返回的结果进行 Gzip 压缩

    语法 默认值 位置
    gzip_proxied off | expired | no-cache |
    no-store | private | no_last_modified |
    no-etag | auth | any;
    gzip_proxied off; http、server、location

    表现出来的形式就是头部信息的不一样,如:no-cache的 header 中包含 Cache-Control:no-cache信息,以此类推。

4.2 配置实例

gzip on;  # 开启 gzip 功能
gzip_types *;  # 压缩元文件类型,根据具体的访问资源类型设定
gzip_comp_level 6;  # gzip 压缩级别
gzip_min_length 1024;  # 进行压缩响应页面的最小长度,content-length
gzip_buffers 4 16k;  # 缓存空间大小
gzip_http_version 1.1;  # 指定亚胡搜响应所需要的最低 HTTP 请求版本
gzip_vary on;  # 往头部信息中添加压缩标识
gzip_disable "MISE [1-6]\\.";  # 对 IE6 以下的版本都不进行压缩
gzip_proxied off;  # nginx 作为反向代理压缩服务端返回数据的条件

这些配置在很多地方可能都会用到,所以我们可以将这些内容抽取到一个配置文件nginx_gzip.conf中,然后通过 include 指令把配置文件再次加载到 nginx.conf 配置文件中,方便使用。

include nginx_gzip.conf;

4.3 Gzip 和 sendfile

在我们使用 sendfile 的时候,我们提到过,开启 sendfile 以后,在读取磁盘上的静态资源文件通过网络设备发送出去,但是 Gzip 要想对资源压缩,是需要经过用户进程进行操作的。所以如何解决两个设置共存的问题呢?

  • 这里我们可以使用 ngx_http_gzip_static_module 模块的 gzip_static 指令来解决。

gzip_static

作用:检测和访问资源同名的 .gz 文件时,,response 中移 gzip 相关的 header 返回 .gz 文件的内容

语法 默认值 位置
gzip_static on | off | always; gzip_static off; http、server、location

添加上述命令后,会报一个错误,unkonwn directive "gzip_static"

  • 主要原因是 Nginx 默认是没有添加 ngx_http_gzip_static_module 模块。

  • 添加方式:

    nginx -V  # 查看当前 Nginx 的配置参数,获取到原来编译的参数
    mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old  # 将 Nginx 安装目录下 sbin 目录中的 Nginx 二进制文件进行改名
    cd /root/nginx/croe/nginx-1.22.1  # 进入安装目录
    make clean  # 清空之前编译的内容
    ./configure old_args  --with-http_gzip_static_module  # 使用 configure 来配置参数
    make  # 使用命令进行编译以及安装
    mv objs/nginx /usr/local/nginx/sbin  # 将生成的二进制文件移动到 Nginx 安装目录下
    make upgrade  # 执行更新命令
    

5、 静态资源的缓存处理

5.1 缓存处理过程

具体可以查看这篇文章:https://www.imooc.com/article/302614

HTTP协议中和页面缓存相关的字段,我们首先来认识一下:

header 说明
Expires 缓存过期的日期和时间
Cache-Control 设置缓存相关的配置信息
Last-Modified 请求资源最后修改的时间
ETag 请求变量的实体标签和当前值,比如文件的 MD5 值

5.2 缓存相关指令

Nginx 需要进行缓存的相关设置,就需要用到如下的指令:

expires

作用:用来控制页面缓存的作用,可以通过该指令控制 HTTP 应答中的 “Expires” 和 “Cache-Control”

语法 默认值 位置
expires [modified] time;
expires epoch | max | off;
expires off; http、server、location

参数:

  • time:可以整数也可以是负数,指定过期时间,如果是负数,Cache-Control 则为 no-cache ,如果为整数或 0,则 Cache-Control 的值为 max-age=time;
  • epoch:指定 Expires 的值为 \'1 January,1970,00:00:01 GMT\',Cache-Control 的值为 no-cache
  • max:指定 Expires 的值为 \'31 December2037 23:59:59 GMT\',Cache-Control 的值为 10 年
  • off:默认不缓存

add_header

作用:用来添加指定的响应头和响应值

语法 默认值 位置
add_header name value [always]; - http、server、location...

这里是用来解决跨域问题:

  • 需要添加两个头信息

    1. 允许跨域访问的原地址信息:Access-Control-Allow-Origin

      可以配置多个(多个用逗号分割),也可以使用 * 代表所有源

    2. 允许跨域访问的请求方式:Access-Control-Allow-Methods

      根据需要设置,GET,POST,PUT,DEETE ...

6、 静态资源防盗链

什么是资源盗链?

  • 资源盗链指的是此内容不在自己服务器上,而是通过技术手段,绕过别人的限制将别人的内容放到自己页面上最终展示给用户。以此盗取大网站的空间和流量。简而言之,就是用别人的东西,成就自己的网站。

Nginx 防盗链实现原理:

  • 后台服务器可以根据获取到 Referer 信息来判断是否为自己信任的网站地址,如果是则放行继续访问,如果不是则可以返回 403 的状态信息

Nginx 防盗链的具体实现:

vaild referers:Nginx 会通过查看 referer 自动和 vaild_referers 后面的内容进行匹配,如果匹配到了就将变量 $invaild_referer = 0,否则该变量的值为1

语法 默认值 位置
vaild_referers none | blocked | server_names | string ... - server、location

参数:

  • none:如果 Header 中的 Referer 为空,允许访问
  • blocked:在 Header 中的 Referer 不为空,但是该值被防火墙或代理进行伪装过,如不带 \'http://\' 等协议头的资源允许访问
location ~ .*\\.(png|jpg|gif)$ 
    vaild_referers none blocked www.baidu..com 
    if ($invaild_referer) 
        return 403;
    
    root html/images;

如果我们的图片很多,该如何批量进行防盗链呢?

  • 我们可以对一个目录下的所有资源进行操作
  • 但是,Referer 的限制比较粗,比如随意加一个 Referer ,上面的方式是无法进行限制的,那这个问题该如何解决呢?
    • 我们需要使用到 Nginx 的第三方模块 ngx_http_accesskey_module

7、 Rewrite 功能配置

Rewrite 是 Nginx 服务器提供的一个重要基本功能,是 web 服务器产品中几乎必备的功能。主要的作用是用来实现 URL 的重写

  • Nginx 使用的是 ngx_http_rewrite_module 模块来解析和处理 Rewrite 功能的相关配置

7.1 相关指令

  1. set

    该指令用来设置一个新的变量:

    语法 默认值 位置
    set $variable value; - server、http、if

    variable:变量名称,该变量名称需要使用 $ 作为变量的第一个字符,且不要与 Nginx 服务器预设的全局变量同名

    value:变量的值,可以是字符串、、其他变量或变量的组合等

    全局变量:https://blog.csdn.net/ljl890705/article/details/80169734

    • 这些全局变量可以在 log_format中使用
  2. if

    该指令用来支持条件判断,并根据条件判断结果选择不同的 Nginx 配置

    语法 默认值 位置
    if (condition)... - server、location

    使用示例:

    if ($request_method = POST) 
    	return 405;
    
    

    注意:

    • 如果变量名对应的值为空字符串或为0,if 判断为 FALSE
    • 使用 = 或者 != 比较变量和字符串是否相等
    • if 和括号之间需要有一个空格

    正则表达式匹配

    匹配成功返回 true,失败返回 false。变量与正则表达式之间使用 "~", "~*", "!~", "!~*" 来连接。

    • "~" 代表匹配正则表达式过程中区分大小写
    • "~*" 代表匹配真正则表达式过程中不区分大小写
    • "!~" 和 "!~*" 刚好和上面区相反值,如果匹配成功返回 false
    if ($http_usr_agent ~ MSIE) 
    	# 如果 user_agent 中包含 MSIE 字符串
    
    

    注意:正则表达式字符串一般不需要加引号,但是如果字符串中包含 "" 或者 ";" 等字符时,就需要把引号加上

    判断请求文件是否存在时,使用"-f" 和 "!-f":

    if (-f $request_filename) ...  # 判断文件是否存在
    

    判断请求的目录是否存在时,使用"-d" 和 "!-d"

    判断请求的目录或者文件是否存在时,使用"-e" 和 "!-e"

    判断请求的文件是否可执行时,使用"-x" 和 "!-x"

  3. break

    该指令用于中断当前相同作用域中的其他 Nginx 配置。与该指令处于同一作用域的 Nginx 配置中,位于它前面的指令配置生效,位于后面的指令配置无效。并且 break 还有另外一个功能就是终止当前的匹配并把当前的 URI 在本 location 进行重定向访问处理。

    location / 
        defaule_type text/html;
        if ($args) 
        	set $username Mike;
            break;
            set $username Nick;
        
        return 200 $username;
    
    
  4. return

    该指令用于完成对请求的处理,直接向用户端返回。在 return 后的所有 Nginx 配置都是无效的。

    语法 默认值 位置
    return code [text];
    return code URL;
    return URL;
    - server、location、if

7.2 rewrite 指令

7.2.1 rewrite

该指令通过正则表达式的使用来改变 URI。可以同时存在一个或者多个指令,按照顺序依次对 URL 进行匹配处理。

语法 默认值 位置
rewrite regex replacement [flag]; - server、location、if
location /rewrite 
    rewrite ^/rewrite/url\\w*$ https://www.baidu.com;
    rewrite ^/rewrite/(test)\\w*$ /$1;  # 括号使用的是分组的方法,这里面是前往/test

flag:用来设置 rewrite 对 URI 的处理行为,可选值: