Open foxlele2014 opened 7 years ago
lua的基本类型:string、boolean、function、number、nil(空,未赋值)
特殊表达式: ~= 不等于 字符串连接“.."
location匹配规则:
location里的if指令
nginx 这个写得更详细多了。
ngx的指令:标准模块、第三方模块提供 如: ngx_rewrite(set)、ngx_echo(echo)、ngx_geo(geo)
变量创建、赋值的阶段 创建(配置加载、ngx启动) 赋值(请求)
可能:不创建变量而直接使用会导致启动失败
变量作用域:整个配置文件(仅限于创建), 赋值:存值有不同的容器
ngx变量的生命周期是不可能跨越请求边界的。
内部跳转:服务器内部从一个location跳到另一个location 外部跳转:http状态码301/301的跳转,
内部跳转类似exec命令,还有c语言的goto,不可逆。 http状态码的可以通过浏览器看见URL的变化
内部跳转:请求不变,location变化,(即:(变量)容器副本不变),
内建变量,可以用来获取请求/响应的信息。 ngx_http_core:如$arg_xxx(变量群),$uri,$request_uri
ngx_set_misc模块(第三方),指令set_unescape_uri可以用于解码,
自动创建变量的指令:set/set_unescape_uri,
内建变量一般是只读的,
支持修改的内建变量:$args (修改当前URL的参数串)
如:影响http代理模块(ngx_proxy)
虚拟主机(server块),
proxy_pass指令(可用于反向代理
转发http请求到远方http服务会把参数带上。
读取变量时执行的代码:取处理程序 改写变量时执行的代码:存处理程序
变量的缓存机制:
用了ngx_map模块里的(map指令,只能在http配置块里使用) map $args $foo { default 0; debug 1; } 类似函数里的自变量、因变量的关系,y = f(x); 第一次请求时,若$args为空,则$foo 一直是0,即便$args改变了,但因为第一次请求时,就做了缓存,
父子请求。 在ngx配置里边进行location的分发操作,最后汇总到父请求里边。
一般变量是有值容器的,不共享。 但是有些第三方的模块是会共享,而且是不去响应子请求的具体响应的(只要返回了200的状态码,就直接继续处理父请求的操作了。
内建变量与子请求
只有一种变量类型:字符串。 特殊值:invalid、not found
声明未赋值是不合法。
内建变量的局限性。
变量插值? 类似js里的变量提升吗?
看了下边的执行顺序。。 看起来不单止是变量提升。
ngx的配置指令的执行顺序:
请求处理阶段(有11个) 常见的: rewrite、access、content
调试日志:( ./configure --with-debug),,默认是关闭的 tar xvf nginx-1.0.10.tar.gz cd nginx-1.0.10/ ./configure --with-debug make sudu make install
配置错误文件位置: error_log logs/error.log debug;
过滤内容: grep 命令
grep -E 'http (output filter|script (set|value))' logs/error.log
看到这里,有的读者可能会问:“那么我在使用一条陌生的配置指令之前,如何知道它究竟运行在哪一个处理阶段呢?”答案是:查看该指令的文档(当然,高级开发人员也可以直接查看模块的C源码)。在许多模块的文档中,都会专门标记其配置指令所运行的具体阶段。例如 echo 指令的文档中有这么一行:
phase: content
还有非过程式的命令。。是不会处于这些阶段的。
处在server块里的指令有一个:server-rewrite的阶段
注意,因为这条指令在为 $c 变量赋值时使用了“变量插值”功能,所以第一行调试信息是以 http script copy 起始的,后面则是拼接到最终取值的字符串常量 "!".
把这些调试信息联系起来看,我们不难发现,这些配置指令的实际执行顺序是:
set $a "hello%20world"; set_unescape_uri $b $a; set $c "$b!";
这与它们在配置文件中的书写顺序完全一致
phase: rewrite tail
在 access 阶段运行的配置指令多是执行访问控制性质的任务,比如检查用户的访问权限,检查用户的来源 IP 地址是否合法,诸如此类。
标准模块 ngx_access 提供的 allow 和 deny 配置指令可用于控制哪些 IP 地址可以访问
ps 命令得到当前 worker 进程的进程号
ngx_access 组比 access_by_lua 组快了大约一个数量级,这正是我们所预期的。不过其绝对时间差是极小的,对于我的 Intel Core2Duo 1.86 GHz 的 CPU 而言,也只有区区十几微秒,或者说是在十万分之一秒的量级。 当然,上面使用 access_by_lua 的例子还可以通过换用 $binary_remote_addr 内建变量进行优化,因为 $binary_remote_addr 读出的是二进制形式的 IP 地址,而 $remote_addr 则返回更长一些的字符串形式的地址。更短的地址意味着用 Lua 进行字符串比较时通常可以更快。
改变书写顺序也不会影响他们的执行顺序
绝大多数 Nginx 模块在向 content 阶段注册配置指令时,本质上是在当前的 location 配置块中注册所谓的“内容处理程序”(content handler)。每一个 location 只能有一个“内容处理程序”,因此,当在 location 中同时使用多个模块的 content 阶段指令时,只有其中一个模块能成功注册“内容处理程序”。
content阶段指令不会顺序执行(可能会不执行,被其他content指令覆盖
当location里没有content指令时,如何处理?
那么当一个 location 中未使用任何 content 阶段的指令,即没有模块注册“内容处理程序”时,content 阶段会发生什么事情呢?谁又来担负起生成内容和输出响应的重担呢?答案就是那些把当前请求的 URI 映射到文件系统的静态资源服务模块。当存在“内容处理程序”时,这些静态资源服务模块并不会起作用;反之,请求的处理权就会自动落到这些模块上。
三个模块:依次是 ngx_index 模块, ngx_autoindex 模块,以及 ngx_static 模块
ngx_index 和 ngx_autoindex 模块都只会作用于那些 URI 以 / 结尾的请求,例如请求 GET /cats/,而对于不以 / 结尾的请求则会直接忽略,同时把处理权移交给 content 阶段的下一个模块。而 ngx_static 模块则刚好相反,直接忽略那些 URI 以 / 结尾的请求。
hello lua