nginx rewrite 指令last break区别

简介:

nginx 的官方注释是这样的:

last
   stops processing the current set of ngx_http_rewrite_module directives followed by a search for a new location matching the changed URI;

break
   stops processing the current set of ngx_http_rewrite_module directives;

 

我们知道nginx运行分十一个执行阶段,上面说提到的ngx_http_rewrite_mode,可以理解为其中一个阶段-rewrite阶段。

typedef enum {
    NGX_HTTP_POST_READ_PHASE = 0,
    NGX_HTTP_SERVER_REWRITE_PHASE,
    NGX_HTTP_FIND_CONFIG_PHASE,
    NGX_HTTP_REWRITE_PHASE,           //rewrite阶段在这里
    NGX_HTTP_POST_REWRITE_PHASE,
    NGX_HTTP_PREACCESS_PHASE,
    NGX_HTTP_ACCESS_PHASE,
    NGX_HTTP_POST_ACCESS_PHASE,
    NGX_HTTP_TRY_FILES_PHASE,
    NGX_HTTP_CONTENT_PHASE,
    NGX_HTTP_LOG_PHASE
} ngx_http_phases;

 

所以我们再来理解last与break的区别:
last: 停止当前这个请求,并根据rewrite匹配的规则重新发起一个请求。新请求又从第一阶段开始执行…
break:相对last,break并不会重新发起一个请求,只是跳过当前的rewrite阶段,并执行本请求后续的执行阶段…

 

我们来看一个例子:

server {
    listen 80 default_server;
    server_name dcshi.com;
    root www;

    location /break/ {
        rewrite ^/break/(.*) /test/$1 break;
        echo "break page";
    } 

    location /last/ {
         rewrite ^/last/(.*) /test/$1 last;
         echo "last page";
    }    

    location /test/ {
       echo "test page";
    }
}

 

请求:http://dcshi.com/break/***
输出: break page
分析:正如上面讨论所说,break是跳过当前请求的rewrite阶段,并继续执行本请求的其他阶段,很明显,对于/foo 对应的content阶段的输出为 echo “break page”; (content阶段,可以简单理解为产生数据输出的阶段,如返回静态页面内容也是在content阶段;echo指令也是运行在content阶段,一般情况下content阶段只能对应一个输出指令,如同一个location配置两个echo,最终只会有一个echo指令被执行);当然如果你把/break/里的echo 指令注释,然后再次访问/break/xx会报404,这也跟我们预期一样:虽然/break/xx被重定向到/test/xx,但是break指令不会重新开启一个新的请求继续匹配,所以nginx是不会匹配到下面的/test/这个location;在echo指令被注释的情况下,/break/ 这location里只能执行nginx默认的content指令,即尝试找/test/xx这个html页面并输出起内容,事实上,这个页面不存在,所以会报404的错误。

 

请求: http://dcshi.com/last/***
输出: test page
分析: last与break最大的不同是,last会重新发起一个新请求,并重新匹配location,所以对于/last,重新匹配请求以后会匹配到/test/,所以最终对应的content阶段的输出是test page;

 

假设你对nginx的运行阶段有一个大概的理解,对理解last与break就没有问题了。



location ~ ^/testtest/ {

default_type text/html;

echo 111;

}

rewrite ^/testtest/  /test.php last;


访问 /testtest/的时候,输出的值是/test.php的内容,显然,重写到rewrite上了,交换rewrite和location位置,执行结果不变,说明这个和位置无关。




      本文转自Tenderrain 51CTO博客,原文链接:http://blog.51cto.com/tenderrain/1949254 ,如需转载请自行联系原作者




相关文章
|
3月前
|
存储 缓存 算法
Java Compressed Oops 指针压缩:JVM 内存节省与性能优化的底层秘密
Java Compressed Oops是JVM在64位系统下的关键内存优化技术:利用对象8字节对齐特性,将64位指针压缩为32位存储+左移寻址,堆≤32GB时可省30%内存、提升缓存命中率,零性能开销。超32GB自动失效,调优需规避临界点。(239字)
371 4
|
Prometheus Kubernetes 监控
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
581 0
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
|
弹性计算 运维 Cloud Native
阿里云罗晶分享 | X86+ARM,容器服务 ACK 多架构应用部署最佳实践
2023年8月31日,系列课程第五节《X86+ARM,容器服务ACK多架构应用部署最佳实践》正式上线,由阿里云云原生应用平台产品专家罗晶主讲,内容涵盖:容器服务ACK简介;ACK支持倚天ARM实例;ACK多架构应用部署最佳实践。
|
机器学习/深度学习 自然语言处理 TensorFlow
使用Python实现深度学习模型:序列建模与生成模型的博客教程
【7月更文挑战第2天】 使用Python实现深度学习模型:序列建模与生成模型的博客教程
353 1
|
存储 Kubernetes API
在K8S中,删除一个Pod会发生什么事情?
在K8S中,删除一个Pod会发生什么事情?
在Linux中,如何查看某进程所打开的所有文件?
在Linux中,如何查看某进程所打开的所有文件?
|
Ubuntu Linux 开发工具
阿里云主机的Milk-V Duo开发板python环境搭建
Milk-V Duo是一款基于算能CV1800B芯片的开发板。搭载阿里云平头哥玄铁C906处理器核心,最高频率为1GHz,视频解码、2D图形加速能力强,可应用于智能语音、智能汽车及高清显示等领域。开发板身材小巧,大小和树莓派Pico相当,引脚也基本一致,但是功能更强大一些,能够运行基于LINUX和RTOS的操作系统。
1688 0
|
Dragonfly Cloud Native 算法
镜像拉取节省 90% 以上,快手基于 Dragonfly 的超大规模分发实践
快手容器云技术团队携手阿里云、蚂蚁集团在龙蜥社区适配,优化落地解决方案。
镜像拉取节省 90% 以上,快手基于 Dragonfly 的超大规模分发实践
|
人工智能 缓存 自然语言处理
升级3:飞天AI推理加速引擎|学习笔记
快速学习升级3:飞天AI推理加速引擎
579 0
升级3:飞天AI推理加速引擎|学习笔记