Nginx反向代理

1、Nginx中location应用实例

location主要用于对URL进行匹配。 location支持正则表达式匹配,也支持条件判断匹配。

以下这段设置是通过location指令来对网页URL进行分析处理,所有扩展名以.gif、.jpg、.jpeg、.png、.bmp、.swf结尾的静态文件都在/data/tp目录下查找。

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
		root   /data/tp;
}

以下这段设置是将upload和html下的所有文件都交给nginx来处理,需要注意的是,upload和html目录是在/data/txt目录下的一个子目录。

location ~ ^/(upload|html)/ {
		root   /data/txt;
}

在下面这段设置中,location是对此虚拟主机下动态网页的过滤处理,也就是将所有以.ico为后缀的文件都交给主机10.50.20.3处理。

location ~ .*\.ico$ {
		proxy_pass http://10.50.20.3;
}

2、Nginx中location匹配优先级

location支持各种匹配规则,在多个匹配规则下,Nginx对location的处理是有优先级的,优先级高的规则会优先进行处理,而优先级低的规则可能会最后处理或者不进行处理

下面列出location多个匹配规则下,每个规则的处理优先级从上到下依次递减。

完全严格匹配

location = / {

[ config A ]

}

非正则表达式匹配

location ^~ /images/ {

[ config B ]

}

不区分大小写正则表达式匹配

location ~* .(gif|jpg|png|swf)$ {

[ config C ]

}

下面都是最长普通匹配

location /abc/def {

[ config D ]

}

location /abc {

[ config E ]

}

location / {

[ config F ]

}

location匹配规则

location [=|~|~*|^~] /uri/ { … }
#|指令|   | 前缀 |  |匹配的网站网址|  |匹配URI之后要执行的配置段|
语法 匹配规则
没有前缀 普通匹配(遵循最大前缀匹配规则)
= 精确(严格)匹配
^~ 正则匹配(依然遵循最大前缀匹配规则)
~ 开头表示区分大小写的正则匹配
~* 开头表示不区分大小写的正则匹配
!~!~* 分别为区分大小写不匹配及不区分大小写不匹配的正则
/ 通用匹配,任何请求都会匹配到。

location分类

两类:正则location和普通location

  • ~~*!~!~* 为正则location
  • =^~无任何前缀的都属于普通location.。

匹配顺序

  1. 普通location 与正则 location 之间的匹配:选择出"普通location"的最大前缀匹配结果后,还需要继续搜索正则location。如果继续搜索的"正则location"也有匹配上的,那么"正则location"覆盖"普通location"的最大前缀匹配
  2. 普通location 之间:最大前缀匹配
  3. 正则与正则:按照正则location 在配置文件中的物理顺序(编辑顺序)匹配的,并且只要匹配到一条正则location,就不再考虑后面的.
  4. 只要在"普通location "前面加上^~符号或者=或者严格精确匹配结果就不再需要继续匹配”正则location(^ 表示“非”,~ 表示“正则”,字符意思是:不要继续匹配正则)。 ^~=:共同点为,都可以阻止继续匹配;不同点是^~依然遵守"最大前缀"匹配规则,然而=不是“最大前缀”,而是必须是严格匹配(exact match )

总结

  1. 所有类型location存在时,"="匹配 > "^~"匹配(不是用正则,最大前缀匹配) > 正则匹配 > 普通(最大前缀匹配)> 默认(/)
  2. 正则 location 匹配让步普通 location 的严格精确匹配结果;但覆盖普通 location 的最大前缀匹配结果
  3. 还有一种“隐含”的方式来阻止正则 location 的搜索,这种隐含的方式就是:当“最大前缀”匹配恰好就是一个“严格精确(exact match )”匹配,照样会停止后面的搜索

location / {}location =/ {} 的区别

  1. location / {}遵守普通location 的最大前缀匹配,由于任何URI 都必然以/根开头,所以对于一个URI ,如果有更长的匹配,那自然是选这个更长的,如果没有,/一定能为这个URI 垫背(至少能匹配到 /),也就是说location / {}有点默认配置的味道,其他更长的配置能覆盖掉这个默认配置(这也是为什么我们总能看到location / {}这个配置的一个很重要的原因)。
  2. location = / {}遵守的是“严格精确匹配exact match ”,也就是只能匹配 http://host:port/ 请求,同时会禁止继续搜索正则location 。因此如果我们只想对“GET / ”请求配置作用指令,那么我们可以选location = / {}这样能减少正则location 的搜索,因此效率比location / {}高(注:前提是我们的目的仅仅只想对“GET / ”起作用)。

示例:

location = / {
 #精确匹配 / ,主机名后面不能带任何字符串
 [ configuration A ]
}
 
location / {
 #因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
 #但是正则和最长字符串会优先匹配
 [ configuration B ]
}
 
location /documents/ {
 #匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
 #只有后面的正则表达式没有匹配到时,这一条才会采用这一条
 [ configuration C ]
}
 
location ~ /documents/Abc {
 #匹配任何以 /documents/Abc 开头的地址,匹配符合以后,还要继续往下搜索
 #只有后面的正则表达式没有匹配到时,这一条才会采用这一条
 [ configuration C ]
}
 
location ^~ /images/ {
 #匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
 [ configuration D ]
}
 
location ~* \.(gif|jpg|jpeg)$ {
 #匹配所有以 gif,jpg或jpeg 结尾的请求
 #然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
 [ configuration E ]
}
 
location /images/ {
 #字符匹配到 /images/,继续往下,会发现 ^~ 存在
 [ configuration F ]
}
 
location /images/abc {
 #最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
 #F与G的放置顺序是没有关系的
 [ configuration G ]
}
 
location ~ /images/abc/ {
 #只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
  [ configuration H ]
}
 
location ~* /js/.*/\.js {
  [ configuration I ]
}

实际使用中,至少有三个匹配规则定义,如下:

#直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
#第一个必选规则
location = / {
  proxy_pass http://tomcat:8080/index
}
#第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
#有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
  root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
  root /webroot/res/;
}
#第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
  proxy_pass http://tomcat:8080/
}

3、反向代理与正向代理

反向代理(Reverse Proxy)

指通过代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并且将从内部网络服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。当一个代理服务器能够代理外部网络上的访问请求来访问内部网络时,这种代理服务的方式称为反向代理服务。

正向代理

客户端无法直接访问外部的web,需要在客户端所在的网络内架设一台代理服务器,客户端通过代理服务器访问外部的web(需要在客户端的浏览器中设置代理服务器),这就是正向代理。

正向代理适用于:

  • 局域网的代理服务器

  • 访问某个受限网络的代理服务器,如教育网访问某些国外网站需要找代理

4、最简单的反向代理实例

实现反向代理功能的是一个叫做proxy_pass的模块,最简单的一个反向代理应用如下所示,这里仅列出整个配置中的server部分:

server {
    listen    80;
    server_name www.a.com;
    location / {
    proxy_pass http://172.16.213.18:8080;
    }
}

这个反向代理实现的功能是:当访问www.a.com的时候,所有访问请求都会转发到后端172.16.213.18这个服务器的8080端口上。

一个典型的反向代理服务器配置如下所示,这里仅列出整个配置中的server部分:

server {
    listen    80;
    server_name www.b.com;
    location / {
    #下面是优化部分
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #上面这部分是让后端服务器能知道真实的ip地址相关信息
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_read_timeout 90;
    proxy_buffer_size 4k;
    proxy_buffers 4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    #******************************#
    proxy_pass http://172.16.213.77:5601;
    }
}

这个反向代理实现的功能是:当访问www.b.com的时候,所有访问请求都会转发到后端172.16.213.77这个服务器的5601端口上。与上面那个反向代理实例相比,此反向代理配置增加了一些反向代理属性,这些属性一般用于生产环境下对代理性能要求很高的环境中。

上面的是通过直接配置的方式,也可以写入文件,然后通过include文件来导入

$ vim /usr/local/nginx/conf/proxy.conf
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

$ vim  /usr/local/nginx/conf/nginx.conf
server {
    listen    80;
    server_name www.b.com;
    location / {
    proxy_pass http://172.16.213.77:5601;
    include /usr/local/nginx/conf/proxy.conf;
    }
}

5、Nginx反向代理uri的用法

Nginx的这种反向代理用法,主要有如下两种情况,这里仅列出整个配置中的server部分

  • 第一种情况请看如下配置:
server {
          server_name www.abc.com;
          location /uri/ {
          proxy_pass http://192.168.99.100:8000;
          }
}

nginx的proxy_pass对于此种情况的处理方式是:

将location中的uri传递给后端服务器

也就是当客户端访问http://www.abc.com/uri/iivey.html 时,会被反向代理到http://192.168.99.100:8000/uri/iivey.html 进行访问。


  • 第二种uri代理方式配置如下:
server {
          server_name www.abc.com;
          location /uri/ {
          proxy_pass http://192.168.99.100:8000/new_uri/;
          }
}

nginx的proxy_pass对于此种情况的处理方式是:

替换成proxy_pass指令中URL中含有的uri

也就是当客户端访问http://www.abc.com/uri/iivey.html 时,会被反向代理到http://192.168.99.100:8000/new_uri/iivey.html 进行访问。


  • 其实还有一种uri代理方式,配置如下:
server {
          server_name www.abc.com;
          location /uri/ {
          proxy_pass http://192.168.99.100:8000/;
          }
}

nginx的proxy_pass对于此种情况的处理方式是:

替换成proxy_pass指令中URL中含有的uri,

也就是当客户端访问http://www.abc.com/uri/iivey.html 时,会被反向代理到http://192.168.99.100:8000/iivey.html 进行访问。


这种反向代理方式其实是上面第二种uri代理方式的扩展

这里要重点注意下proxy_pass http://192.168.99.100:8000/; 这个url结尾有个/和没有/的区别。

posted @ 2023-12-18 15:33  厚礼蝎  阅读(60)  评论(0编辑  收藏  举报