NGINX学习积累(学习牛人)
大牛:http://www.cnblogs.com/zengkefu/p/5563608.html
当请求来临的时候,NGINX会选择进入虚拟主机,匹配location后,进入请求处理阶段。
在请求处理阶段中,发生跳转时,会重新匹配location,再次进入请求处理阶段。
===================================================================
1、模块与指令的关系 每个模块包括多个指令,每个指令都有相应的处理函数 在运行时,NGINX会解析配置文件,按照配置指令进行模块的加载并注册指令处理函数到请求处理的不同阶段。 也就是说,在请求处理的不同阶段,会调用配置文件中的配置指令对应的处理函数。 特别要强调的是,在内容处理阶段,只可以包含一个模块的指令处理函数。 注意配置指令时,可以查看指令处理函数运行的阶段。Map指令不与任何阶段关联,是声明性的。
、变量的种类 索引变量 未索引变量具有值访问函数,用户访问时,NGINX开始解析URL参数,并非所有具有值访问函数的变量都会缓存。$arg_*的变量是实时求值
、变量的求值 具有取访问函数的变量,不一定具有缓存。具有缓存的只有在第一次访问变量的时候,会求值。
NGX——MAP模块的map指令,给自定义变量定义取处理函数,并且具有缓存功能。
map $A $B {
default 0;
x 1;
}
解读:当变量$A为x时,$B就取值1,默认为default,$B就取值1,一般定义在Server块外部
非缓存变量,解析配置求值
set $A $B;立即计算赋值
4、变量与请求的关系 变量是与请求绑定的,每个请求都具有变量的独立副本,各个请求间的变量不会相互影响。 NGX——AUTH——REQUEST模块指令 auth_request是个特例,跳专到的子请求可以共享父请求的变量。 请求分为主请求和子请求或子子请求。 特殊情况 并非所有的变量都是绑定一个请求,$request_method,$request_url都是横跨父子请求。
第三方模块提供了解决方案echo_request_method
、NGINX内置变量局限性 $arg_xxx无法取得多个值,只会取得第一个, 使用 ngx_lua 模块提供的 ngx.req.get_uri_args 函数解决 未定义变量或未发现时,处理为空字符串,不能判断是否为未定义或未发现 NGX_LUA模块解决 location /test {
content_by_lua '
if ngx.var.arg_name == nil then
ngx.say("name: missing")
else
ngx.say("name: [", ngx.var.arg_name, "]")
end
‘
} $cookie_XXX 变量也会在名为XXX
的 cookie 不存在时返回特殊值“没找到”:
location /test {
content_by_lua '
if ngx.var.cookie_user == nil then
ngx.say("cookie user: missing")
else
ngx.say("cookie user: [", ngx.var.cookie_user, "]")
end
';
}
、指令与处理阶段
------rewrite------ 页面跳转
网站跳转 1)set 2) set_unescape_uri set_by_lua $c "return ngx.var.a + ngx.var.b";
在 Lua 代码里读取ngx.var.a
和ngx.var.b
时得到的其实都是 Lua 字符串类型的值"32"
和"56"
;
接着,我们对两个字符串作加法运算会触发 Lua 对加数进行自动类型转换(Lua 会把两个加数先转换为数值类型再求和);
然后,我们在 Lua 代码中把最终结果通过return
语句返回给外面的 Nginx 变量$c
;
最后,ngx_lua 模块在给$c
实际赋值之前,也会把return
语句返回的数值类型的结果,也就是 Lua 加法计算得出的“和”,自动转换为字符串 在运行时,不同模块的配置指令集之间的先后顺序一般是不确定的(严格来说,一般是由模块的加载顺序决定的,但也有例外的情况)。
比如A
和B
两个模块都在rewrite
阶段运行指令,于是要么是A
模块的所有指令全部执行完再执行B
模块的那些指令,
要么就是反过来,把B
的指令全部执行完,再去运行A
的指令。除非模块的文档中有明确的交待,否则用户一般不应编写依赖于此种不确定顺序的配置。 3)第三方模块 ngx_headers_more 提供了一系列配置指令,用于操纵当前请求的请求头和响应头。
其中有一条名叫 more_set_input_headers 的指令可以在rewrite
阶段改写指定的请求头(或者在请求头不存在时自动创建)。
这条指令总是运行在rewrite
阶段的末尾
? location /test {
? set $value dog;
? more_set_input_headers "X-Species: $value";
? set $value cat; ? echo "X-Species: $http_x_species";
? }
$http_XXX 变量在匹配请求头时会自动对请求头的名字进行归一化,即将名字的大写字母转换为小写字母,
同时把间隔符(-
)替换为下划线(_
),所以变量名$http_x_species
才得以成功匹配 more_set_input_headers 语句中设置的请求头X-Species
.
--------------------endrewrite-----------------------
--------------------access---------------------------
1)ngx_access 提供的 allow 和 deny 配置指令可用于控制哪些 IP 地址可以访问,哪些不可以
location /hello {
allow 127.0.0.1;
deny all;
echo "hello world";
}
。ngx_access 模块自己的多条配置指令之间是按顺序执行的,直到遇到第一条满足条件的指令就不再执行后续的 allow 和 deny 指令。
如果首先匹配的指令是 allow,则会继续执行后续其他模块的指令或者跳到后续的处理阶段;
而如果首先满足的是 deny 则会立即中止当前整个请求的处理,并立即返回403
错误页。 2)ngx_lua 模块提供了配置指令 access_by_lua,用于在access
请求处理阶段插入用户 Lua 代码。
这条指令运行于access
阶段的末尾,因此总是在 allow 和 deny 这样的指令之后运行,虽然它们同属access
阶段。
一般我们通过 access_by_lua 在 ngx_access 这样的模块检查过客户端 IP 地址之后,
再通过 Lua 代码执行一系列更为复杂的请求验证操作,比如实时查询数据库或者其他后端服务,以验证当前用户的身份或权限。
location /hello {
access_by_lua '
if ngx.var.remote_addr == "127.0.0.1" then
return
end
ngx.exit(403)
';
echo "hello world";
}
--------------------endacess------------------------- --------------------content--------------------------
1)echo 指令
2)echo_exec
3)proxy_pass
4)echo_location
5)content_by_luacontent
阶段属于一个比较靠后的处理阶段,运行在先前介绍过的rewrite
和access
这两个阶段之后。当和rewrite
、access
阶段的指令一起使用时,这个阶段的指令总是最后运行,例如:
绝大多数 Nginx 模块在向content
阶段注册配置指令时,本质上是在当前的location
配置块中注册所谓的“内容处理程序”(content handler)。
每一个location
只能有一个“内容处理程序”,因此,当在location
中同时使用多个模块的content
阶段指令时,只有其中一个模块能成功注册“内容处理程序”。
? location /test {
? echo hello;
? content_by_lua 'ngx.say("world")';
? }
这里,ngx_echo 模块的 echo 指令和 ngx_lua 模块的 content_by_lua 指令同处 content
阶段,
于是只有其中一个模块能注册和运行这个 location
的“内容处理程序”:
并非所有模块的指令都支持在同一个 location
中被使用多次,例如 content_by_lua 就只能使用一次,所以下面这个例子是错误的:
? location /test {
? content_by_lua 'ngx.say("hello")';
? content_by_lua 'ngx.say("world")';
? }
正确的写法应当是:
location /test {
content_by_lua 'ngx.say("hello") ngx.say("world")';
} ngx_proxy 模块的 proxy_pass 指令和 echo 指令也不能同时用在一个location
中,因为它们也同属content
阶段。
不少 Nginx 新手都会犯类似下面这样的错误:
? location /test {
? echo "before...";
? proxy_pass http://127.0.0.1:8080/foo;
? echo "after...";
? }
?
? location /foo {
? echo "contents to be proxied";
? } 正确的方法:
配置指令 echo_before_body 和 echo_after_body 之所以可以和其他模块运行在content
阶段的指令一起工作,是因为它们运行在 Nginx 的“输出过滤器”中。
前面我们在 (一) 中分析 echo 指令产生的“调试日志”时已经知道,Nginx 在输出响应体数据时都会调用“输出过滤器”,
所以 ngx_echo 模块才有机会在“输出过滤器”中对 ngx_proxy 模块产生的响应体输出进行修改(即在首尾添加新的内容)。
值得一提的是,“输出过滤器”并不属于 (一) 中提到的那 11 个请求处理阶段(毕竟许多阶段都可以通过输出响应体数据来调用“输出过滤器”)
location /test {
echo_before_body "before...";
proxy_pass http://127.0.0.1:8080/foo;
echo_after_body "after...";
}
location /foo {
echo "contents to be proxied";
}
重点注意:
当在内容处理阶段,没有注册成功的内容处理程序,那么NGINX 会默认把请求依次交给三个内容处理模块去处理,只要有一个处理,就掠过后续。
A、ngx_index
location / {
root html;
index index.html index.htm:
autoindex on;
}
当没有任何匹配时,就匹配根,index处理函数只对/感兴趣,如果不是就交给下个autoindex处理
index处理函数开始接手,去检查html/是否存在index.html,如果存在就发起内部跳转/index.html,重新匹配location;
由于index处理函数只对/感兴趣,所以把请求转发给autoindex处理函数处理,autoindex也只对 /感兴趣,它就把请求交给static处理
B、ngx_autoindex
只对/感兴趣,index在根下html下找不到index.html时,就回把请求转交给autoindex处理,会生成一个目录文件索引网页返回给客户端
当非/时,把请求交给static处理
autoindex on;
C、ngx_static
这是内容处理阶段最后一个静态模块,所有静态文件都交给这个处理函数,返回给客户端静态资源。
--------------------endcontent-----------------------
NGINX学习积累(学习牛人)的更多相关文章
- 学习ios(必看经典)牛人40天精通iOS开发的学习方法
学习ios(必看经典)牛人40天精通iOS开发的学习方法 描述 这是一套从一个对iOS开发感兴趣的学员到iOS开发高手的系统.专业的课程体系.以培养企业开发真正需要的人才为目标,每个知识点都用案例来讲 ...
- 【转】 学习ios(必看经典)牛人40天精通iOS开发的学习方法【2015.12.2
原文网址:http://bbs.51cto.com/thread-1099956-1.html 亲爱的学员们: 如今,各路开发者为淘一桶金也纷纷转入iOS开发的行列.你心动了吗?想要行动吗?知道如何做 ...
- 学习STM32单片机,从菜鸟到牛人就是这样简单(配视频资料)
我想说,为了学习单片机而去学习单片机的思路不对. 你问,如何系统地入门学习stm32? 本身就是一个错误的问题.假如你会使用8051 , 会写C语言,那么STM32本身并不需要刻意的学习. 你要考虑的 ...
- IT人的自我导向型学习:学习的3个维度
看到大家对我的文章赞了不少,看来大家还比较喜欢看.园子里的一些朋友和我说:”终于又看到你要在园子里发原创文章了.几年前就受益匪浅,经过几年的成长分享来的东西肯定也是精品.“ 感谢大家对我的信任,如果你 ...
- IT人的自我导向型学习:学习的1个理念和2个心态
本文更新版本已挪至 http://www.zhoujingen.cn/blog/2484.html ----------------------------- 写这一个系列之前,我定位是与高效学习有 ...
- ios开发 学习积累20161027~20161031
前言 学习ios这几天来,总结下,函数的定义,调用.跟其他语言都有一定的区别: 几个特别重要的就是对象的迭代的使用和判断.取随机数.动画的实现及数组的深入研究等等 之前的总结地址 ios开发 学习积累 ...
- IT人的自我导向型学习:学习的4个层次
谈起软件开发一定会想到用什么技术.采用什么框架,然而在盛行的敏捷之下,人的问题逐渐凸显出来.不少企业请人来培训敏捷开发技术,却发现并不能真正运用起来,其中一个主要原因就是大家还没有很好的学习能力.没有 ...
- nginx源码学习资源(不断更新)
nginx源码学习是一个痛苦又快乐的过程,下面列出了一些nginx的学习资源. 首先要做的当然是下载一份nginx源码,可以从nginx官方网站下载一份最新的. 看了nginx源码,发现这是一份完全没 ...
- nginx源码学习资源
http://www.cnblogs.com/yjf512/archive/2012/06/13/2548515.html nginx源码学习是一个痛苦又快乐的过程,下面列出了一些nginx的学习资源 ...
- nginx源码学习资源(不断更新)转
原文地址:http://www.cnblogs.com/yjf512/archive/2012/06/13/2548515.html nginx源码学习是一个痛苦又快乐的过程,下面列出了一些nginx ...
随机推荐
- 干了这杯Java,让你的Idea比eclipse好用
1.Idea基本配置 1.1 Idea简介 Idea是一个专门针对Java的集成开发工具(IDE),由Java语言编写.所以,需要有JRE运行环境并配置好环境变量.简单的说,Idea是写代码用的工具. ...
- .Net Core 2.0 App中读取appsettings.json
引用: Microsoft.Extensions.ConfigurationMicrosoft.Extensions.Configuration.FileExtensionsMicrosoft.Ext ...
- JS高级---原型的引入,原型添加的方法解决数据共享
原型的引入:解决:通过构造函数创建对象带来的问题,即浪费内存(一个对象开一个内存,多个对象开多个内存) 通过原型来添加方法,解决数据共享,节省内存空间 <script> function ...
- 红帽RHCE培训-课程2笔记内容
1 kickstart自动安装 已安装系统中,在root下述目录会自动生成kickstart配置文件 ll ~/anaconda-ks.cfg 关键配置元素注释,详见未精简版 创建Kickstart配 ...
- Plastic Bottle Manufacturer Profile: Plastic Bottle Forming Process
Plastic bottle molding refers to the process of making a final plastic product from a polymer produc ...
- C语言传递二维数组
方法一, 形参给出第二维的长度. 例如: #include <stdio.h> ] ) { int i; ; i < n; i++) printf("/nstr[%d] = ...
- LaunchPad
链接:https://ac.nowcoder.com/acm/contest/3665/D来源:牛客网 Hery is a boy with strong practical abilities. N ...
- windows centos php-beast 安装
https://github.com/imaben/php-beast-binaries windows下 可以直接在这里下载dll 根据自己的php版本 还有是不是线程安全的 来选择下载对应的 放 ...
- 安卓之线性布局LinearLayout
一.xml属性 (1)orientation:指定线性布局的方向 (2)gravity:指定布局内部视图与本线性布局的对齐方式 (3)layout_weight:指定当前视图的宽或高占上级 ...
- 《JavaScript高级程序设计》读书笔记(四)变量、作用域和内存问题
内容---理解基本类型和引用类型的值---理解执行环境---理解垃圾收集 --JavaScript变量松散类型的本质--决定了它只是在特定时间用于保存特定值的一个名字而已--变量的值及其数据类型可以在 ...