Nginx高级应用(四)

2017年11月16日18:37:04 发表评论 621 views

第1章 Nginx技术深入剖析

1.1 Nginx软件功能模块说明

1.1.1 Nginx核心功能模块

Nginx核心功能模块负责Nginx的全局应用,主要对应主配置文件的Main区块和Events区块区域,这里有很多Nginx必须的全局参数配置。

1.1.2 标准的http功能模块

Nginx http功能模块 模块说明
ngx_http_core_module 包括一些核心http参数配置,对应Nginx的配置为HTTP区块部分
ngx_http_access_module 访问控制模块,用来控制网站用户对Nginx的访问
ngx_http_gzip_module 压缩模块,对Nginx返回的数据压缩,属于性能优化模块
ngx_http_fastcgi_module FastCGI模块,和动态应用相关的模块,例如PHP
ngx_http_proxy_module proxy代理模块
ngx_http_upstream_module 负载均衡模块,以实现网站的负载均衡功能及节点的健康检查
ngx_http_rewrite_module URL地址重写模块
ngx_http_limit_conn_module 限制用户并发连接数及请求数模块
ngx_http_limit_req_module 根据定义的key限制Nginx请求过程的速率
ngx_http_log_module 访问日志模块,以指定的格式记录Nginx客户访问日志等信息
ngx_http_auth_basic_module Web认证模块,设置Web用户通过账号、密码访问Nginx
ngx_http_ssl_module SSL模块,用于加密的HTTP连接,如https
ngx_http_stub_status_module 记录Nginx基本访问状态信息等的模块

1.2 Nginx目录结构说明

[[email protected] nginx]# tree /application/nginx
.
├── client_body_temp
├── conf                             #这是Nginx所有配置文件的目录,极其重要
│   ├── fastcgi.conf                #fastcgi相关参数的配置文件
│   ├── fastcgi.conf.default        #fastcgi.conf的原始备份
│   ├── fastcgi_params              #fastcgi的参数文件
│   ├── fastcgi_params.default
│   ├── koi-utf
│   ├── koi-win
│   ├── mime.types                  #媒体类型
│   ├── mime.types.default
│   ├── nginx.conf                  #这是Nginx默认的主配置文件
│   ├── nginx.conf.default
│   ├── scgi_params                 #scgi相关参数文件,一般用不到
│   ├── scgi_params.default
│   ├── uwsgi_params                #uwsgi相关参数文件,一般用不到
│   ├── uwsgi_params.default
│   └── win-utf                    
├── fastcgi_temp                     #fastcgi临时数据目录
├── html                             #这是编译安装时Nginx的默认站点目录,类似Apache的默认站点htdocs目录
│   ├── 50x.html                    #错误页面优雅替代显示文件
│   └── index.html                  #默认的首页文件,首页文件名字在nginx.conf中事先定义好的
├── logs                             #这是Nginx默认的日志路径,包括错误日志及访问日志
│   ├── access.log                  #默认访问日志文件
│   ├── error.log                   #错误日志文件
│   └── nginx.pid                   #Nginx的Pid文件,进程启动后,会将所有进程的ID号写入这里
├── proxy_temp                       #临时目录
├── sbin                             #Nginx命令的默认目录,只有nginx一条命令
│   └── nginx
├── scgi_temp                        #临时目录
└── uwsgi_temp                       #临时目录

9 directories, 21 files

提示:所有结尾为default的文件都是备份文件。

1.3 Nginx主配置文件nginx.conf

它位于Nginx安装目录下的conf目录中,整个配置文件以区块的形式组织的。

Nginx高级应用(四)

1.3.1 nginx.conf配置文件详解

Nginx高级应用(四)

1.3.2 Nginx其他配置文件

如果是配合动态服务(例如PHP服务),Nginx软件还会用到扩展的FastCGI相关配置文件,这个配置是通过在nginx.conf主配置文件中嵌入include命令来实现的,不过默认情况是注释状态,不会生效。

[[email protected] conf]# cat fastcgi.conf

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

第2章 Nginx location

2.1 location作用

location指令的作用是根据用户请求的URI来执行不同的应用。其实就是根据用户请求的网站地址URL进行匹配,匹配成功即进行相关操作。

2.2 location语法

Syntax:   location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default:  —
Context:  server, location

2.2.1 语法说明

location [=|~|~*|^~|@] uri {...}
指令 匹配标识 匹配的网站网址 匹配URI后要执行的配置段
  • 其中URI可以是普通的字符串地址路径或者是正则表达式,匹配成功则执行后面大括号里的相关指令。
  • “~”用于区分大小写(大小写敏感)的匹配,“!~”表示取反
  • “~*”用于不区分大小写的匹配,“!~*”表示取反
  • “^~”在进行常规的字符串匹配检查之后不做正则表达式的检查

2.3 location匹配示例

location = / {                      #用户请求/时,配置configuration A
    [ configuration A ]
}

location / {                        #用户请求/index.html时,配置configuration B
    [ configuration B ]
}

location /documents/ {              #用户请求/documents/document.html时,配置configuration C
    [ configuration C ]
}

location ^~ /images/ {              #用户请求/images/1.gif时,配置configuration D
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {     #用户请求/documents/1.jpg时,配置configuration E
    [ configuration E ]
}

  • 不同URI对应的配置情况:
用户请求的URI 完整的URL地址 匹配的配置
/ http://blog.leon.com/ configuration A
/index.html http://blog.leon.com /index.html configuration B
/documents/document.html http://blog.leon.com /documents/document.html configuration C
/images/1.gif http://blog.leon.com /images/1.gif configuration D
/documents/1.jpg http://blog.leon.com /documents/1.jpg configuration E

2.4 location配置实战

2.4.1 编辑www.conf配置文件

[[email protected] extra]# vim www.conf
    server {
        listen       80;
        server_name  www.leon.com www.leon.shadow.com;
        root   html/www;
            location / {
                return 401;
            }
            location = / {
                return 402;
            }
            location /documents/ {
                return 403;
            }
#匹配任何以/images/开头的查询并且停止搜索。任何正则表达式匹配将不会被检查。
#“^~”的作用是在常规的字符串匹配检查之后不做正则表达式的检查,即如果最明确的那个字符串匹配的location配置中由此前缀,那么不做正则表达式的检查。
            location ^~ /images/ {
                return 404;
            }
#匹配任何以gif、jpg或jpeg结尾的请求
            location ~* \.(gif|jpg|jpeg)$ {
                return 500;
            }
        access_log  logs/access_www.log  main;
   }

2.4.2 检查并重启配置

[[email protected] extra]# nginx -t
nginx: the configuration file /application/nginx-1.10.3/conf/nginx.conf syntax is ok
nginx: configuration file /application/nginx-1.10.3/conf/nginx.conf test is successful
[[email protected] extra]# nginx -s reload

2.4.3 测试结果

[[email protected] extra]# curl -s -o /dev/null -I -w "%{http_code}\n" www.leonshadow.com
402
[[email protected] extra]# curl -s -o /dev/null -I -w "%{http_code}\n" www.leonshadow.com/
402
[[email protected] extra]# curl -s -o /dev/null -I -w "%{http_code}\n" www.leonshadow.com/index.html
401
[[email protected] extra]# curl -s -o /dev/null -I -w "%{http_code}\n" www.leonshadow.com/documents/document.html
403
[[email protected] extra]# curl -s -o /dev/null -I -w "%{http_code}\n" www.leonshadow.com/images/1.gif
404
[[email protected] extra]# curl -s -o /dev/null -I -w "%{http_code}\n" www.leonshadow.com/documents/1.jpg
500

2.5 用户请求的URI说明

用户请求的URI 设置的状态码 说明
当为空或/时 返回402,匹配了

location = / {

return 402;

} 与configuration A一致

=的精确匹配优先级最高,无论放置的顺序如何,它都将优先被匹配并执行。
/index.html或任意不匹配其他location的字符串 返回401,匹配了

location / {

return 401;

} 与configuration B一致

/为默认匹配,即如果没有匹配上其他的location则最后匹配“默认匹配”部分
/documents/document.html 返回403,匹配了

location /documents/ {

return 403;

} 与configuration C一致

此部分为路径匹配,即匹配了路径/documents/,注意后面的/documents/1.jpg表示没有匹配此处的location,而是匹配了结尾的1.jpg
/images/1.gif 返回404,匹配了

location ^~ /images/ {

return 404;

} 与configuration D一致

此部分为路径匹配,但是前面增加了特殊字符^~,所以优先匹配路径,而没有匹配结尾的1.gif
/documents/1.jpg 返回500,匹配了

location ~* \.(gif|jpg|jpeg)$ {

return 500;

} 与configuration E一致

此部分匹配了1.jpg,属于扩展名匹配,虽然有/documents/,但还是匹配了扩展名

2.5.1 URI匹配顺序说明

顺序 不同的URI及特殊字符组合匹配 匹配说明
1 location = / { 精确匹配/
2 location ^~ /images/ { 匹配常规字符串,不做正则匹配检查
3 location ~* \.(gif|jpg|jpeg)$ { 匹配正则
4 location /documents/ { 匹配常规字符串,如果有正则则优先匹配正则
5 location / { 所有location都不能匹配后的默认匹配

第3章 Nginx rewrite

3.1 什么是Nginx rewrite

Nginx rewrite的主要功能也是实现URL地址重写。Nginx的rewrite规则需要PCRE软件的支持,即通过Perl兼容正则表达式语法进行规则匹配。默认参数编译时Nginx就会安装支持rewrite的模块,但是也要有PCRE(pcre、pcre-devel)软件的支持。

3.2 Nginx rewrite语法

指令语法:rewrite <em>regex</em> replacement [<em>flag</em>];
默认值:none
应用位置:server、location、if

rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容重定向到replacement部分内容,结尾是flag标记。

  • URL rewrite跳转示例

rewrite ^/(.*) http://blog.leonshadow.com/$1 permanent;

  • 命令说明:
  1. rewrite:固定关键字,表示开启一条rewrite匹配规则
  2. ^/(.*):regex部分,表示匹配所有
  3. http://blog.leon.com/$1:表示匹配成功后跳转的位置,$1是取regex部分括号里的内容
  4. permanent:是永久301重定向标记

3.3 正则表达式说明

字符 描述
\ 将后面接着的字符标记为一个特殊字符或一个原义字符或一个后向引用。

例如:“\n”匹配一个换行符,序列“\\”和“\$”则匹配“$”

^ 匹配输入字符串的起始位置,如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置
$ 匹配输入字符串的结束位置,如果设置了RegExp对象的Mulitiline属性,$也匹配“\n”或“\r”之前的位置
* 匹配前面的字符零次或多次。例如:ol*能匹配“o”及“olll”,*等价于{0,}
+ 匹配前面的字符一次或多次。例如:ol+能匹配“ol”及“oll”,但不能匹配“o”,.+等价于{1,}
匹配前面的字符一次或多次。例如:“do(es)+”可以匹配“do”或“does”中的“do”,. 等价于{0,1}

当该字符紧跟在任何一个其他限制符(*,+ ,{n},{n},{n,m})的后面时,匹配模式是费贪婪模式的,非贪婪模式会尽可能少地匹配搜索的字符串,而默认的贪婪模式会尽可能多地匹配所搜索的字符串。例如:对于字符串“oooo”,“o+ ”将匹配单个“o”,而“o+”将匹配所有“o”

. 匹配除“\n”之外的任何单个字符,要匹配包括“\n”在内的任何字符,可以使用像“[.\n]”这样的模式
(pattern) 匹配括号内的pattern,并可以在后面获取对应的匹配,常用$0...$9属性获取小括号中的匹配内容。要匹配圆括号字符,可以使用“\(”或“\)”

3.4 rewrite指令flag标记说明

flag标记符号 说明
last 本条规则匹配完成后,继续向下匹配新的location URI规则
break 本条规则匹配完成即终止,不再匹配后面的任何规则
redirect 返回302临时重定向,浏览器地址栏会显示跳转后的URL地址
permanent 返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

last和break用来实现URL重写,浏览器地址栏的URL地址不变,但在服务端访问的路径发生了变化;redirect和permanent用来实现URL跳转,浏览器地址栏会显示跳转后的URL地址。

  • last和break标记的区别:
  1. 使用alias指令时必须使用last标记,使用proxy_pass指令时要使用break标记
  2. last标记在本条rewrite规则执行完毕后,会对其所在的server{......}标签重新发起请求,而break标记则会在本条规则匹配完成后终止匹配,不再匹配后面的规则

3.5 Nginx rewrite的企业应用场景

  • 可以调整用户浏览的URL,使其看起来更规范,合乎开发及产品人员的需求
  • 为了让搜索引擎收录网站内容,并让用户体验更好,企业会将动态URL地址伪装成静态地址提供服务
  • 网站换新域名后,让旧域名的访问跳转到新的域名上。例如:京东360buy。com跳转到com上
  • 根据特殊变量、目录、客户端的信息进行URL跳转等

3.6 Nginx rewrite跳转实例

3.6.1 Nginx rewrite 301 跳转

  • 方法一:使用新的server区块解决死循环问题

[[email protected] extra]# vim www.conf
   server {
        listen       80;
        server_name  www.leon.shadow.com;
        rewrite ^/(.*) http://www.leonshadow.com/$1 permanent;
   }
   server {
        listen       80;
        server_name  www.leonshadow.com;
        location / {
            root   html/www;
            index  index.html index.htm;
            autoindex on;
        }

        access_log  logs/access_www.log  main;
        error_page   500 502 503 504  /50x.html;

        location = /50x.html {
            root   html;
        }
   }

  • 方法二:使用If判断语句解决死循环问题

   server {
        listen       80;
        server_name  www.leon.com;
        if ($host ~* "^www.leon.shadow.com$") {     #此处如果不使用if判断,会产生死循环错误
            rewrite ^/(.*) http://www.leonshadow.com/$1 permanent;
        }
        location / {
            root   html/www;
            index  index.html index.htm;
            autoindex on;
        }
    
        access_log  logs/access_www.log  main;
        error_page   500 502 503 504  /50x.html;

        location = /50x.html {
            root   html;
        }
   }

  • 测试结果:

[[email protected] extra]# curl www.leon.shadow.com
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.10.3</center>
</body>
</html>

[[email protected] ~]# curl -Lv www.leon.shadow.com            #追踪结果,没有产生死循环
* About to connect() to www.leon.shadow.com port 80 (#0)
*   Trying 10.0.0.8... connected
* Connected to www.leon.shadow.com (10.0.0.8) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: www.leon.shadow.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.10.3
< Date: Wed, 13 Sep 2017 07:28:23 GMT
< Content-Type: text/html
< Content-Length: 185
< Connection: keep-alive
< Location: http://www.leon.com/
<
* Ignoring the response-body
* Connection #0 to host www.leon.shadow.com left intact
* Issue another request to this URL: 'http://www.leon.com/'
* About to connect() to www.leon.com port 80 (#1)
*   Trying 10.0.0.8... connected
* Connected to www.leon.com (10.0.0.8) port 80 (#1)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: www.leon.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.3
< Date: Wed, 13 Sep 2017 07:28:23 GMT
< Content-Type: text/html
< Content-Length: 10
< Last-Modified: Tue, 12 Sep 2017 11:23:10 GMT
< Connection: keep-alive
< ETag: "59b7c39e-a"
< Accept-Ranges: bytes
<
www web01
* Connection #1 to host www.leon.com left intact
* Closing connection #0
* Closing connection #1

Nginx高级应用(四)

3.6.2 实现不同域名的URL跳转

实现访问http://blog.leonshadow.com时跳转到http://www.leonshadow.com/blog/leon.html。

  • 配置blog站点

[[email protected] extra]# vim blog.conf
    server {
        listen       80;
        server_name  blog.leon.com;
        location / {
            root   html/blog;
            index  index.html index.htm;
        }
      
        if ( $http_host ~* "^(.*)\.leon\.com" ) {
            set $domain $1;
            rewrite ^(.*) http://www.leon.com/$domain/leon.html  
            break;
        }

        access_log  logs/access_blog.log  main;
        error_page   500 502 503 504  /50x.html;

        location = /50x.html {
            root   html;
        }
    }

  • 配置leon.com/blog/leon.html地址对应的站点

[[email protected] extra]# cd ../../html/www/
[[email protected] www]# mkdir blog            #创建要跳转到的blog目录
[[email protected] www]# cd blog
[[email protected] blog]# vim leon.html        #创建要访问的leon.html文件
<html>
<title>Leon's Blog</title>
<body>
        <h1 align="center">Leon's Logo</h1>
        <p style="text-align: center;"><img src=logo.png alt="Leon's logo" /></p>
</body>
</html>

  • 实验结果

[[email protected] blog]# curl blog.leon.com
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.10.3</center>
</body>
</html>

3.7 rewrite特殊标记last与break的说明

  • 在根location(即location/{……})中或server{……}标签中编写rewrite规则,建议使用last标记;
  • 普通的location(例location/leon/{……}或if{})中编写rewrite规则,则建议使用break标记。

第4章 Nginx访问认证

4.1 什么是Nginx访问认证

在实际工作中企业会要求我们为网站设置访问账号和密码权限,这样操作后只有拥有站好密码的用户才可以访问网站内容。

Nginx高级应用(四)

4.2 Nginx访问认证的应用

这种使用账号密码才能访问网站的功能主要应用在企业内部人员访问的地址上。例如:企业网站后台、MySQL客户端phpmyadmin、企业内部CRM、WIKI网站平台等。

4.3 Nginx访问认证的语法及参数

  • auth_basic:

Syntax: auth_basic string | off;
Default: auth_basic off;
Context: http, server, location, limit_except

  • auth_basic_user_file:

Syntax: auth_basic_user_file file;
Default: —
Context: http, server, location, limit_except

file文件格式:
# comment
name1:password1
name2:password2:comment
name3:password3

可以使用Apache自带的“htpasswd”或“openssl passwd”命令设置用户和密码到认证文件里,密码是加密的。

参考资料: http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html

4.4 Nginx访问认证配置

4.4.1 配置www虚拟主机

[[email protected] extra]# vim www.conf
    server {
        listen       80;
        server_name  www.leonshadow.com;
        location / {
            root   html/www;
            index  index.html index.htm;
            auth_basic           "leon test";                   #设置认证提示字符串“leon test”
            auth_basic_user_file /application/nginx/conf/htpasswd;  #用于设置认证的密码文件
        }
    }

4.4.2 生成认证账号密码

[[email protected] extra]# yum install -y httpd
[[email protected] extra]# htpasswd -bc /application/nginx/conf/htpasswd leon 123456
Adding password for user leon
[[email protected] extra]# chmod 400 /application/nginx/conf/htpasswd
[[email protected] extra]# chown www /application/nginx/conf/htpasswd
[[email protected] extra]# cat /application/nginx/conf/htpasswd
leon:nfNYxfnwPJ32A

4.4.3 检查并重新加载配置

[[email protected] extra]# nginx -t
nginx: the configuration file /application/nginx-1.10.3/conf/nginx.conf syntax is ok
nginx: configuration file /application/nginx-1.10.3/conf/nginx.conf test is successful
[[email protected] extra]# nginx -s reload

4.4.4 测试结果

  • Windows客户端:

Nginx高级应用(四)

Nginx高级应用(四)Nginx高级应用(四)

 

 

 

 

 

 

  • Linux客户端:

[[email protected] extra]# curl www.leon.com
<html>
<head><title>401 Authorization Required</title></head>      #提示需要认证才能访问
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.10.3</center>
</body>
</html>
[[email protected] extra]# curl -uleon <a href="http://www.leon.com">www.leon.com</a>                #以leon用户身份访问网站
Enter host password for user 'leon':
www web01
[[email protected] extra]# curl -uleon:123456 <a href="http://www.leon.com">www.leon.com</a>         #以leon用户带密码直接访问网站
www web01

第5章 Nginx相关问题解答

5.1 Tengine和Nginx是什么关系

Tengine是淘宝开源Nginx的分支,官方站点为http://tengine.taobao.org/

5.2 访问Nginx时出现“403 forbidden”的原因

5.2.1 出现403错误的情况:

  • Nginx配置文件里没有配置默认首页参数
  • 站点目录下没有配置文件指定的首页文件
  • 站点目录或内部的程序文件没有Nginx用户的访问权限
  • Nginx配置文件中设置了allow、deny等权限控制,导致客户端没有访问权限

5.2.2 nginx出403错误解决方式

参考资料:http://oldboy.blog.51cto.com/2561410/1633952

[[email protected] conf]# cat nginx.conf
worker_processes  3;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    autoindex on;               #当找不到首页文件时,会展示目录结构,这个功能一般不要用除非有需求。

    include extra/www.conf;
    include extra/blog.conf;
    include extra/bbs.conf;
}

Nginx高级应用(四)

说明:显示的目录结构中,有些信息点击就是下载,有的点击就是显示,因为扩展名称不一样,根本在于nginx软件是否能够进行解析(根据媒体资源类型决定的)。
weinxin
我的微信
如果有技术上的问题可以扫一扫我的微信
版权声明
1. 本网站名称:Leon的博客
2. 本站永久网址:https://blog.leonshadow.cn
3. 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长QQ632113590进行删除处理。
4. 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5. 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
6. 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
liyang