Nginx配置文件你了解多少(二)

脱了好久才写这篇二,笔者最近拖延症又加重了,哈哈,相信大家平常也会遇到,该怎么治呢?

进入正题。

上一篇讲了主要介绍了Nginx的events模块,http模块。http模块配置了一些公共的的属性,如:log,fastcgi,proxy,upstream,server等等,今天就将介绍里面很重要的一个模块:server模块。

在配置文件里,只有一个http模块,但是一个http里面,可以包含多个server模块,即:一个nginx服务可以对外提供多个多个域名,多个端口的监听服务。

上一篇忘记说upstream了,upstream模块是http模块里面的,但是不在server里面

upstream stream_test {

server myname.com weight 1;

server 127.0.0.1:8999 weight 2;

server unix:/temp/tmp.socket weight 3;

// upstream 设置了一组代理服务器,server指定了服务器名,或ip,或域名,或socket ,weight是权重,值越大,被分配的比重越大。

}

Server {

listen [IP:] port [default_server]

// 监听端口。

// 可以在前面设置IP,下面是从官网解的一段话:

// 字面意思看来:是校验请求的IP地址是否匹配

// (笔者检验后,设置了IP,只能通过IP访问才匹配到这个server,大家也可以留意一下,这儿有了解的同学可以留言)。

// default_server :如果对应的port下,没有找到对应的server_name ,

//就会匹配带有default_server的server,或者按顺序的第一个server

server_name *.example.cn

server_name www.*

server_name ^(.*)+\.example.cn$

// nginx会根据请求的host匹配server_name

// 如果配置了多个server ,且port一样,那么按照server_name的优先级进行匹配,优先级如下:

// 1. 精确匹配

// 2. 以*开头的字符串

// 3. 以*结尾的字符串

// 4. 正则表达式

一个请求过来nginx是如何匹配虚拟主机(server)呢?

1. nginx首先会根据listen进行匹配

2. listen存在多个一致的,则根据上面的server_name的优先级顺序进行匹配,只要匹配到一项就停止搜索。

3. 没有找到server_name ,则会寻找对应port的default_server

index index.html;

// 默认访问的文件

root /home/work/www;

// 设置默认的根目录

access_log /home/work/log/server1.log main;

error_log /home/work/log/error_server1.log ;

// 在每一个server里面都可以重新定义单独的access_log/error_log

// error_log级别有notice,error,debug等,

//debug级别打印内容非常详细,对理解NGINX的工作原理,和PHP的交互都有很好的帮助。

error_page 500 502 503 504 /500.html

error_page 404 /404.html

// error_page定义了出现4xx,5xx错误时,如何更加友好的显示

// 注意/500.html,前面加了/,加了/表示绝对路径,是相对于root的绝对路径。

//如果不加/,表示相对路径,是访问的url的相对路径,

// 如果访问ling/test/test,则会变成ling/test/500.html,就不能访问了

location ~* .(php)$ {

return 403;

}

// 禁止直接访问或者下载PHP文件,

// 这个还是蛮重要的,如果黑客知道了你的路径就可以下载你的PHP文件了

location ~* .(jpgjpegjpgpngcssjs)$ {

valid_referers none blocked *.example.cn

If ($invalid_referer) {

return 403;

}

}

// 防盗链,只能防住大部分的请求,因为referer还是容易伪造的

// valid_referers指令,指校验referer头

// none:表示没有referer;blocked:表示有referer头,但是值是空;域名表达式。

// $invalid_referer是内置变量,如果在valid_referers的合法域名里面,是0;否则是1。

location /ngx_status {

stub_status on;

access_log one;

allow 127.0.0.1;

deny all;

}

// nginx的一个简单的状态监控,注意,stub_status模块需要在编译时,手动添加—with-http_stub_status_module

// 此配置监控的比较简单,其中一个监控项:

// active connections: 当前的活跃连接数,如果这个为0,可能要检查一下了。

location /fpm_status {

fastcgi_pass 127.0.0.1:9000;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

include fastcgi_params;

allow 127.0.0.1;

deny all;

}

// 监控PHP-FPM的状态,同时需要在php-fpm.conf添加配置:

//pm.status_path = /fpm_status,监控的内容如下:

location ^~ /test {

// 方向代理

proxy_pass http://stream_test;

// 注意:stream_test后面不要有/。/表示绝对路径,会将/test当做绝对路径,如下:

// 原请求:/test/ling?a=2,如果有/,就会被反向代理成http://stream_test/ling?a=2,这明显是不对的。

proxy_set_header Host $host;

proxy_set_header X-Forward-For $remote_addr;

//proxy_set_header 向反向代理服务器添加header头。

// 添加host,这样代理服务器只可以知道如何通过server_name 选择对应的虚拟机了

// 添加X-Forward-For,就可以知道真实的访问ip地址

// proxy的细节的东西还是不少,平常在配置的时候要多注意。

}

location ~ ^/ling {

root /home/work/www/;

fastcgi_pass 127.0.0.1:9000;

// 定义了将请求如何转到PHP,除了ip:port的方式,还有socket的方式,当然要和php-fpm.conf里面的listen保持一致

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

// 这个参数还是很重要的。网上有好多疑问,访问nginx,却是空页,nginx也不报错?

// 就是少了这个参数,这个参数指明了访问的index.php的路径,

// $document_root就是配的root,$fastcgi_script_name就是访问路径 (/index)

// 如果你发现SCRIPT_FILENAME没有,那有可能包含在下面的fastcgi_params里面了

include fastcgi_params;

rewrite (.*)$ /index.php?$1 break;

//rewrite是URI重定向,不是整个url的重定向,举例说明:

// url:/ling/test/test?a=2,那么rewrite的URI是那部分呢?

// 是/ling/test/test,那么重定向后的url变成了,/index.php?/ling/test/test&a=2

// 因为a=2是一个arg,再重定向后ling/test/test也变成了arg,故最后就拼到了一起

// 同时在PHP中的$_SERVER看到的QUERY_STRING和REQUEST_URI会怎么变呢?

// $_SERVER[‘QUERY_STRING’] =/ling/test/test&a=2,变成了rewrite后的,

// $_SERVER[‘REQUEST_URI’] = /ling/test/test?a=2,还是原生的url

//这说明request_uri是不随着rewrite改变的。

//break,表示rewrite后的url不再进行其他的location匹配,到此为止。

//last,表示rewrite后的url,要再进行location匹配,会从头将所有的location进行新的匹配,

// 如果遇到匹配的location,要重新rewrite.

//redirect,表示302重定向。上面两种,浏览器url,不变,下面两种会重定向。

//permanent,表示301冲定向。

// rewrite的内容还是不少的,先讲到这儿吧,大家感兴趣,可以自发看看相关资料。

}

从上面的配置,大家能看到有很多的location,有如:

location /ngx_status

location ~* .(php)$

location ~ ^/ling

location ^~ /test

到底请求过来的时候,是如何选择的,这些规则是什么意思呢?

首先要明确一点,location校验的部分是请求的URI部分,不是整个URL,这点是和rewrite一致的。(如果要匹配?后的参数,可以用 if 来操作,这儿就不多说了,感兴趣的同学可以查一下资料)

location的匹配命令:

1.= 精确匹配(要求URI完全一样),整个优先级最高,如果精确匹配到了,就停止。

2.空格 普通字符串匹配,默认是从头开始匹配。

3.^~ 普通字符串匹配,默认是从头开始匹配

4.~ 正则表达式匹配,区分大小写

5.~* 正则表达式匹配,不区分大小写

location的优先级匹配,下面是官方文档截的一部分:

1.Directives with the = prefix that match the query exactly. If found, searching stops.

2.All remaining directives with conventional strings, longest match first. If this match used the ^~ prefix, searching stops.

3. Regular expressions, in order of definition in the configuration file.

4.If #3 yielded a match, that result is used. Else the match from #2 is used.

解释一下就是:

1. 如果URI和=后面的定义一模一样,则匹配成功,停止搜索。

2. 普通字符串匹配(空格,和^~) ,选取最长的匹配,如果这个最长的是^~,那么匹配成功,停止搜索。

3. 正则表达式匹配(~,~*),按照定义的顺序决定优先级高低。谁最先定义,谁优先级高。

4.如果规则3匹配成功了,结束;否则就用规则2匹配的结果。

(解释一下,按照2的规则去匹配,匹配到了最长的,如果是^~,结束;否则,去匹配规则3,规则3匹配到了,使用规则3的结果,否则是2的结果)

最后做个测试吧,

1. http://localhost/test => 600

2. http://localhost/test/a => 607

3. http://localhost/test/a/b => 603

4. http://localhost/test/a/c => 607

5. http://localhost/test/c => 603

6. http://localhost/api/test/a/1 => 604

7. http://localhost/test/ => 603,不是600奥

}

nginx的内容太多,讲的也没有那么详细,但是希望大家从这篇文章中有收获,对最后的问题有疑问,欢迎下方留言奥。

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180112G0J2AJ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券