zoukankan      html  css  js  c++  java
  • nginx模块学习——nginx_http_push_module模块深入讲解和聊天室实现

    nginx-push-stream模块源码进修(二)——模块初始化
    http://www.cnblogs.com/h2-database/archive/2012/06/06/2583257.html
     

            本文重点介绍push stream模块的构成,至于nginx如何启动、保护该模块不会具体论说,今后有时候会做具体论说。
    一、模块定义
    1.1.  模块设备


            通用nginx模块的设备struct有三种,分别是main,server和location。本模块会涉及到main和location两个域的设 备。名称分别为:ngx_http_push_stream_main_conf_t和 ngx_http_push_stream_loc_conf_t. 

           具体模块设备请参考nginx官网:http://wiki.nginx.org/HttpPushStreamModule
    1.2.  模块指令
      模块的指令是定义在一个叫做ngx_command_t的静态数组中的,或用于在nginx设备文件中设定模块的相干参数或处理惩罚响应恳求,先简单来说下ngx_command_t的定义:

    struct ngx_command_t {
        ngx_str_t             name;//指令名称
        ngx_uint_t            type;//指令类型——该指令可用于ngx conf的哪个域——main?server?location?
        /*号令所对应的处理惩罚函数指针,参数
              @指向布局体 ngx_conf_t 的指针, 这个布局体里包含须要传递给指令的参数;
              @指向布局体 ngx_command_t 的指针;
              @指向模块自定义设备布局体的指针
        */
        char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
        ngx_uint_t            conf;//指定参数存储区域(main?server?loc?)
        ngx_uint_t            offset;//指定命据保存地位
        void                 *post;//指向模块在读设备的时辰须要的一些零散变量
    };
    


    比如:

    { ngx_string("push_stream_publisher"),
        NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1,//指令用在location域,没有参数或1个参数
        ngx_http_push_stream_publisher,//公布处理惩罚函数
        NGX_HTTP_LOC_CONF_OFFSET,//参数存储在location域
        offsetof(ngx_http_push_stream_loc_conf_t, location_type),
        NULL },
    { ngx_string("push_stream_subscriber"),
        NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1,
        ngx_http_push_stream_subscriber,
        NGX_HTTP_LOC_CONF_OFFSET,
        offsetof(ngx_http_push_stream_loc_conf_t, location_type),
        NULL },
    
    


    1.3.  模块高低文
           静态的ngx_http_module_t布局体,包含一大坨函数引用,用来创建和归并三段设备 (main,server,location):

    static ngx_http_module_t    ngx_http_push_stream_module_ctx = {
        NULL,                                       /* preconfiguration */
        ngx_http_push_stream_postconfig,            /* postconfiguration */
        ngx_http_push_stream_create_main_conf,      /* create main configuration */
        ngx_http_push_stream_init_main_conf,        /* init main configuration */
        NULL,                                       /* create server configuration */
        NULL,                                       /* merge server configuration */
        ngx_http_push_stream_create_loc_conf,       /* create location configuration */
        ngx_http_push_stream_merge_loc_conf,        /* merge location configuration */
    };
    



    1.4.  模块定义

    ngx_module_t    ngx_http_push_stream_module = {
        NGX_MODULE_V1,
        &ngx_http_push_stream_module_ctx,           /* module context */
        ngx_http_push_stream_commands,              /* module directives */
        NGX_HTTP_MODULE,                            /* module type */
        NULL,                                       /* init master */
        ngx_http_push_stream_init_module,           /* init module */
        ngx_http_push_stream_init_worker,           /* init process */
        NULL,                                       /* init thread */
        NULL,                                       /* exit thread */
        ngx_http_push_stream_exit_worker,           /* exit process */
        ngx_http_push_stream_exit_master,           /* exit master */
        NGX_MODULE_V1_PADDING
    };
    
    


    二、初始化
            由上文可以看出,nginx初始化时会调用ngx_http_push_stream_init_module和ngx_http_push_stream_init_worker两个函数,下面看下它们都干了什么
    2.1.  模块初始化(init_module)

    static ngx_int_t
    ngx_http_push_stream_init_module(ngx_cycle_t *cycle)
    {
        ngx_core_conf_t                         *ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module
    );
    
        if ((ngx_http_push_stream_module_main_conf == NULL) || !ngx_http_push_stream_module_main_conf->enabled) {
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "ngx_http_push_stream_module will not be used with this configu
    ration.");
            return NGX_OK;
        }
    
        // initialize our little IPC
        return ngx_http_push_stream_init_ipc(cycle, ccf->worker_processes);
    }
    
    


    代码很简单

    • 获取conf
    • 初始化IPC


    2.1.1 IPC
           该模块的IPC是对nginx的master与worker间IPC的扩大,有关nginx的过程间通信请拜见http://simohayha.iteye.com/blog/467940
           简单来讲,master与worker直接的通信模型为:

    • master每次创建worker之前,创建一个channel(socketpair),fork后worker持续该socketpair
    • master保存所有worker的socketpair从而可以向所有worker发送把握指令。
    • worker持续socketpair时,仅保存master为本身创建的socketpair的读端以及master为其他worker创建的socketpair的写端,从而可实现worker间的过程间通信
    • 因为worker创建时序的不合,先创建的worker无法获悉后创建worker的chaneel信息,为此master每次创建channel后以将新创建的channel信息以指令的情势通知先前创建的worker


           因为master为worker创建的channel(socketpair)只处理惩罚特定的指令,push stream模块创建了供本身应用的socketpair:

    • 模块初始化时为所有worker创建一个socketpair
    • master创建worker时,worker会完全持续由模块创建的socketpair读端与写端。
    • worker可借助由push stream模块创建的socketpair实现全双工通信


    2.  ngx worker初始化(ngx_http_push_stream_init_worker)

  • 相关阅读:
    msyql 死锁
    yii2 操作数据库
    yii2 加载静态资源
    Yii2 之 UrlManager 实践 (一)
    Wordpress 之 Rewrite Rules
    yii2 使用gii生成代码文件
    权限设计的杂谈
    NodeJS —— 自定义流的实现
    浅析递归
    请将你的App签名文件放进保险箱
  • 原文地址:https://www.cnblogs.com/ldms/p/ngix.html
Copyright © 2011-2022 走看看