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开启Brotli压缩算法实现过程详解
Mar 31 Servers
Nginx反向代理及负载均衡如何实现(基于linux)
Mar 31 Servers
Nginx工作原理和优化总结。
Apr 02 Servers
JVM上高性能数据格式库包Apache Arrow入门和架构详解(Gkatziouras)
May 26 Servers
Nginx配置https的实现
Nov 27 Servers
Shell脚本一键安装Nginx服务自定义Nginx版本
Mar 20 Servers
CentOS7安装GlusterFS集群以及相关配置
Apr 12 Servers
Windows Server 2019 安装DHCP服务及相关配置
Apr 28 Servers
超越Nginx的Web服务器caddy优雅用法
Jun 21 Servers
Windows server 2012 NTP时间同步的实现
Jun 25 Servers
Nginx安装配置详解
Jun 25 Servers
Win2008系统搭建DHCP服务器
Jun 25 Servers
Docker下安装Oracle19c
nginx location 带斜杠【 / 】与不带的区别
Apr 13 #Servers
Linux下使用C语言代码搭建一个简单的HTTP服务器
idea下配置tomcat避坑详解
CentOS安装Nginx并部署vue
CentOS7安装GlusterFS集群以及相关配置
Nginx+Tomcat负载均衡多实例详解
You might like
PHP模块 Memcached功能多于Memcache
2011/06/14 PHP
PHP学习笔记之数组篇
2011/06/28 PHP
php数组函数序列之array_search()- 按元素值返回键名
2011/11/04 PHP
php删除页面记录 同时刷新页面 删除条件用GET方式获得
2012/01/10 PHP
ThinkPHP模板比较标签用法详解
2014/06/30 PHP
javascript String 对象
2008/04/25 Javascript
js调试工具 Javascript Debug Toolkit 2.0.0版本发布
2008/12/02 Javascript
使用原生JS实现弹出层特效
2014/12/22 Javascript
js实现input框文字动态变换显示效果
2015/08/19 Javascript
Javascript中判断一个值是否为undefined的方法详解
2016/09/28 Javascript
Javascript的动态增加类的实现方法
2016/10/20 Javascript
纯JS实现只能输入数字的简单代码
2017/06/21 Javascript
jQuery实现frame之间互通的方法
2017/06/26 jQuery
vue2.X组件学习心得(新手必看篇)
2017/07/05 Javascript
jquery对table做排序操作的实例演示
2017/08/10 jQuery
微信小程序画布圆形进度条显示效果
2020/11/17 Javascript
nodejs之koa2请求示例(GET,POST)
2018/08/07 NodeJs
Python+selenium 获取浏览器窗口坐标、句柄的方法
2018/10/14 Python
python 用opencv调用训练好的模型进行识别的方法
2018/12/07 Python
Python实现的文轩网爬虫完整示例
2019/05/16 Python
Python集中化管理平台Ansible介绍与YAML简介
2019/06/12 Python
python数据预处理 :数据共线性处理详解
2020/02/24 Python
python实现贪吃蛇双人大战
2020/04/18 Python
python框架flask入门之路由及简单实现方法
2020/06/07 Python
如何使用canvas绘制可移动网格的示例代码
2020/12/14 HTML / CSS
施华洛世奇韩国官网:SWAROVSKI韩国
2018/06/05 全球购物
加拿大户外探险购物网站:SAIL
2020/06/27 全球购物
网络编程中设计并发服务器,使用多进程与多线程,请问有什么区别?
2016/03/27 面试题
带薪年假请假条
2014/02/04 职场文书
高中军训的心得体会
2014/09/01 职场文书
尊老爱幼演讲稿
2014/09/04 职场文书
知识就是力量演讲稿
2014/09/13 职场文书
先进事迹材料怎么写
2014/12/30 职场文书
2015年暑期见闻
2015/07/14 职场文书
血轮眼轮回眼特效 html+css
2021/03/31 HTML / CSS
JAVA长虹键法之建造者Builder模式实现
2022/04/10 Java/Android