Nginx系列教程:nginx_module_development模块开发

好像这是唯一的一份模块开发文档.. 以下简称 guide 读代码!!

nginx 程序启动

把 nginx.conf 读入内存 处理模块 ngx_http_module_t 定义的 configuration. 应该是如下的执行顺序 pre create_main_conf 执行 ngx_command_t
里面定义的函数. 可以视为 init_main_conf 的自动处理部分 init_main_conf ... postconfig listen fork 子进程(真正的服务器进程 master), 父进程退出

master 执行 setsid 脱离终端; getpid 写入 pid 文件; 启动 worker

Handlers, Filters

Handler. Handler 可以做的工作包括: 作为 handler-chain 的一部分, 返回 NGX_DECLINED 指示继续交给后继的 chain 运行. 现在 mod_passport 就仅仅是在这个机制上工作的 handler-chain 分成好几个 phases, 包括 NGX_HTTP_POST_READ_PHASE, NGX_HTTP_SERVER_REWRITE_PHASE, ... 参考 src/http/ngx_http_core_module.h 直接处理 request, 返回 response Filter. 貌似 handler 的 phases 缺乏处理返回给客户端的内容的阶段.
于是这个任务就在 Filter 里面完成了 Header Filter Body Filter

Upstream Handler, Load-Balancer

基本上需要用到这个来写模块的可能性就很小了

Upstream Handler. 从guide的翻译:"假设需要和后台服务器通信,比如 FastCGI, Memcached.. 那怎么才能避免网络 IO 阻塞 primary event loop 呢?这就要靠 Nginx 内置的 upstream 网络连接机制, 以及 hook 对应的 handler" Load-Balancer. 咱们邮件中心应用这个机制的一种可能是把请求 dispatch 到后端的桶上去... 这样恐怕 Upstream 需要能配置为泛域名——因为如果每增加一个桶
前面就改一次配置就太恶心了——或者自己实现一个 Upstream 连接机制

这里多说一句,只要架构准备好了,扩展其他业务就简单。比如 nginx 的 smtp/pop3/imap4 反向代理功能

内存池, 数据结构, 以及对应函数

忍不住要抱怨一下, 相比较于 apr, nginx 的内置数据结构及其函数简直太XXXX了, 这直接导致了编写 module 成为一件门槛很高的工作

常用函数的包装(也是为了跨平台编译, 甚至更好的性能), 见 src/core/ngx_string.h ngx_memset ngx_memzero ngx_memcpy ... 资源池 pool, 见 src/core/ngx_palloc.c ngx_palloc, 这个是最基本的malloc包装 ngx_calloc, 包装完 ngx_palloc 后再 memzero 一下 ngx_pool_cleanup_add, 正是因为这个功能的存在,pool 成为一个资源池而不仅仅是内存池. 调用 ngx_pool_cleanup_add 后返回一个指针 ptr,
然后设置 ptr->handler 为释放资源的函数就可以. 具体参考 ngx_destroy_pool 看看是怎么调用 handler 的 神秘的 temp_pool, 还没有搞清楚为什么许多数据结构里面除了 pool 外还提供了一个 temp_pool ngx_str_t, 它提供了一个存储 binary string 的方案.
不过并没有提供 realloc 相关的运算(这样的话内存管理就
复杂了)

在 log/sprintf 函数族输出的时候, 用 %V 来对应 ngx_str_t *, 以避免哪些没有 '\0' 结尾的字符串输出 ngx_array_t, 本质是一个栈表. 就我所观察, 它是所有复杂数据结构的基石, 好在不难理解.

提示:ngx_array_push 的用法和 ngx_pool_cleanup_add 类似, 也是先返回一个指针, 然后调用者再对这个指针做操作——而不是调用者先在外面把 insert/push 的数据准备好再传递进去. 从此可一窥 nginx 的编程风格. ngx_list_t 提供一个单向链表, 链表的每个单元是一个固定
大小的 array 这个东东比 ngx_array_t 有什么优势呢??array 每次都扩大内存都 double palloc 再 memcpy, ngx_list_t 效率上会好一些. 仍然是 ngx_list_push() 这样的风格 虽然效率高, 但 ngx_list_t 被使用的相比 ngx_array_t 就少多了, 大概和迭代算法写起来稍麻烦有关系. src/core/ngx_hash.c ngx_table_elt_t 是在 ngx_hash.h 里面定义的,也算一个常用的数据结构,但和 hash table 没有什么关系
首先是 ngx_hash_keys_arrays_t, 它几乎可以说是一个完备的 hash table 'keys' 成员就是当向里面添加 key/value 的时候, 依次 push 进去的 array 'keys_hash' 和 'hsize' 对应, 用来分布 hash, 在初始化的时候 palloc 好,以后就无法改变了. ngx_hash_keys_array_init() 里面的 asize 就是初始化 hash table 的 'keys' array 大小. ngx_hash_add_key() 用来放 key/value 这个数据结构只提供了 add 方法(甚至没有 set), 遍历之也还算简单, 就是没有快速的 get 的实现!! 虽然没有 get, 但 ngx_hash_add_key() 里的 ngx_hash_key_t *hk->key_hash 为接下来的操作埋下了伏笔 看起来 ngx_hash_t 才是真正可以 get(find) 的 hash_table ngx_hash_t 好像不能一个一个的插入,只能从一个 array table 里面去初始化. 一个有趣的事实是,nginx 自己的模块里面,所有用 ngx_hash_keys_arrays_t 的地方,最后都把 'keys' 用ngx_hash_init() 初始化出一个 ngx_hash_t (为什么 nginx 要这么设计 hash table 呢?难道和 wildcard 支持相关?没有继续深究了,现
有的知识已经足够完成 mod_passport 的功能了) ngx_rbtree 红黑树 ngx_radix_tree radix树用来放路由表这样的结构是比较好的... 看看代码, 果然是只在 geo_module 里面用到了这个结构 ngx_regex

时间: 2024-11-10 10:05:00

Nginx系列教程:nginx_module_development模块开发的相关文章

Nginx系列教程:nginx_substitutions_filter模块

nginx_substitutions_filter 请注意:此模块不是Nginx源的分布,可点击此链接找到安装说明, http://wiki.nginx.org/NginxHttpSubsModule#Installation . 概述 nginx_substitutions_filter 是一个过滤器模块,它可以在响应主体上运行正则表达式和固定字符串替换.该 模块不同于Nginx的本地替代模块.它能够扫描输出链缓冲区和匹配逐行字符串,类似于http://www.aliyun.com/zixu

Nginx系列教程:HTTP Upstream Request Hash模块

ngx_http_upstream_hash_module 本模块由第三方提供,不包含在 Nginx 的源码发布版中. upstream_hash该模块提供了简单的上游负载分配,通过散列一个可配置的变量(例如,请求URI,传入的HTTP标头或一些组合).用法示例如下: upstream backend {: server server1;: server server2;: hash $request_uri;} 在这里,nginx将通过散列请求的URI($ REQUEST_URI)选择Serv

Nginx系列教程:HTTP OwnerMatch模块

我编写了一个 Nginx 模块 HTTP OwnerMatch 解决了 Nginx http://www.aliyun.com/zixun/aggregation/14840.html">虚拟主机间可通过链接型文件(硬链接和符号链接)跨站访问的问题.通过这个模块可以指定每个虚拟主机的每个 Location 可以或不可以访问的哪些用户的文件. 配置文件实例 location / { root html; index index.html index.htm; omallow heiher;

Nginx系列教程:Http Access Key模块

此模块没有被包含在Nginx官方安装包中. 这个模块可以阻止所有URL中未包含合法访问令牌的访问(防盗链).访问令牌可以由访问者IP或者其它服务器变量生成,所以可以很好地控制客户端的下载行为. 配置实例: location /download {&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp; accesskey             on;  accesskey_hashmethod  md5;  access

Nginx系列教程:ngx_cache_purge模块

ngx_cache_purge 本模块由第三方提供,不包含在 Nginx 的源码发布版中. 概述 ngx_cache_purge是nginx模块,用于从FastCGI.proxy.SCGI 和uWSGI5603.html">缓存中增加内容清除功能. 安装 下载模块源码:ngx_cache_purge-1.2(更新记录)(SHA1: d9468cf42432e81ea3a110ec63aae2eb273f5516) 其他版本 解压,然后编译: ./configuremake &&am

Nginx系列教程:HTTP DAV模块

这个模块可以为Http webDAV 增加 PUT, DELETE, MKCOL, COPY 和 MOVE 等方法. 这个模块在默认编译的情况下不是被包含的,你需要在编译时指定如下参数: ./ configure --with-http_dav_module 配置范例: location / { root /data/www; client_body_temp_path /data/client_temp; dav_methods PUT DELETE MKCOL COPY MOVE; crea

Nginx系列教程:HTTP Real IP模块

HttpRealIpModule模块简介 这个模块允许从请求Headers里更改客户端的IP地址值(例如 实时的转发). 它是有用的,如果nginx后面有多层http://www.aliyun.com/zixun/aggregation/13996.html">负载均衡/代理,nginx转发请求时将会添加添加客户端的IP头. 这个模块是不是建立在默认情况下,需要这样启用它 --with-http_realip_module 用户评论:"你将建立一个值得信赖的代理列表(见下文)和客

Nginx系列教程:HTTP Stub Status模块

ngx_http_stub_status_module 这个模块能够获取Nginx自上次启动以来的工作状态 此模块非核心模块,需要在编译的时候手动添加编译参数 --with-http_stub_status_module __配置说明__ location /nginx_status {: # copied from http://blog.kovyrin.net/2006/04/29/monitoring-nginx-with-rrdtool/: stub_status on;: access

Nginx系列教程:HTTP模块

控制Nginx HTTP 进程的核心属性. 指令 alias 语法: alias file-path|directory-path; 默认值: no 作用域: location 该指令设置指定location使用的路径.注意它跟 root 相似,但是不改变文件的根路径,仅仅是使用文件系统路径.比如: location&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp; /i/ {  alias  /spool/w3/i