• Nginx_handler模块发开(hello模块结构解析)


    声明:请在文章页面明显位置给出原文连接http://www.cnblogs.com/paulweihan/p/4654173.html,否则保留追究法律责任的权利。

    最近查了很多资料,入门的例子都是ngx_http_hello(or mytest)_module. 
    最主要是参考http://tengine.taobao.org/book/chapter_03.html#config 网站以及 
    《深入理解Nginx模块发开与架构解析》一书,但感觉讲的都不够清楚。书上讲的太复杂,侧重结构体解析,下面贴出我的理解,欢迎大家谈论,联系方式:rwhsysu@163.com 。

    (读本日志,希望你首先对于Nginx有个基本了解,其次,手头有一份Nginx源码,一份gx_http_hello(or mytest)_module.c源码)

    本文不涉及hello模块目录下的config文件以及编译时添加的add-module指令,注重对于模块源码的结构的理解,用于理清作者本人和您的思路。

    对于上面网站上和书上强调的很清楚的各个结构的定义,本文不做赘述,(太占篇幅-_-|||),参考资料里面讲的很详细很清楚,本文着重描述自己的理解。如有对结构定义疑问,请读者自行参考上面提到的书以及网站

    对于ngx_http_hello(or mytest)_module内定义的数据结构与函数的理解见下图: 
    ngx_http_hello(or mytest)_module数据结构与函数关系

    上面图里包括了我对这个入门模块的结构的理解,解释如下: 
    实现一个handler的步骤:

    1. 编写模块基本结构。包括模块的定义,模块上下文结构,模块的配置结构等。
    2. 如果有loc_conf,需要定义自己loc_conf结构,以及conf结构创建,赋值函数。
    3. 实现handler的挂载函数。根据模块的需求选择正确的挂载方式。
    4. 编写handler处理函数。模块的功能主要通过这个函数来完成。

    这些结构域函数之间的包含关系见上面的图。下面说说我个人对这些模块和函数的理解。 
    Num 1:模块定义结构

    1 ngx_module_t ngx_http_hello_module;

    对于开发一个模块来说,我们都需要定义一个ngx_module_t类型的变量来说明这个模块本身的信息,从某种意义上来说,这是这个模块最重要的一个信息,它告诉了nginx这个模块的一些信息,上面定义的配置信息,还有模块上下文信息,都是通过这个结构来告诉nginx系统的,也就是加载模块的上层代码,都需要通过定义的这个结构,来获取这些信息。 
    这个模块中最主要要定义的就是CTX上下文结构与commands配置结构数组。 
    Num 2:上下文结构

    1 ngx_http_module_t ngx_http_hello_module_ctx;

    这是一个ngx_http_module_t类型的静态变量。这个变量实际上是提供一组回调函数指针,这些函数有在创建存储配置信息的对象的函数,也有在创建前和创建后会调用的函数。这些函数都将被nginx在合适的时间进行调用。 
    这个例子中,该结构最重要的是

    • 调用了一个handler挂载函数ngx_http_hello_init
    • 调用了一个loc_conf创建函数ngx_http_hello_create_loc_conf

    Num 3:模块的配置结构

    1 ngx_command_t ngx_http_hello_commands[];

    在我的理解里,这个数组实现的功能是将我们在nginx.conf文件中定义的配置读取并存储进loc_conf结构中,conf结构已经在上下文结构中被创建。 
    Num 4:loc_conf与其创建赋值函数 
    本例子中,定义了一个结构体:

    1 typedef struct
    2 {
    3         ngx_str_t hello_string;
    4         ngx_int_t hello_counter;
    5 }ngx_http_hello_loc_conf_t;

    该结构体储存了本模块的配置变量。通过上下文结构中的调用的ngx_http_hello_create_loc_conf函数创建,通过配置结构中的ngx_http_hello_string以及ngx_http_hello_counter函数赋值。(具体实现代码不贴了,请读者自行查询hello模块源码) 
    Num 5:handler 挂载函数

    1 ngx_int_t ngx_http_hello_init;

    该函数在上下文结构中被调用,决定了handler函数具体在11个PHASE中的哪个PHASE被调用。关于PHASE定义以及函数具体实现参看网站以及hello模块源码。 
    Num 6:handler函数

    1 static ngx_int_t
    2 ngx_http_hello_handler(ngx_http_request_t *r)
    3 {
    4 }

    关于这个函数,没什么好说的,他实现了对于整个request的处理,根据loc_conf的不同,处理方式也不同。

    待续:上面只介绍了hello模块涉及的数据结构以及函数的关系以及其相关功能,理清了hello模块是如何工作的:具体体现在,在哪些结构中调用了哪些函数。 
    对于主要的两个数据结构ngx_conf_t ngx_http_request_t是如何传递和实现的并未解释。同时,并未联系上nginx的main函数进行整体的分析。 
    希望对你有帮助,欢迎讨论。

  • 相关阅读:
    Java中常见数据结构:List与Map
    JAVA 双重检查锁定和延迟初始化
    Spring 读取配置文件(二)
    Spring 读取配置文件(一)
    Java配置文件读取和路径设置
    动态设置spring配置PropertyPlaceholderConfigurer location的路径
    MySQL 数据库备份种类以及经常使用备份工具汇总
    打印二叉树两个叶子节点间的路径
    读书报告之《改动代码的艺术》 (I)
    虚幻引擎自带的创建插件的插件
  • 原文地址:https://www.cnblogs.com/paulweihan/p/4654173.html
Copyright © 2020-2023  润新知