关于Nginx中server块配置

最近给服务器配置的东西有点多…
这里就给Nginx中server模块的配置做个小小总结叭

Nginx

Nginx 是使用基于事件驱动架构,高度模块化、高性能、开源的一台服务器,可以作为HTTP 服务器发布网站,也可以作为反向代理服务器实现负载均衡、网络跨区访问等。(总得有句话简单介绍一下基础知识点吧)。

常用命令

1
2
3
4
nginx -c /usr/local/nginx/conf/nginx.conf     #读取配置文件启动
nginx -s reload #重新读取配置文件,优雅重启
nginx -t #检测配置文件是否有语法错误
nginx -s reopen #重启Nginx

正文

location配置是为了与客户端请求的URI相匹配,从而分发到对应的服务器

location

  • Nginx一般会在server中的多个location中选取匹配度最高的一个
  • 匹配顺序是:
    带有“=“的精确匹配
    没有修饰符的精确匹配
    带有“^~”修饰符的前缀匹配
    带有“~” 或“~*” 修饰符的正则顺序匹配
    不带任何修饰符的前缀匹配
    通用匹配
  • 修饰符类型有:
    「=」 修饰符:要求路径完全匹配
    「~」 修饰符:区分大小写的正则匹配
    「~*」不区分大小写的正则匹配

proxy_pass中的/

举例说明:
下面四种情况分别访问http://localhost/proxy/test.html
配置均类似于

1
2
3
location  /proxy/ {
proxy_pass 差异在这里;
}

差异在于proxy_pass后面

配置 结果
http://22.5.88:88:82 http://22.5.88:88:82/proxy/test.html
http://22.5.88:88:82/ http://22.5.88:88:82/test.html
http://22.5.88:88:82/abc http://22.5.88:88:82/abctest.html
http://22.5.88:88:82/abc/ http://22.5.88:88:82/abc/test.html

正则与URI

值得一提的是,在使用正则表达式来匹配路径时,proxy_pass不能配置URI
proxy_pass配置URI或者URL的区别在于,nginx在转发后是否保留location中路径部分,举个栗子:

1
2
3
4
5
6
location /test {

配置1, proxy_pass https://127.0.0.1:8080
配置2, proxy_pass https://127.0.0.1:8080/abc

}

如果请求https://test.com/test/XXX
配置1使用URL,那么请求就会转发到https://127.0.0.1:8080/test/XXX
配置2使用URI,那么请求就会转发到https://127.0.0.1:8080/abc/XXX,注意这里没有保留/test

但是
否则会提示”proxy_pass cannot have URI part in location given by regular expression…”
解决方法是使用rewrite,举个栗子,使用正则表达式的配置匹配/test后面有数字的路径

1
2
3
4
5
6
location ~ /test\d+ {

rewrite ^ /abc$1 break;
proxy_pass https://127.0.0.1:8080

}

意思就是重写整个URL, 在前面添加/abc,然后再加上剩余的部分
rewrite 最后一项flag参数解释是:

  • last 本条规则匹配完成后继续向下匹配新的location规则
  • break 本条规则匹配完成后终止,不在匹配任何规则
  • redirect 返回302临时重定向
  • permanent 返回301永久重定向

端口


一般情况下建议指明proxy_pass端口,或者选择下面一种配置

1
2
proxy_set_header Host $host:$server_port;   #Nigix监听的端口
proxy_set_header Host $host:$proxy_port; #服务器真正访问的端口

Host

server中默认不配置这个参数的话,nginx转发的请求header里不会有Host字段,而服务器一般通过Host值来判断防盗链之类的。
也就说不配置的情况下,后端服务器得到是Nginx的主机名,并非客户端主机名

1
proxy_set_header Host $http_host;

这样配置是将原http请求的Header中的Host字段也放到转发的请求里,如果Host请求头部没有出现在请求头中,一般会用$host代替$http_host变量,避免不被重写。

X-Forward-For

X_Forward_For字段表示该条http请求由谁发起。
如果Nginx不重写该请求头,那么后端真实服务器在处理时会认为所有的请求都由Nginx发起,那么如果后端有防攻击策略的话,Nginx可能被封掉,同理可得:

1
proxy_set_header X-Forward-For $remote_addr;

resolver

当proxy_pass使用域名,并且服务器没有配置域名解析时,需要在Nginx配置中使用resolver
resolver中配置DNS服务器的IP以及一些其他参数

1
resolver 202.123.456.78 114.114.114.114 valid=10s ipv6=off;

Nginx默认会解析ipv6,如果没有ipv6环境,可以显式关闭;
这里还可能存在另一个问题,就是域名在被解析之后会被缓存,并不是每一次都动态解析,这可能导致一些意料之外的事情发生
可以通过设置变量以及解析超时时间来解决
1
2
3
4
5
6
7
resolver 202.123.456.78 114.114.114.114 valid=10s ipv6=off;
resolver_timeout 10s;
location / {
...
set $backend api.example.com;
proxy_pass http://$backend;
}

以上,祝你玩得愉快~

分享到:
Disqus 加载中...

如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理