Nginx反向代理、重定向


Posted in Servers onApril 13, 2022

前言:

我们访问一个网址,服务器返回对应的资源。那么一个网址是如何对应一个资源的呢?
用 Nginx 可以很好地帮我们实现路由功能,我们所有需要做的就是配置好 location 模块。

语法规则

 location [=|~|~*|^~] /uri/ {… }

符号 含义
= 精确匹配 
^~ 非正则匹配
~ 正则匹配(区分大小写)
~* 正则匹配(不区分大小写)
!~ 正则不匹配(区分大小写)
!~* 正则不匹配(不区分大小写)
  普通匹配(这里没有符号的时候)

匹配规则

1. 精准匹配命中时,停止location

2.一般匹配(普通和非正则)命中时,对比所有命中的一般匹配,选出最长的一条

3.如果最长的那一条为非正则匹配,直接匹配此条,停止location

4.如果最长的那一条为普通匹配,继续尝试正则location(以上至此都不存在代码顺序)

5.按代码顺序执行正则匹配,当第一条正则location命中时,停止location

示例:

想运行以下示例需先下载第三方模块echo-nginx-module:

#下载到/usr/local/src目录

wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz

tar -zxvf v0.61.tar.gz                                 

#在Nginx源码目录nginx-1.15.8下配置,--add-module指向模块目录即会安装插件到nginx中

./configure --add-module=/usr/local/src/echo-nginx-module-0.61/

make && make install

#验证安装

nginx -V

Nginx反向代理、重定向

你还需要配置 C:\Windows\System32\drivers\etc\hosts 文件,添加“虚拟机ip 域名”到最后:

192.168.100.14 test.loaction.com

server {
 
	listen       80;
	server_name  test.location.com;
 
	#精准匹配测试
	#第1,2条虽然匹配,但第三条是精准匹配,出第三条结果
	#测试路径/equal/a/b/c
	location ~ /equal/* {
		echo '/equal/*';
	}
	location /equal/a/b {
		echo '/equal/a/b';
	}
	location = /equal/a/b/c {
		echo '/equal/a/b/c';
	}
 
	#普通匹配测试
	#第1,2条虽然匹配,第三条匹配更长,出第三条结果
	#测试路径/match/a/b/c
	location /match/a {
		return 200  "/match/a";
	}
	location /match/a/b {
		return 200  "/match/a/b";	
	}
	location /match/a/b/c {
		 return 200  "/match/a/b/c";
	}
	location /match/a/b/c/d {
		return 200  "/match/a/b/c/d"; 
	}
 
	#正则匹配覆盖普通匹配,不会覆盖非正则匹配
	#访问/re/a.htm,会被后面的正则覆盖
	#访问/re/a/b开头的路径,不会被后面的正则覆盖
	location /re/a.htm {
		 echo 'match /re/a.htm';
	}
	location ^~ /re/a/b {
		echo 'math ^~/re/a/b*';		
	}
	location ~ /re/(.*)\.(htm|js|css)$ {
		echo "cover /re/$1.$2";
	}
 
	#正则匹配成功一条后,便不再走其它正则
	#测试路径/rex/a/b/c.htm
	location ~ /rex/.*\.(htm|js|css)$ {
		echo "match first";
	}
	location ~ /rex/a/(.*)\.(htm|js|css)$ {
		echo "match second";
	}
	location ~ /rex/a/b/(.*)\.(htm|js|css)$ {
		echo "match third";
	}
}

结果:

精准匹配最优先:

Nginx反向代理、重定向

一般匹配选最长:

Nginx反向代理、重定向

正则覆盖普通匹:

Nginx反向代理、重定向

不能覆盖非正则

Nginx反向代理、重定向

正则匹配选首位:

Nginx反向代理、重定向

proxy_pass 代理转发

在上面的示例中,我们通过修改本机hosts文件,让本机访问 test.loaction.com 相当于访问 192.168.100.14。我们现在假设有一个服务在 192.168.100.15 这台机器上。我们能不能通过访问 test.loaction.com,访问到 192.168.100.15 上的资源呢?

这样的想法其实是在模拟实际做项目的时候,我们可以只购买一个域名,然后访问多个云服务器。我们要做的就是让域名对应的服务器具有代理转发的功能。这里是服务器作为代理,让客户端能通过访问代理服务器来访问其它服务器,所以是反向代理。

通过在 location 里配置 proxy_pass 就能实现代理转发功能,帮助我们将请求转发到别的服务器。

我们先看示例再看规则:

server {
        listen       80;
        server_name	test.location.com;
 
        本机ip地址:192.168.100.104
 
        #后端服务路径:
        http://192.168.100.105:8080/user/query?id=1
        
        #规则一:
        #访问路径:http://test.location.com/user/query?id=1
        location /user {
        #path1:/user path2:/query 
                          #ip:port 后面无 /
               proxy_pass http://192.168.0.105:8080;
        }
        
        规则二:
        #访问路径 :http://test.location.com/A/user/query?id=1
        location /A/user {
        #path1:/A/user path2:/query 
                           #ip:port 后面有 /xxx
                proxy_pass http://192.168.0.105:8080/user;
        }
       
    }

解读:

后端服务路径都是 http://192.168.100.105:8080/user/query?id=1。用规则一,可以使访问路径为 http://test.location.com/user/query?id=1;用规则二,可以使访问路径为 http://test.location.com/A/user/query?id=1。

规则:

1. 访问路径格式为 sever_name + path1 + path2 + ?param

2. location 后面的路径就是 path1,对照访问路径格式,path1 和 ?param 之间的为path2

3. 如果 proxy_pass 后面的值形如 http: // ip : port; 那么实际访问的地址是 http: // ip : port + path1 + path2 + ?param

4. 如果 proxy_pass 后面的值形如 http: // ip : port / xxx; (末尾相比上面有 /xxx)

    那么实际访问的地址是 http: // ip : port  + path2 + ?param

规则二的作用:

如果我们访问其它服务器都使用规则一,那么我们将无法直观地从 URL 确定这个服务属于那台机器或者哪种服务。

而如果使用规则二,我们可以通过合理的设置明确地知道,我们访问的是服务A。

root 与 index

nginx.conf 里的默认 location 如下:

location / {
            root   html;
            index  index.html;
        }

意思是资源文件的根目录在 nginx 程序所在文件夹下的 html 文件夹:

Nginx反向代理、重定向

如果我们没有写 URI,默认的资源是 html 文件夹下的 index.html

但是你如果这样配置:

location / {
            root   html;
            index  index.html;
        }
 
location /index.html {
                echo "index";
        }

最后访问 http://test.location.com/ 浏览器会输出 index:

Nginx反向代理、重定向

也就是说,虽然前面设置了 index ,但是如果它对应的地址有被 location 匹配到的话,会执行 location 匹配后的结果

但是,必须还是得有 index 对应的文件

为了验证上面这一点,我把 html 目录下的 index.html 改成 index,再 reload 并访问:

Nginx反向代理、重定向

root 与 alias

还是先看示例比较直观:

server {
        listen       80;
        server_name	test.local.com;
 
    #文件地址:/etc/nginx/html/static/a.html
 
	#访问路径:http://test.local.com/static/a.html 	
	location /static {
        #path1:/static path2:/a.html
        root /etc/nginx/html/;
        #文件地址:root + path1 + path2
        }
 
	#访问路径:http://test.local.com/target/a.html 
	location /target {
        #path1:/target path2:/a.html
        alias /etc/nginx/html/static/;
        #文件地址:alias + path2
        }	       
    }

解读:

文件地址一样,访问路径可以不同。

使用 root 声明的是根目录,经过 location 匹配后,直接去根目录下找访问路径中 sever_name 后面的文件地址。

使用 alias 声明的是别名目录,经过 location 匹配后,去别名目录下找访问路径中 sever_name 后面除去 location 匹配的地址的剩余地址。这就好像给 location 匹配的地址取了个别名一样。

规则

1. 访问路径格式为 sever_name + path1 + path2 

2.  location 后面的路径就是 path1,对照访问路径格式,path1 后面的就是 path2

3. 如果使用 root ,文件地址为:

    root + path1 +path2

4. 如果使用 alias ,文件地址为:

   alias + path2

location 执行过程

结合以上内容,就很容易理解 location 执行过程了,如下图

Nginx反向代理、重定向

rewrite 重定向

location 里还可以配置 rewrite 实现重定向:

rewrite regex replacement [flag];

其中:

regex:正则表达式

replacement :替换值flag:后续处理标识,可以为 break/last/permanent/redirect

重点在于 flag :

1. flag=break

发生 nginx 内部重定向,path值被更新,rewrite层面的命令会中断。原控制流程逻辑不变往下走

2. flag=last

发生nginx内部重定向,path值被更新,rewrite层面的命令会中断。控制流程刷新,重新进行整个location层的逻辑流程

3. flag= permanent/redirect

发生页面重定向(301永久重定向/302临时重定向),nginx流程结束,返回http响应到浏览器,页面url更新

4.flag为空

发生nginx内部重定向,path值被更新,rewrite层面的命令继续。最后一个rewrite完毕,刷新控制流程,重新进行location重匹配

示例:

server {
 
	listen       80;
	server_name  test.location.com;
 
	location /a.html {
		echo 'I am a.html';
	}
	location /b.html {
		echo 'I am b.html';
	}
 
	#此路径请求:http://test.location.com/aa.html
	location /aa.html {##内部重定向
		rewrite ^/  /a.html break;##不会执行下面的rewrite		
		rewrite ^/  /b.html break;	
		root   /etc/nginx/html/;
	}
	
 
	#此路径请求:http://test.location.com/ab.html
	location /ab.html {##内部重定向
		rewrite ^/  /a.html last;##不会执行下面的rewrite,但重新location匹配
		rewrite ^/  /b.html last;
		rewrite ^/  /c.html;
		root   /etc/nginx/html/;		
	}
 
	#此路径请求:http://test.location.com/ba
	location /ba {
		rewrite ^/  /b.html permanent;##301永久重定向
		root   /etc/nginx/html/;
	}
 
 
	#此路径请求:http://test.location.com/bb
	location /bb {
		rewrite ^/  /b.html redirect;##302临时重定向
		set $aa 12;
		root   /etc/nginx/html/;
	}
	
	#此路径请求:http://test.location.com/cc.html
	location /cc.html {
                rewrite ^/  /c.html;##指令不停,继续往下
                rewrite ^/  /b.html;
                rewrite ^/  /a.html;##最后一条,生效的是这条
                root   /etc/nginx/html/;
        }
 
}

结果:

访问 http://test.location.com/aa.html,直接寻找 root 目录下的 a.html,我没有写这个 html,所以是 404

Nginx反向代理、重定向

访问 http://test.location.com/ab.html,因为重新 location 匹配了,所以匹配到了上面的 /a.html,输出了一句话

Nginx反向代理、重定向

访问 http://test.location.com/ba,永久重定向,可以看到地址栏的网址都变了,是外部重定向

Nginx反向代理、重定向

访问 http://test.location.com/bb,临时重定向

Nginx反向代理、重定向

访问 http://test.location.com/cc.html,不是 404,也经过了重新 location 匹配

Nginx反向代理、重定向

Nginx 处理请求的11个阶段

Nginx反向代理、重定向

Nginx 处理请求的全过程一共划分为 11 个阶段(如图),按阶段由上到下依次执行 (上一阶段的所有指令执行完毕,才进入下一阶段)

各阶段的含义如下:

  • post_read: 接收到完整的 http 头部后处理的阶段,在uri重写之前。一般跳过
  • server_rewrite: location匹配前,修改uri的阶段,用于重定向,location块外的重写指令(多次执行)
  • find_config: uri 寻找匹配的location块配置项(多次执行)
  • rewrite:找到location块后再修改uri,location级别的uri重写阶段(多次执行)
  • post_rewrite:防死循环,跳转到对应阶段
  • preaccess: 权限预处理
  • access:判断是否允许这个请求进入
  • post_access: 向用户发送拒绝服务的错误码,用来响应上一阶段的拒绝
  • try_files: 访问静态文件资源
  • content : 内容生成阶段,该阶段产生响应,并发送到客户端
  • log:记录访问日志

到此这篇关于Nginx配置 location模块实现路由(反向代理、重定向)功能的文章就介绍到这了!

Servers 相关文章推荐
destoon在各个服务器下设置URL Rewrite(伪静态)的方法
Jun 21 Servers
nginx反向代理时如何保持长连接
Mar 31 Servers
提升Nginx性能的一些建议
Mar 31 Servers
制作能在nginx和IIS中使用的ssl证书
Jun 21 Servers
nginx配置虚拟主机的详细步骤
Jul 21 Servers
使用 Apache Dubbo 实现远程通信(微服务架构)
Feb 12 Servers
Apache Hudi的多版本清理服务彻底讲解
Mar 31 Servers
关于windows server 2012 DC 环境 重启后蓝屏代码:0xc00002e2的问题
May 25 Servers
Nginx开源可视化配置工具NginxConfig使用教程
Jun 21 Servers
腾讯云服务器部署前后分离项目之前端部署
Jun 28 Servers
nginx访问报403错误的几种情况详解
Jul 23 Servers
WIN10使用IIS部署ftp服务器详细教程
Aug 05 Servers
Docker下安装Oracle19c
nginx location 带斜杠【 / 】与不带的区别
Apr 13 #Servers
Linux下使用C语言代码搭建一个简单的HTTP服务器
idea下配置tomcat避坑详解
CentOS安装Nginx并部署vue
CentOS7安装GlusterFS集群以及相关配置
Nginx+Tomcat负载均衡多实例详解
You might like
php判断字符串在另一个字符串位置的方法
2014/02/27 PHP
php实现图片等比例缩放代码
2015/07/23 PHP
php+redis实现商城秒杀功能
2020/11/19 PHP
PHP实现的获取文件mimes类型工具类示例
2018/04/08 PHP
thinkPHP框架通过Redis实现增删改查操作的方法详解
2019/05/13 PHP
thinkPHP事务操作简单案例分析
2019/10/17 PHP
用jquery仿做发微博功能示例
2014/04/18 Javascript
基于NodeJS的前后端分离的思考与实践(三)轻量级的接口配置建模框架
2014/09/26 NodeJs
js读写json文件实例代码
2014/10/21 Javascript
jquery插件unobtrusive实现片段式加载
2015/06/15 Javascript
js实现仿Discuz文本框弹出层效果
2015/08/13 Javascript
jQuery实现从身份证号中获取出生日期和性别的方法分析
2016/02/25 Javascript
深入浅析JavaScript中with语句的理解
2016/05/12 Javascript
JS组件Bootstrap实现图片轮播效果
2016/05/16 Javascript
canvas学习之API整理笔记(二)
2016/12/29 Javascript
JavaScript的继承实现小结
2017/05/07 Javascript
使用vue构建移动应用实战代码
2017/08/02 Javascript
jQuery 1.9版本以上的浏览器判断方法代码分享
2017/08/28 jQuery
在vue中使用G2图表的示例代码
2019/03/19 Javascript
深入浅出 Vue 系列 -- 数据劫持实现原理
2019/04/23 Javascript
[45:50]完美世界DOTA2联赛PWL S3 CPG vs Forest 第二场 12.16
2020/12/17 DOTA
Python中isnumeric()方法的使用简介
2015/05/19 Python
Python3实现Web网页图片下载
2016/01/28 Python
Python解析树及树的遍历
2016/02/03 Python
浅谈Python批处理文件夹中的txt文件
2019/03/11 Python
flask 使用 flask_apscheduler 做定时循环任务的实现
2019/12/10 Python
python 列表、字典和集合的添加和删除操作
2019/12/16 Python
selenium+Chrome滑动验证码破解二(某某网站)
2019/12/17 Python
Python开发之基于模板匹配的信用卡数字识别功能
2020/01/13 Python
解决matplotlib.pyplot在Jupyter notebook中不显示图像问题
2020/04/22 Python
html5唤醒APP小记
2019/03/27 HTML / CSS
解除劳动关系协议书2篇
2014/11/28 职场文书
会议简报格式范文
2015/07/20 职场文书
《勇者辞职不干了》上卷BD发售宣传CM公开
2022/04/08 日漫
win10系统xps文件怎么打开?win10打开xps文件的两种操作方法
2022/07/23 数码科技
Python使用plt.boxplot()函数绘制箱图、常用方法以及含义详解
2022/08/14 Python