nginx-push-stream模块源码学习(二)——模块初始化
本文重点介绍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)
nginx-push-stream模块源码学习(二)——模块初始化的更多相关文章
- vue 源码学习二 实例初始化和挂载过程
vue 入口 从vue的构建过程可以知道,web环境下,入口文件在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compil ...
- Dubbo源码学习(二)
@Adaptive注解 在上一篇ExtensionLoader的博客中记录了,有两种扩展点,一种是普通的扩展实现,另一种就是自适应的扩展点,即@Adaptive注解的实现类. @Documented ...
- Vue源码学习二 ———— Vue原型对象包装
Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...
- python 协程库gevent学习--gevent源码学习(二)
在进行gevent源码学习一分析之后,我还对两个比较核心的问题抱有疑问: 1. gevent.Greenlet.join()以及他的list版本joinall()的原理和使用. 2. 关于在使用mon ...
- 以太坊 layer2: optimism 源码学习(二) 提现原理
作者:林冠宏 / 指尖下的幽灵.转载者,请: 务必标明出处. 掘金:https://juejin.im/user/1785262612681997 博客:http://www.cnblogs.com/ ...
- Spring 源码学习 04:初始化容器与 DefaultListableBeanFactory
前言 在前一篇文章:创建 IoC 容器的几种方式中,介绍了四种方式,这里以 AnnotationConfigApplicationContext 为例,跟进代码,看看 IoC 的启动流程. 入口 从 ...
- [spring源码学习]二、IOC源码——配置文件读取
一.环境准备 对于学习源码来讲,拿到一大堆的代码,脑袋里肯定是嗡嗡的,所以从代码实例进行跟踪调试未尝不是一种好的办法,此处,我们准备了一个小例子: package com.zjl; public cl ...
- ngx-push-stream模块源码学习(五)——内存清理
1.定时器 采用nginx自身的定时器管理机制,具体细节待学习过nginx源码后加以补充 2.channel的生成周期 (0).初始(诞生) 发布.订阅均有可能产生ch ...
- ngx-push-stream模块源码学习(四)——订阅
一.概述 push stream模块允许三种模式的订阅者: longpolling:每收到服务端响应数据即断开连接然后迅速重连,连接耗时可以忽略 stream:与服务端保持长连接,持续不断的请求-&g ...
随机推荐
- C_文件读写流
strcmp() 所在头文件:string.h 功能:比较俩个字符串 一般形式:strcmp(字符串1,字符串2) 说明: 当S1<S2时,返回为负数return result,result&l ...
- VS2012 update1 和 VS2012 Lang Pack 离线安装方法
原文:VS2012 update1 和 VS2012 Lang Pack 离线安装方法 最近有需要用VS2012打开ReactOS这个大项目,生成sln后打开用来导航代码什么的,但其代码都是ascii ...
- JS怎样将拖拉事件与点击事件分离?
帖子:http://bbs.csdn.net/topics/390785395?page=1#post-397369340 怎样将拖拉事件跟点击事件分离? 须要做到:拖拉时不触动点击事件 <ht ...
- tomcat的webapps文件夹下放更新后的项目就訪问不了
昨天给同事更新完程序,同事说更新后的程序訪问不了.它曾经的程序叫tj52,更新后的程序叫webapp.也就是tomcat的文件夹有两个文件架,一个叫webapp,一个叫tj52.最后另外一同事给了解决 ...
- android 使用asm.jar将android手机屏幕投射到电脑
使用asm.jar将Android手机到电脑屏幕投影 有时候可能须要将手机上的一些操作投影出来,比方一些App Demo的展示等.事实上,有专门的硬件设备能干这件事儿.但不是必需专门为展示个Demo去 ...
- Git 一些常见的命令
git branch 查看本地所有分支 git status 查看当前状态 git commit 提交 git branch -a 查看所有的分支 git branch -r 查看远程所有分支 git ...
- JS链表
链表 我们可以看到在javascript概念中的队列与栈都是一种特殊的线性表的结构,也是一种比较简单的基于数组的顺序存储结构.由于javascript的解释器针对数组都做了直接的优化,不会存在在很多编 ...
- JQuery在Ajax的Post提交中国乱码的解决方案
介绍: 在JQuery的Ajax POST要求,一个要求.中国的背景之中,乱码,如何解决呢? 问题简介: var regid = $('#oregion').combobox('getValue'); ...
- jenkins+svn+gradle自动化部署笔记
自己虚拟机jekins配置:(jenkins+svn+gradle)自动化部署,1.linux配置好jdk,解压tomcat,将 jenkins.war翻到webapps目录下.2.系统管理-管理用户 ...
- CLR Profiler 性能分析工具
CLR Profiler 性能分析工具 CLR Profiler 性能分析工具 CLR Profiler 有两个版本,分别用于CLR1.1 和 CLR2.0,至于CLR4试了一些也可以,但不知道是否完 ...