关于Nginx开发,应属官网推荐的两篇文章最为经典,相当多的国内文章都是用这两篇文章作为蓝本,翻译修改。这里不重复,本来是想写个系列的,列好提纲发现来来去去都是那些基础知识,木有什么好说的。不如直接对着提纲简单说一说就行了,浅尝辄止。这里不讲什么细节的,另一篇开发细节指南在准备中,会有一些细节。
一、Phase与状态机
Nginx的HTTP服务,跟众多其他的网络服务一样,就是一个状态机。状态机中的各个状态/阶段在Nginx中定义为各种各样的phase,细数一下达到了11个之多。各个phase与形形色色的钩子、异步机制协作,成就了nginx的高效、稳定与强大功能。
状态机本身并不是Nginx独有,唯一需要注意的是状态机的中断、挂起(暂且这么说吧)在不同phase的handler中对应着不同的返回值,需要理解NGX_OK/NGX_DONE/NGX_AGAIN/NGX_DECLINED等在不同阶段的作用。
状态机
其他需要在开发中注意的就是状态机的东西了。状态机的“状态”除了Nginx中用于标识所在阶段的变量外,就是上下文,需要理解这个上下文结构,并对其进行维护。另外,一旦打断了原本完善的状态机,就要在适当的时候把routine接回去,或是自己完成所有其他操作。为方便维护、保持代码优雅,我倾向于前者。
二、钩子与异步机制
个人认为Nginx之所以有如此强大的功能,主要归结于其中形形色色的钩子和异步机制。都有哪些类型的钩子?几乎我能想到的Nginx都提供了,充斥在各个阶段,各个模块,各种功能。关于钩子的说明可以参考XXXXXX(名字隐去)相关文章,网络上应该也有一些相关文章在流传。
需要注意的是细节,如有一些位置是可以放多个钩子,也有一些位置是排 他的,只能安放一个。如两种比较常用的逻辑介入方式中,多次设置的location handler(content handler)只会有一个生效,新handler会覆盖旧的;而多次向某个phase 追加handler(phase handler)则均可生效(如果没被中途打断的话)。
异步机制,现在一般用epoll。epoll、event什么,好多人好多书都讲,也没什么好说的。需要注意的是不同触发机器的区别,Nginx使用的是边缘触发,建立模型的时候得提醒自己:用的是边缘,用的是边缘……
边缘与水平触发
三、core的各种优雅
Nginx的代码写得非常优雅,第一印象似乎耦合严重但实际上模块划分是很清晰的,看它的代码很过瘾。什么hash/array/rbtree/queue/list,简单实用。什么cpu/slab/page/buffer/shm/各种lock(部分在os),要看底层,这里也有啊,还汇编的呢。什么chain/mpool/log,细节,这就是细节。
要说还缺点什么,真是没什么了。如果有需要,自己做个任务队列,非富一下数据结构种类,换一些更好的算法,加一点读写锁,给共享内存功能增强一点什么的。但没事也不乱折腾,够用也就行,简单一点好。
四、特色:subrequest
之前虽然有一些地方也会有类似用法,但没有看到subrequest子请求这种明确的概念,或者会成为服务器一种新的标准?有另一个概念是internal redirect,看名字应该也能猜到它们的区别。相关的主要是Request结构体里边相关的三个属性/字段。最原始的用法是把多个子请求的结果合并到主请求(外部原始请求)中去,如果要改变这个默认行为,就注意下flag。
如何跟主请求的流程结合起来?跑完主请求的状态机退出来,跟着就跑下posted requests。如果自己介入了Nginx的异步机制,也需要留意除了状态机,还有posted requests。子请求天然是异步并发的,如果要强制同步,状态机上加点状态也就行了。
未完待补充……