前言:
本来的想法是写一个针对经典配置的情景分析,写到一半的时候就力不从心了,感觉很难给出一个完整全面的展示,主要是这块内容牵扯到整个系统的很多方面,比较复杂。所以就打算从一个有代表性的rewrite配置出发,讲一下在这个情景下,nginx的脚本引擎是如何工作的。
nginx的脚本解析系统,虽然不能跟专业的脚本解析器相比,但是它的设计却是非常巧妙,而且抽象性很高。先大体说一下它的大体思路。
设计思路:
我们知道nginx在解析配置时,每次根据读出的配置信息都会查找相应模块的特定处理函数,而rewrite的配置一般都是要针对具体的url来做特定的处理,如正则匹配等等,所以不能在解析的时候不能像其他配置那样得到一个相对静态的配置信息。nginx的做法是,为每个配置设置一个后续处理所需要的结构体,结构体中包含了与该配置相关的重要信息,并设置相应的处理handler,之后在处理请求的某个阶段(主要REWRITE_PHASE,这方面的介绍可以参考其他博客,这里就不重复了),会集中对这些在解析时设置的处理handler做一个集中处理。
在这个脚本引擎中,rewrite的处理或者其他使用使用脚本引擎的地方,都是通过ngx_http_script_engine_t结构体来驱动执行和保存执行结果的。我们通过下面这段代码来看一下,它的核心处理是怎么样的。
// sp是一个ngx_http_variable_value_t的数组,里面保存了从配置中分离出的一些变量
// 和一些中间结果,在当前处理中可以可以方便的拿到之前或者之后的变量(通过sp—
// 或者sp++)
e->sp = ngx_pcalloc(r->pool, rlcf->stack_size * sizeof(ngx_http_variable_value_t));
// 包含了在配置解析过程中设置的一些处理结构体,下面的rlcf->codes是一个数组,
// 注意的是,这些结构体的第一个成员就是一个处理handler,这里处理时,都会将该
// 结构体类型强转,拿到其处理handler,然后按照顺序依次执行之
e->ip = rlcf->codes->elts;
// 需要处理的请求
e->request = r;
// 初始时认为uri需要特殊处理,如做escape,或者urldecode处理。
e->quote = 1;
e->log = rlcf->log;
// 保存处理过程时可能出现的一些http response code,以便进行特定的处理
e->status = NGX_DECLINED;
// 依次对e->ip 数组中的不同结构进行处理,在处理时通过将当前结构进行强转,就
// 可以得到具体的处理handler,因为每个结构的第一个变量就是一个handler。我们看
// 的出来这些结构成员的设计都是有它的意图的。
while (*(uintptr_t *) e->ip) {
code = *(ngx_http_script_code_pt *) e->ip;
code(e);
}
说了这些抽象的理论之后,下面给出一个具体的例子来更加形象的分析一下。
情景分析:
这里我们以下面这个例子来看一下,在一个特定的rewrite情景下,nginx的脚本引擎是如何工作的:
location / {
if ($uri ~* "(.*).html$" ) {
set $file $1;
rewrite ^(.*)$ http://$http_host$file.mp4 break;
}
}
我想对于这个示例配置,大家应该都知道它的作用,主要是将一个对html请求,通过302跳转,让客户端重新取一个同名的mp4文件(是不是很无聊-_-!)。
这里通过一个图来展现在整个解析过程得到的结构及其相应的处理handler,然后我们再对一些重点的地方加以分析,对于具体的逻辑,大家可以自己看。

说明:
1. 图中蓝色的部分是if行,它的解析主要通过ngx_http_rewrite_if,set和rewirte类推。
2. 图中带有小圆圈的标记,是脚本引擎中处理handler的执行顺序,即前面的e->ip数组。
接下来我们针对这个情景下的处理流程中的一些重点进行探讨。
重点探讨:
(一) if行的解析
1. 在解析if时, nginx会把它当做一个location来对待的,并且它的location type为noname。通过ngx_http_add_location将该“location”添加到上层的locations中。这里将if看做location自然有它的合理性,因为if的配置也是需要进行url匹配的。
2. if中具体的解析通过ngx_http_rewrite_if_condition来实施。
3. 在(1)的处理时,对于$uri,ngx_http_rewrite_variable 函数会进行处理。主要的工作是将当前的这个变量(即$uri),放到全局的变量数组中,并得到其下标。还有一点就是ngx_http_script_var_code_t结构中的index,这个用来记录该下标,这样后面用到的时候就可以很快的取到该变量。
4. 为什么(2)没用设置结构体和handler呢?那是因为根据(2)的配置,就可以确定后面这个配置的处理方式了。所以这里不是每个分句都有对应的结构和handler的设置,能简单处理的,就可以捎带处理掉了,同理的还有像“break”等。
配置中凡是出现‘~’的,都是属于正则的处理。这里提醒一点是带有‘*’的,是不区分大小写的。
5. 这里先提一点相关的背景。较新的PCRE库中实现了perl和python中叫做named subpattern的东西,我们通常在引用一个pattern中的()部分时,通常使用$1,$2…等,这里的named subpattern是指在一个pattern使用类似(?<name>...)的形式,这样我们在引用这个()的内容是,就可以通过这个name来指定了,使用更加灵活。这里在(3)的处理的时候,会通过ngx_http_regex_compile函数来进行正则的编译,里面封装了一些PCRE正则库的一些API,相关的细节可以到官网http://www.pcre.org/中的document上查看。这里提一点的是,由于我们的情景中都是比较常规的正则表达式,所以与像named
subpattern之类的处理就先跳过,如rc->named_captures的处理,我们这里只关注rc->captures这个值,它是正则表达式里,出现的()的个数,这个数目在对于处理后面出现的$1,$2…等非常有用。
在(3)的处理中关键的的其实就是为模式匹配提供信息,所以通过regex->test = 1来标记实际处理时应该采取的处理方式。
下一篇我们将分析set指令和rewrite执行。望关注!
分享到:
相关推荐
### Nginx脚本引擎与Rewrite设计原理深入解析 #### 一、Set语句的解析与处理 在深入探讨Nginx脚本引擎与Rewrite设计原理时,我们聚焦于`set`与`rewrite`指令的处理机制,这两者在Nginx的配置文件中极为常见,尤其...
Nginx的脚本引擎设计精妙,尽管无法与专业级脚本语言媲美,但其高抽象性和灵活性足以满足web服务的需求。在配置解析过程中,Nginx会为每个配置项创建一个包含关键信息的结构体,并关联相应的处理函数(handler)。...
### Nginx脚本引擎与Rewrite设计原理详解 #### 一、引言 Nginx作为一款高性能的Web服务器及反向代理服务器,在互联网领域得到了广泛应用。其强大的功能不仅体现在高并发处理能力上,还在于灵活的配置选项以及丰富的...
**Nginx脚本详解** Nginx,作为一款高性能的HTTP和反向代理服务器,以其轻量级、高并发的特性在Web服务领域广泛应用。它不仅能够处理静态内容,还可以通过配置执行一些动态处理任务,例如使用脚本来实现自定义逻辑...
**Nginx 一键安装与自动化脚本** 在IT行业中,服务器配置和管理是一项重要的任务,尤其是在处理Web服务时。Nginx是一款高性能的HTTP和反向代理服务器,以其高效、稳定和轻量级的特性而广受欢迎。本文将详细讨论如何...
Nginx通过配置不同的站点来管理多个网站的运行,而“添加站点脚本”就是一种自动化创建和管理Nginx站点配置的工具。下面我们将深入探讨Nginx站点脚本的工作原理以及如何使用它。 ### 1. Nginx的基本概念 Nginx是一...
要创建一个自动化安装Nginx的脚本,你需要熟悉bash shell语法,包括变量、条件语句、循环以及函数等概念。 1. **安装必备工具**:在开始安装Nginx之前,确保系统已经安装了必要的软件包管理器,如`apt`(Ubuntu/...
对于“源码”部分,脚本可能涉及到检查Nginx是否已运行、设置环境变量、处理命令行参数、调用Nginx二进制文件以及处理各种信号等。 “工具”可能指的是使用`systemctl`、`service`或`init.d`命令来管理Nginx服务,...
### Bash脚本示例:Nginx服务状态检查与操作 #### 概述 本文将详细介绍一个用于管理和检查Nginx服务状态的Bash脚本。该脚本能够自动检测Nginx服务是否正在运行,并根据当前状态执行启动、停止或重启等操作。通过这...
6. **性能优化**:虽然Ruby语言本身较动态,但通过合理设计和优化脚本,可以尽量减少对Nginx性能的影响。例如,避免在每次请求时执行昂贵的计算,而是尽可能利用缓存和预处理。 7. **错误处理**:在Ruby脚本中处理...
"nginx健康检查脚本文件异常发送邮件通知.rar"这个压缩包就提供了一个这样的解决方案。 该压缩包包含一个shell脚本,它的主要功能是检查Nginx服务的状态,并在检测到异常时自动发送邮件通知给指定的管理员。这个...
这里给大家介绍一个很好用的nginx启动脚本。以及简单的使用,如下: 1. 执行如下命令: vim /etc/init.d/nginxd 2.输入如下内容: 注意:该文件中的如下几个变量,都需要根据你实际的目录来改写。 nginx=/usr/...
- **OpenResty**:是一个基于Nginx与Lua的高性能Web平台,它极大地简化了在Nginx上编写复杂的Web应用的过程。OpenResty提供了强大的Lua API,可以用来处理HTTP请求和响应,实现复杂的功能逻辑。 #### 需求分析 本...
14. OpenResty:标签中提到了openresty,这表明教程可能也会涉及到OpenResty的相关知识,OpenResty是一个基于Nginx和LuaJIT的高性能Web平台,它将Nginx与Lua脚本语言结合,从而提供了丰富的扩展性和开发上的便利。...
Linux下创建Nginx脚本以实现启动(start)、停止(stop)、重载(reload)等操作的详细知识点介绍: 1. Nginx的基本概念与作用: Nginx是一款高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP代理服务器。它以...
1. **Nginx模块 ngx_lua**:Nginx与Lua的桥梁是ngx_lua模块,由OpenResty公司开发,它允许我们在Nginx配置文件中直接嵌入Lua脚本,实现动态处理请求。 2. **性能优势**:由于LuaJIT(Just-In-Time编译器)的存在,...
此外,脚本还包含了一些辅助功能,比如检查网络是否已启用(`[ "$NETWORKING" = "no" ] && exit 0`),读取`/etc/sysconfig/nginx`中的配置变量,以及定义了一个锁文件`/var/lock/subsys/nginx`,用于标识服务是否...
本资源包含的是 Nginx 1.9.0 版本在 Windows 64 位系统上的安装与配置指南,以及用于管理 Nginx 服务的批处理脚本。 一、Nginx 1.9.0 安装 1. 下载:首先需要下载适用于 Windows 64 位系统的 Nginx 1.9.0 安装包。...
7. **故障排查与日志管理**:Nginx的日志管理是运维工作中不可或缺的一部分。脚本可以用来自动化处理日志,如定期清理旧日志、实时分析错误日志,甚至通过ELK(Elasticsearch, Logstash, Kibana)堆栈实现日志的可视...