nginx模块开发
NginxRTMP模块nginx-rtmp-module指令详解

NginxRTMP模块nginx-rtmp-module指令详解译序:截⾄ Jul 8th,2013 官⽅公布的最新 Nginx RTMP 模块 nginx-rtmp-module 指令详解。
指令Corertmp语法:rtmp { ... }上下⽂:根描述:保存所有 RTMP 配置的块。
server语法:server { ... }上下⽂:rtmp描述:声明⼀个 RTMP 实例。
rtmp {server {}}listen语法:listen (addr[:port]|port|unix:path) [bind] [ipv6only=on|off] [so_keepalive=on|off|keepidle:keepintvl:keepcnt]上下⽂:server描述:给 NGINX 添加⼀个监听端⼝以接收 RTMP 连接。
server {listen 1935;}application语法:application name { ... }上下⽂:server描述:创建⼀个 RTMP 应⽤。
application 名的模式并不类似于 http location。
server {listen 1935;application myapp {}}timeout语法:timeout value上下⽂:rtmp, server描述:Socket 超时。
这个值主要⽤于写数据时。
⼤多数情况下,RTMP 模块并不期望除 publisher 端⼝之外的其他端⼝处于活动状态。
如果你想要快速关掉 socket 可以⽤ keepalive 或者 RTMP ping 等。
timeout 默认值为 1 分钟。
timeout 60s;ping语法:ping value上下⽂:rtmp, server描述:RTMP ping 间隔。
零值的话将 ping 关掉。
RTMP ping 是⼀个⽤于检查活动连接的协议功能。
发送⼀个特殊的包到远程连接,然后在ping_timeout 指令指定的时间内期待⼀个回复。
Nginx模块开发文档

nginx文档吴东April 28, 2009Contents1前言52基本配置72.1安装 (7)2.2配置说明 (10)2.3启动和控制 (25)3深入源码273.1源码结构 (27)3.2configure配置 (27)3.3nginx源码习惯 (27)3.4常用基础库 (28)3.5core模块 (40)3.6event模块 (44)3.7http模块 (46)4模块编写554.1http模块编写 (55)4.2基于nginx的高性能服务器开发. . . . . . . . . 555附录575.1编译器参数 (57)5.2系统函数 (59)CONTENTS CONTENTSChapter 1前言在互联网编程中,http服务器编程作为一个非常重要方向一直为各种语言所重视,从c语言的apache,Lighttpd到当前非常流行的nginx。
Java有tom-cat,jetty,websphere等众多服务器,pyhoen的zope等服务器。
既有重量级的服务器,又有轻量级的,嵌入式的服务器。
从互联网的应用来说,c语言的http 服务器一直占有主导地位,当前最流行的三个开源服务器有apache,Lighttpd和nginx。
Apache作为经典的Web服务器,除了慢没有别的缺点了,Apache2对fcgi支持并不好,非常好用的proxy和proxy_ajp (很多人用它作为tomcat的前端),不支持epoll(这年头,epoll几乎是性能的必备)。
Lighttpd作为杀手级的静态文件能力,杀手级的fcgi能力但是proxy模块不够稳定。
Nginx速度快,占用资源少,杀手级的proxy和rewrite,非常不错的静态文件能力,最适合作为整个网站的前端服务(将php、svn等不同请求发送往后端apache)。
现在国内Nginx的用户越来越多了,多数拥抱Nginx的网站都钟意其优异的性能表现,如果是相对比较大的网站,节约下来的服务器成本无疑是客观的。
Windows下编译Nginx并添加模块

Windows下编译Nginx并添加模块一.准备工作1.环境安装1.安装vs2010或vs2013等vs工具。
2.安装ActivePerl,安装完成后,将其安装路径加入到PATH环境变量。
3.安装MinGW,下载mingw-get-setup.exe,安装完成后,将其安装路径加入到PATH环境变量。
(记得安装的时候装上msys,不懂就全勾了)4.安装nasm,安装完成后,将其安装路径加入到PATH环境变量。
2.下载编译nginx源码文件1.nginx源码:nginx-1.12.22.pcre:pcre-8.403.zlib:zlib-1.2.114.openssl:openssl-1.0.2l3.下载添加模块文件1.文件上传模块: nginx-upload-module2.rtmp模块:nginx-rtmp-module3.文件上传进度条模块:nginx-upload-progress-module二.编译并添加模块1.将上述7个压缩包文件解压至文件夹msys文件目录下,如C:\MinGW\msys\1.0\home\$UESRNAME\。
2.找到msys.bat的路径并双击msys.bat,运行。
如下图所示3.打开msys.bat后如下所示右击上方编辑栏,选择编辑,粘贴,可进行粘贴复制功能。
4.cd 至nginx源码路径,并在源码路径下执行下面语句:auto/configure --with-cc=cl --builddir=objs --prefix= \--conf-path=conf/nginx.conf --pid-path=logs/nginx.pid \--http-log-path=logs/access.log --error-log-path=logs/error.log \ --sbin-path=nginx.exe--http-client-body-temp-path=temp/client_body_temp \--http-proxy-temp-path=temp/proxy_temp \--http-fastcgi-temp-path=temp/fastcgi_temp \--with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=../pcre-8.40 \--with-zlib=../zlib-1.2.11 --with-openssl=../openssl-1.0.2l \--with-select_module --with-http_ssl_module \--with-http_sub_module \--add-module=../nginx-upload-module-2.255 \--add-module=../nginx-upload-progress-module-master \--add-module=../nginx-rtmp-module-master \其中pcre,zlib,openssl的语句需根据版本号的不同进行改变,最后增加的模块也需更具实际情况进行相应的改变,步骤4操作如下图所示:下图表示正在形成Makefile文件,请等待。
NGINX 介绍

Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,也是一个IMAP/POP3/SMTP 代理服务器。
Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本0.1.0发布于2004年10月4日。
其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。
2011年6月1日,nginx 1.0.4发布。
目录优点Nginx性能概述常见问题(FAQ)安装Nginx优点Nginx性能概述常见问题(FAQ)安装Nginx展开nginx mapNginx 可以在大多数 Unix like OS 上编译运行,并有 Windows 移植版。
目前 Nginx 的1.0.0稳定版已发布,开发版本为0.9.x,稳定版为 0.8.x,历史稳定版为 0.7.x,建议使用 0.8系列作为生产版本。
Nginx 的源代码使用 2-clause BSD-like license。
Nginx 是一个很牛的高性能Web和反向代理服务器,它具有很多非常优越的特性:在高连接并发的情况下,Nginx是Apache服务器不错的替代品:Nginx 在美国是做虚拟主机生意的老板们经常选择的软件平台之一。
能够支持高达 50,000 个并发连接数的响应,感谢Nginx为我们选择了 epoll and kqueue作为开发模型。
Nginx作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和PHP 程序对外进行服务,也可以支持作为 HTTP代理服务器对外进行服务。
Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比Perlbal 要好很多。
作为邮件代理服务器:Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器),Last. fm 描述了成功并且美妙的使用经验。
Nginx的rewrite模块详解

Nginx的rewrite模块详解rewrite模块即ngx_http_rewrite_module模块,主要功能是改写请求URI,是Nginx默认安装的模块。
rewrite模块会根据PCRE 正则匹配重写URI,然后发起内部跳转再匹配location,或者直接做30x重定向返回客户端。
指令执⾏顺序⾸先顺序执⾏server块中的rewrite模块指令,得到rewrite后的请求URI然后循环执⾏如下指令如果没有遇到中断循环标志,此循环最多执⾏10次,但是我们可以使⽤break指令来中断rewrite后的新⼀轮的循环(1). 依据rewrite后的请求URI,匹配定义的 location 块(2). 顺序执⾏匹配到的 location 中的rewrite模块指令指令breakContext: server, location, if停⽌执⾏ ngx_http_rewrite_module 的指令集,但是其他模块指令是不受影响的例⼦说明server {listen 8080;# 此处 break 会停⽌执⾏ server 块的 return 指令(return 指令属于rewrite模块)# 如果把它注释掉则所有请求进来都返回 okbreak;return 200 "ok";location = /testbreak {break;return 200 $request_uri;proxy_pass http://127.0.0.1:8080/other;}location / {return 200 $request_uri;}}# 发送请求如下# curl 127.0.0.1:8080/testbreak# /other# 可以看到返回 `/other` ⽽不是 `/testbreak`,说明 `proxy_pass` 指令还是被执⾏了# 也就是说其他模块的指令是不会被 break 中断执⾏的# (proxy_pass是ngx_http_proxy_module的指令)ifContext: server, location依据指定的条件决定是否执⾏ if 块语句中的内容if 中的⼏种判断条件1.⼀个变量名,如果变量 $variable 的值为空字符串或者字符串"0",则为false2.变量与⼀个字符串的⽐较相等为(=) 不相等为(!=) 注意此处不要把相等当做赋值语句啊3.变量与⼀个正则表达式的模式匹配操作符可以是(~ 区分⼤⼩写的正则匹配, ~不区分⼤⼩写的正则匹配, !!,前⾯两者的⾮)4.检测⽂件是否存在使⽤ -f(存在) 和 !-f(不存在)5.检测路径是否存在使⽤ -d(存在) 和 !-d(不存在) 后⾯判断可以是字符串也可是变量6.检测⽂件、路径、或者链接⽂件是否存在使⽤ -e(存在) 和 !-e(不存在) 后⾯判断可以是字符串也可是变量7.检测⽂件是否为可执⾏⽂件使⽤ -x(可执⾏) 和 !-x(不可执⾏) 后⾯判断可以是字符串也可是变量注意上⾯第1,2,3条被判断的必须是变量, 4, 5, 6, 7则可以是变量也可是字符串, -f/-d/-e/-x 基本⽤法和 bash 是⼀致的. set $variable "0";if ($variable) {# 不会执⾏,因为 "0" 为 falsebreak;}# 使⽤变量与正则表达式匹配没有问题if ( $http_host ~ "^star\.igrow\.cn$" ) {break;}# 字符串与正则表达式匹配报错if ( "star" ~ "^star\.igrow\.cn$" ) {break;}# 检查⽂件类的字符串与变量均可if ( !-f "/data.log" ) {break;}if ( !-f $filename ) {break;}returnContext: server, location, ifreturn code [text];return code URL;return URL;停⽌处理并将指定的code码返回给客户端。
Nginx源代码分析

Nginx源代码分析1.Nginx代码的目录和结构nginx的源码目录结构层次明确,从自动编译脚本到各级的源码,层次都很清晰,是一个大型服务端软件构建的一个范例。
以下是源码目录结构说明:├─auto 自动编译安装相关目录│├─cc 针对各种编译器进行相应的编译配置目录,包括Gcc、Ccc等│├─lib 程序依赖的各种库,包括md5,openssl,pcre等│├─os 针对不同操作系统所做的编译配置目录│└─types├─conf 相关配置文件等目录,包括nginx的配置文件、fcgi相关的配置等├─contrib├─html index.html└─src 源码目录├─core 核心源码目录,包括定义常用数据结构、体系结构实现等├─event 封装的事件系统源码目录├─http http服务器实现目录├─mail 邮件代码服务器实现目录├─misc 该目录当前版本只包含google perftools包└─os nginx对各操作系统下的函数进行封装以及实现核心调用的目录。
2.基本数据结构2.1.简单的数据类型在core/ngx_config.h 目录里面定义了基本的数据类型的映射,大部分都映射到c语言自身的数据类型。
typedef intptr_t ngx_int_t;typedef uintptr_t ngx_uint_t;typedef intptr_t ngx_flag_t;其中ngx_int_t,nginx_flag_t,都映射为intptr_t;ngx_uint_t映射为uintptr_t。
这两个类型在/usr/include/stdint.h的定义为:/* Types for `void *' pointers. */#if __WORDSIZE == 64# ifndef __intptr_t_definedtypedef long int intptr_t;# define __intptr_t_defined# endiftypedef unsigned long int uintptr_t;#else# ifndef __intptr_t_definedtypedef int intptr_t;# define __intptr_t_defined# endiftypedef unsigned int uintptr_t;#endif所以基本的操作和整形/指针类型的操作类似。
nginx源码安装配置详解(.configure)

nginx源码安装配置详解(.configure)在"./configure"配置中,"--with"表⽰启⽤模块,也就是说这些模块在编译时不会⾃动构建,"--without"表⽰禁⽤模块,也就是说这些模块在编译时会⾃动构建,若你想Nginx轻量级运⾏,可以去除⼀些不必要的模块。
[root@localhost nginx-1.14.0]# ./configure --help => 查看编译配置项--help打印帮助信息。
--prefix=PATH设置软件安装⽬录路径。
--sbin-path=PATH设置可执⾏⽂件安装⽬录路径。
--modules-path=PATH设置模块安装⽬录路径。
--conf-path=PATH设置配置⽂件安装⽬录路径。
--error-log-path=PATH设置错误⽇志⽂件安装⽬录路径。
--pid-path=PATH设置进程⽂件安装⽬录路径。
--lock-path=PATH设置NGINX锁⽂件安装⽬录路径,当NGINX运⾏时会⾃动创建该⽂件,⽤于在⼀台服务器上只允许运⾏⼀个NGINX服务。
--user=USER设置运⾏进程时所使⽤的系统⽤户,如果没有指定,则默认为nobody,就算安装时不指定,后期也可以通过修改"nginx.conf"配置⽂件中的"user"项修改。
--group=GROUP设置运⾏进程时所使⽤的⽤户组。
--build=NAME设置编译名,⼀个描述,没有任何其他作⽤。
--builddir=DIR设置编译⽬录,会将编译后⽣成的⽂件写⼊到这个⽬录中。
----------------------------------------------------------------------------------with-select_module--without-select_module启⽤或禁⽤select事件驱动模型。
写给大忙人的nginx核心配置详解(匹配重写、集群、环境变量上下文、Lua)

写给⼤忙⼈的nginx核⼼配置详解(匹配重写、集群、环境变量上下⽂、Lua) 由于当前很多应该都是前后端分离了,同时⼤量的基于http的分布式和微服务架构,使得很多时候应⽤和不同项⽬组之间的系统相互来回调⽤,关系复杂。
如果使⽤传统的做法,都在应⽤中进⾏各种处理和判断,不仅维护复杂、容易出错,还⼤⼤增加开发、调试的⼯作量,在nginx中,有不少的⾮功能类其实是可以帮我们处理掉的,所以,对于现代开发⼈员来说,有必要对nginx的location⽐较熟悉,以便达到事半功倍的效果,⽐如说,⽇常的图⽚上传就是个例⼦,我们可以将图⽚上传到特定的⽬录,然后配置nginx对于⽤户上传的图⽚,都转发到特定的⽬录,该⽬录不⼀定是nginx的html⽬录,甚⾄是挂载的盘,这样对于⼀般的应⽤来说,既可以按应⽤规划设置⽂件服务器,也避免了需要安装和维护ftp服务器软件的⼯作。
nginx配置 因为Nginx是模块化架构,每个模块都会有⼀系列⾃⼰引⼊的指令,这些指令通常包含在指令块中,⽐如events模块,就有⼀个events 块。
如下所⽰:events {worker_connections 1024;} 对于最常⽤的部分,指令块通常层层嵌套。
例如:http {server {listen 80;server_name ;access_log /var/log/nginx/.log;location ^~ /admin/ {index index.php;}}} 默认情况下,之块会继承⽗块中声明的设置,除⾮明确覆盖。
在nginx的配置中,语法⽐较复杂,⽽且不同的指令,可能规则完全不同。
⽐如root仅接受⼀个字符,声明服务于⽹站的⽂件的根路径。
模块中通常定义了可以⽤于指令中的变量,变量以$开头。
某些指令中不允许使⽤变量,⽐如error_log,此时它会被当做字⾯量处理。
指令的值可以带双引号、带单引号、不带引号,除⾮使⽤了特殊符号,此时需要⽤引号括起来以避免nginx解析误解,对于特殊符号需要当做字⾯量使⽤的,需要⽤\,⽐如$。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
By 薛长俊 2013-11
Nginx模块开发
模块化 daemon 编码规范
模块化
• 模块分类
handlers,处理http请求并构造输出 filters,处理handler产生的输出 load-balancers,当有多于一个的后端服务器时,选择一台将http请求发 送过去
模块化
daemon
• 编写Handler
Nginx允许handler一次产生一组输出,可以产生多次,Nginx将输出组织成一 个单链表结构,链表中的每个节点是一个chain_t。
daemon
• 组合Nginx Module
一个Nginx模块被定义为一个ngx_module_t结构,这个结构的字段很多,不 过开头和结尾若干字段一般可以通过Nginx内置的宏去填充,下面是我们 echo模块的模块主体定义:
模块化
• ngx_module_t,ngx_module_s
ngx_uint_t type; //用于区分core、event、http和mail。 ngx_int_t (*init_master)(ngx_log_t *log); //初始化master时执行 ngx_int_t (*init_module)(ngx_cycle_t *cycle); //初始化module时执行 ngx_int_t (*init_process)(ngx_cycle_t *cycle); //初始化process时执行 ngx_int_t (*init_thread)(ngx_cycle_t *cycle); //初始化thread时执行 void (*exit_thread)(ngx_cycle_t *cycle); //退出thread时执行 void (*exit_process)(ngx_cycle_t *cycle); //退出process时执行 void (*exit_master)(ngx_cycle_t *cycle); //退出master时执行 ....
daemon
• 定义指令
一个Nginx模块往往接收一至多个指令,echo模块接收一个指令“echo”。 指令数组的命名规则为ngx_http_[module-name]_commands,注意数组 最后一个元素要是ngx_null_command结束。
daemon
• 定义参数转化函数
这个函数除了调用ngx_conf_set_str_slot转化echo指令的参数外,还将修改 了核心模块配置(也就是这个location的配置),将其handler替换为我们编 写的handler:ngx_http_echo_handler。这样就屏蔽了此location的默认 handler,使用ngx_http_echo_handler产生HTTP响应。
}
模块化
• 上下文
typedef struct { ngx_int_t (*preconfiguration)(ngx_conf_t *cf); //读入配置文件前调用 ngx_int_t (*postconfiguration)(ngx_conf_t *cf); //读入配置文件后调用 void *(*create_main_conf)(ngx_conf_t *cf); //创建main配置时调用 char *(*init_main_conf)(ngx_conf_t *cf, void *conf); //初始化main配置时
模块化
• 函数执行时机
• 当服务读配置文件之前 • 读存在location和server或其他任何部分的每一个配置指令 • 当Nginx初始化全局部分的配置时 • 当Nginx初始化主机部分(比如主机/端口)的配置时 • 当Nginx将全局部分的配置与主机部分的配置合并的时候 • 当Nginx初始化位置部分配置的时候 • 当Nginx将其上层主机配置与位置部分配置合并的时候 • 当Nginx的主(master)进程开始的时候 • 当一个新的工作进程(worker)开始的时候 • 当一个工作进程退出的时候 • 当主进程退出的时候 • 处理请求
模块化
• 上下文
模块上下文是四个结构体定义的:ngx_core_module_t、ngx_event_module_t、 ngx_http_module_t、ngx_mail_module_t,分别对应于四类模块。 typedef struct { ngx_str_t name; void *(*create_conf)(ngx_cycle_t *cycle); //创建并初始化conf char *(*init_conf)(ngx_cycle_t *cycle, void *conf); //赋值给conf } ngx_core_module_t; typedef struct { ngx_str_t *name; void *(*create_conf)(ngx_cycle_t *cycle); char *(*init_conf)(ngx_cycle_t *cycle, void *conf); ngx_event_actions_t actions; //模块的操作handler, 如epoll的init、 add、del等 ngx_event_module_t;
首先我们需要一个结构用于存储从配置文件中读进来的相关指令参数,即模 块配置信息结构。根据Nginx模块开发规则,这个结构的命名规则为: ngx_http_[module-name]_[main|srv|loc]_conf_t 其中,main、srv和loc分别用于表示同一模块在三层block中的配置信息。 这里我们的echo模块只需要运行在loc层级下,需要存储一个字符串参数, 因此我们可以定义如下的模块配置:
daemon
• 定义模块Context
首先需要定义一个ngx_http_module_t类型的结构体变量,命名规则为: ngx_http_[module-name]_module_ctx 这个结构主要用于定义各个Hook函数。下面是echo模块的context结构:
其中create_loc_conf用于初始化一个配置结构体,如为配置结构体分配内存 等工作;merge_loc_conf用于将其父block的配置信息合并到此结构体中,也 就是实现配置的继承。这两个函数会被Nginx自动调用。 命名规则: ngx_http_[module-name]_[create|merge]_[main|srv|loc]_conf。
daemon
• 编写模块config文件
这个文件需要放在和模块源代码文件放在同一目录下。 文件内容如下:
我们的config文件:
daemon
• 编译安装
编译安装命令:
修改nginx配置并启动:
ngx_module_t *ngx_modules[] = { &ngx_core_module, &ngx_errlog_module, &ngx_conf_module, &ngx_events_module, …. }
模块化
• ngx_module_t,ngx_module_s
typedef struct ngx_module_s ngx_module_t; struct ngx_module_s { ngx_uint_t ctx_index; //分类的模块计数器,nginx模块分为四 种:core、event、http和mail,每个模块都会各自计数。
daemon
• 定义create、merge函数
daemon
• 编写Handler
handler可以说是模块中真正干活的代码,它主要有以下四项职责: 读入模块配置; 处理功能业务; 产生HTTP header; 产生HTTP body;
daemon
• 编写Handler
daemon
• 编写Handler
模块化
• ngx_command_t中type取值
NGX_HTTP_MAIN_CONF: 指令出现在全局配置部分是合法的 NGX_HTTP_SRV_CONF: 指令在主机配置部分出现是合法的 NGX_HTTP_LOC_CONF: 指令在位置配置部分出现是合法的 NGX_HTTP_UPS_CONF: 指令在上游服务器配置部分出现是合法的 NGX_CONF_NOARGS: 指令没有参数 NGX_CONF_TAKE1: 指令读入一个参数 NGX_CONF_TAKE2: 指令读入两个参数 ... 更多取值参照core/ngx_conf_file.h
模块化
• 函数执行时机
• 过滤回复的头部 • 过滤回复的主体 • 选择一台后端服务器 • 初始化到后端服务器的请求 • 重新初始化到后端的服务器的请求 • 处理来自后端服务器的回复 • 完成与后端服务器的交互
模块化
• 模块定义(objs/ngx_modules.c )
extern extern extern extern … ngx_module_t ngx_module_t ngx_module_t ngx_module_t ngx_core_module; ngx_errlog_module; ngx_conf_module; ngx_events_module;
调用
void *(*create_srv_conf)(ngx_conf_t *cf); //创建server配置时调用 char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf); //与 main配置合并时调用 void *(*create_loc_conf)(ngx_conf_t *cf); //创建location时调用 char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf); //与 server配置合并时调用 } ngx_http_module_t;