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 相关文章推荐
详解如何修改nginx的默认端口
Mar 31 Servers
nginx对http请求处理的各个阶段详析
Mar 31 Servers
小程序后台PHP版本部署运行 LNMP+WNMP
Apr 01 Servers
Nginx stream 配置代理(Nginx TCP/UDP 负载均衡)
Nov 17 Servers
Apache Pulsar结合Hudi构建Lakehouse方案分析
Mar 31 Servers
配置Kubernetes外网访问集群
Mar 31 Servers
Nginx+Tomcat负载均衡多实例详解
Apr 11 Servers
tomcat正常启动但网页却无法访问的几种解决方法
May 06 Servers
项目中Nginx多级代理是如何获取客户端的真实IP地址
May 30 Servers
永中文档在线转换预览基于nginx配置部署方案
Jun 10 Servers
Win2008系统搭建DHCP服务器
Jun 25 Servers
Nginx配置使用详解
Jul 07 Servers
Docker下安装Oracle19c
nginx location 带斜杠【 / 】与不带的区别
Apr 13 #Servers
Linux下使用C语言代码搭建一个简单的HTTP服务器
idea下配置tomcat避坑详解
CentOS安装Nginx并部署vue
CentOS7安装GlusterFS集群以及相关配置
Nginx+Tomcat负载均衡多实例详解
You might like
PHP jQuery表单,带验证具体实现方法
2014/02/15 PHP
分享一个php 的异常处理程序
2014/06/22 PHP
PHP模糊查询的实现方法(推荐)
2016/09/06 PHP
php提取微信账单的有效信息
2018/10/01 PHP
extjs form textfield的隐藏方法
2008/12/29 Javascript
14个有用的Jquery技巧分享
2015/01/08 Javascript
jquery实现的判断倒计时是否结束代码
2016/02/05 Javascript
jQuery实现给input绑定回车事件的方法
2017/02/09 Javascript
浅析JS中常用类型转换及运算符表达式
2017/07/23 Javascript
angularjs实现简单的购物车功能
2017/09/21 Javascript
vue 实现走马灯效果
2019/10/28 Javascript
微信sdk实现禁止微信分享(使用原生php实现)
2019/11/15 Javascript
JS脚本实现定时到网站上签到/签退功能
2020/04/22 Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
2020/10/18 Javascript
[02:51]DOTA2 Supermajor小组分组对阵抽签仪式
2018/06/01 DOTA
python实现类似ftp传输文件的网络程序示例
2014/04/08 Python
Python的Django框架中设置日期和字段可选的方法
2015/07/17 Python
Python压缩解压缩zip文件及破解zip文件密码的方法
2015/11/04 Python
深入讲解Python函数中参数的使用及默认参数的陷阱
2016/03/13 Python
Python编写一个优美的下载器
2018/04/15 Python
NumPy.npy与pandas DataFrame的实例讲解
2018/07/09 Python
Python制作exe文件简单流程
2019/01/24 Python
Django 模型类(models.py)的定义详解
2019/07/19 Python
Python flask框架端口失效解决方案
2020/06/04 Python
Python 开发工具通过 agent 代理使用的方法
2020/09/27 Python
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
美国网上书店:Barnes & Noble
2018/08/15 全球购物
DJI大疆德国官方商城:大疆无人机
2018/09/01 全球购物
Ariat官网:美国马靴和服装品牌
2019/12/16 全球购物
区域销售经理岗位职责
2013/12/10 职场文书
消防安全汇报材料
2014/02/08 职场文书
质量承诺书范文
2014/03/27 职场文书
关于读书的演讲稿800字
2014/08/27 职场文书
党风廉政建设心得体会(2016最新版)
2016/01/22 职场文书
什么是Python装饰器?如何定义和使用?
2022/04/11 Python
MySQL 条件查询的常用操作
2022/04/28 MySQL