Emiller的nginx模块开发指引

Emiller的nginx模块开发指引


2024年4月5日发(作者:)

要非常感谢

nginx,

它帮助我更加了解蝙蝠侠这个喜剧角色。

蝙蝠侠很快,

nginx

也很快。蝙蝠侠在与罪恶斗争,

nginx

在与浪费

CPU

、内存泄漏

等现象做斗争。蝙蝠侠在压力下能保持良好状态,

nginx

在强大的服务请求压力下表现出

色。

但是,蝙蝠侠如果没有那根蝙蝠侠万能腰带

(batman utility belt)

,那他就什么都

不是。

在任何时候,蝙蝠侠的万能腰带都应该包括 一个锁扣、几个

batarang(

蝙蝠侠的特殊武

bat-tracer(

跟踪器?

)

、器

)

、几个

bat-cuff(

护腕

)

、 夜视眼镜、几个

bat-darts(

蝙蝠

)...

或者还包括一个

apple iphone

。当蝙蝠侠需要使他的敌人失明、失聪、或者晕倒,

或者当他需要跟踪他的敌人,或者给他的敌人发个短信,你最好相信他正在他的万能腰带

上找一个合适的工具。这根腰带对蝙蝠侠的行动如此至关重要,所以,当蝙蝠侠在选择穿裤

子还是穿腰带的时候,他肯定会选择穿腰带。事实上他确实选择了腰带,这就是为什么蝙蝠

侠穿着紧绷的橡胶衣,而没有穿裤子。

虽然

nginx

没有这样一条万能腰带,但是

nginx

有一个模块链

(module chain)

,当

nginx

需要对应答进行

gzip

chunked

编码时,它会拿出一个模块来做这个工作。当

nginx

基于

IP

http

认证来阻拦对某些资源的访问时,也是由一个模块来做这些工作

的。同样,当

nginx

需要和

memcahed

或者

fastCGI

交互时,也分别由对应的模块来做

相应的工作。

尽管蝙蝠侠的万能腰带上有很多小玩意,但是有时候他还是需要一个新的小工具。也许他有

新的敌人,而他现在的武器

(

batarang

bat-cuff)

都不足以对付这个敌人。也许他

需要有新的技能,比如在水下呼吸。所以他会让

Lucius Fox

来帮他设计这些小工具。

这个文档会告诉你

nginx

模块链表

(module chain)

的一些细节,这样你就可以做到像

Lucius Fox

一样。当你完成这个课程,你将可以设计并写出高质量的模块,来完成

nginx

以前做不了的事。

Nginx

的模块系统有很多需要注意的细节,所以你可能需要经常

返回这篇文档阅读。我已尽力将这些内容梳理清楚,但我比较愚钝,写

nginx

模块仍然是

很费力的一件事情。

0

前提条件

(prerequisites)

你需要熟悉

C

。不仅仅是

C

语言语法;你需要熟悉

C

结构体相关的知识;不能被指针和函数

引用所吓倒;对预编译、宏有一定的认识。如果你需要提高一下

C

语言方面的知识,没有什

么比这更好了:

K&R

HTTP

协议的了解很有用,毕竟你是在一个

webserver

之上工作。

你也应该对

nginx

的配置文件非常熟悉。如果你不熟悉它,这里有一个简短的介绍:配置

文件中有

4

context(

分别叫

main,server,upstream,location)

。每个

context

中可以包含数个拥有一个或多个参数的指令。在

main context

中的指令对所有事情生效;

server context

中的指令对一个特定的

host/port

生效;在

upstream context

中的指令对后端的一组

server

生效;在

location context

中的指令仅对能匹配到的

web

地址

(

"/","/images"

)

生效。一个

location context

会继承包含它的

server context

的属性,同样,一个

server context

会继承

main context

的属

Upstream context

不会继承任何属性,也不会把自己的属性传递给其它;它有自己性。

的特殊的指令,这些指令不会在其它任何地方生效。我比较多地提到了这

4

context

所以

...

别忘记它们。

让我们开始吧。

1 nginx

模块概述

Nginx

模块中有

3

个角色我们将要关注:

1. Handler

:处理请求并且产生输出。

2. Filter

:对

handler

产生的输出进行操作(比如

gzip

压缩,

chunked

编码等)

3. Load-balancer

:当有多个符合条件的后端

server

可供选择时,从中选择一个以

便将请求转发过去。

模块承担着所有你能想到的和

webserver

相关的实际工作:当

nginx

寻找一个静态文件,

或者将请求代理到另外一台

server

的时候,这时候有一个

handler

模块来做这些工作;

nginx

对输出进行编码,或者执行有一个服务端的包含

(server-side include)

Nginx

的核心模块很简单,它关心网络通信、作,它将使用

filter

模块。应用协议。另外,

当处理一个请求时,将所有需要调用的合格模块排好序

(

以便在处理时依次调用

)

。这种没

有中心控制节点的架构,让你可以写一个非常好的自包含模块来做你想做的事情。

注意:不像

apache

中的模块,

nginx

中的模块不是以动态链接库

(so)

的方式存在。

(换句话说,它被编译进

nginx

这个可执行的

bin

文件)。

一个模块是如何被调用的?一般情况下,当

nginx

启动时,每个

handler

都有一个

机会将自己和配置文件中的某个

location

关联起来;如果有

2

个以上的模块关联到同一

location

,那么仅有其中一个能成功(当然,一个好的配置书写人员不会上这种冲突

产生)。

Handler

能以

3

种方式返回:所有处理成功;有错误产生;拒绝处理请求并将它

传给默认

handler

处理

(

默认

handler

通常返回一个静态文件

)

如果一个

handler

是一个到一些后端

server

组的反向代理,那么就需要用到

load-

balancer

。一个

load-balancer

决定一个被接收到的请求将要被发送到后端

server

中的哪一台。

Nginx

自带

2

load-balancer

模块:

round-robin(

轮询

)

,它像我们

在扑克牌游戏中发牌一样,(将请求轮流发送给后端

server

);

iphash

,它能保证一个

客户端的多次请求可以被同一台后端

server

处理。

如果

handler

在处理过程没有产生错误,那么

filter

将被调用。每个

location

都可以

被关联

(hook)

多个

filter

,所以,(举个例子),一个应答可以先被压缩,然后被

chunked

编码。它们的调用顺序在编译时就决定好了。

Filter

是一种典型的

CHAIN OF

RESPONSIBILITY(

职责链

)

设计模式。一个

filter

被调用,做完它的工作,然后再调用

下一个,直到最后一个

filter

被调用,

nginx

才完成它对

response

的处理。

Filter

链表中最酷的设计在于,每个

filter

并不需要等待前一个

filter

完成后才能

开始工作,它可以像

unix

系统管道一样工作,在前一个

filter

产生输出的同时处理


发布者:admin,转转请注明出处:http://www.yc00.com/news/1712319798a2040624.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信