手把手教你开发Nginx模块
Nginx开发和配置教程
Nginx开发和配置教程一、Nginx的开发1. Nginx模块开发-编写模块的配置指令:模块的配置指令决定了模块如何被配置和使用。
-实现模块的处理函数:处理函数负责处理来自客户端的请求并返回响应。
- 注册模块:将模块注册到Nginx的配置中。
2. Nginx的事件驱动模型-事件模块:负责监听和接收客户端请求。
-连接池:管理与客户端的连接。
-请求处理:负责处理客户端的请求并返回响应。
二、Nginx的配置1. Nginx配置文件2. Nginx的基本配置指令- worker_processes:指定Nginx的工作进程数,用于处理并发请求。
- pid:指定Nginx的进程ID文件路径。
- error_log:指定错误日志文件的路径。
- access_log:指定访问日志文件的路径。
- events:指定Nginx的事件模块配置。
3. Nginx的虚拟主机配置- server:定义一个虚拟主机。
- listen:指定虚拟主机监听的端口。
- server_name:指定虚拟主机的域名。
- root:指定虚拟主机的根目录。
4. Nginx的负载均衡配置- upstream:定义一个负载均衡服务器组。
- server:定义一个后端服务器。
- weight:指定后端服务器的权重,用于分配请求。
- ip_hash:根据客户端IP地址进行负载均衡。
总结:本文介绍了Nginx的开发和配置教程。
在Nginx的开发方面,我们了解了Nginx的模块开发和事件驱动模型。
在Nginx的配置方面,我们了解了Nginx的配置文件,基本配置指令,虚拟主机配置和负载均衡配置。
希望这些内容能帮助您更好地开发和配置Nginx服务器。
Nginx源码分析--模块module解析执行nginx.conf配置文件流程分析一
Nginx源码分析--模块module解析执⾏nginx.conf配置⽂件流程分析⼀ 搭建nginx服务器时,主要的配置⽂件 nginx.conf 是部署和维护服务器⼈员经常要使⽤到的⽂件,⾥⾯进⾏了许多服务器参数的设置。
那么nginx 以模块 module为⾻架的设计下是如何运⽤模块 module来解析并执⾏nginx.conf配置⽂件下的指令的呢?在探究源码之前,需要对nginx下的模块 module 有个基本的认知(详情参考前⾯的博⽂ )同时也要对nginx中常⽤到的⼀些结构有个基本的了解如:内存池pool 管理相关的函数、ngx_string 的基本结构等(详情参考前⾯的博⽂),若不然看代码的时候可能不能很明晰其中的意思,本⽂着重探究的是解析执⾏的流程。
1、从main函数说起。
Nginx的main函数在nginx.c⽂件中(本⽂使⽤release-1.3.0版本源码,200⾏),因为是主函数其中涉及到了许许多多的功能模块的初始化等内容,我们只关注我们需要的部分。
看到326⾏:ngx_max_module = 0;for (i = 0; ngx_modules[i]; i++) {ngx_modules[i]->index = ngx_max_module++;} cycle = ngx_init_cycle(&init_cycle); 可以看出来,这⾥对 ngx_modules (中有介绍)进⾏了索引编号,并且计算得到模块的总数 ngx_max_module。
然后,对cycle进⾏初始化,跳转到 ngx_init_cycle中。
对于cycle 这个变量是nginx的核⼼变量,可以说模块机制都是围绕它进⾏的,⾥⾯的参数⽐较复杂涉及到的内容⼗分多,本⽂并不详细对它讨论,可以将其看作是⼀个核⼼资源库。
2、ngx_init_cycle 函数 这个函数在⽂件ngx_cycle.c中(43⾏),这个函数是nginx初始化中最重要的函数之⼀,⾥⾯涉及到与cycle变量相关的初始化⼯作,看到第188⾏cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module *sizeof(void *)); 这⾥获取了 ngx_max_module 个指针空间,⽤来保存每个模块的配置信息,从cycle 变量的字段conf_ctx 命名中就可以知道,ctx 为context 上下⽂的缩写。
nginx模块开发
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时执行 ....
nginx详细配置
nginx详细配置Nginx内容概览1、nginx简介(1)介绍 nginx的应⽤场景和具体可以做什么事情(2)介绍什么是反向代理(3)介绍什么是负载均衡(4)介绍什么是动静分离2、nginx安装(1)介绍 nginx在 linux系统中如何进⾏安装3、nginx常⽤的命令和配置⽂件(1)介绍 nginx启动、关闭、重新加载命令(2)介绍 nginx的配置⽂件4、nginx配置实例-反向代理5、nginx配置实例-负载均衡6、nginx配置实例-动静分离7、nginx原理与优化参数配置8、搭建 nginx⾼可⽤集群(1)搭建 nginx⾼可⽤集群(主从模式)(2)搭建 nginx⾼可⽤集群(双主模式)第 1 章 Nginx 简介1.1 Nginx 概述Nginx ("engine x") 是⼀个⾼性能的 HTTP 和反向代理服务器,特点是占有内存少,并发能⼒强,事实上 nginx的并发能⼒确实在同类型的⽹页服务器中表现较好,中国⼤陆使⽤ nginx⽹站⽤户有:百度、京东、新浪、⽹易、腾讯、淘宝等1.2 Nginx 作为 web 服务器Nginx 可以作为静态页⾯的 web 服务器,同时还⽀持 CGI 协议的动态语⾔,⽐如 perl、php等。
但是不⽀持 java。
Java程序只能通过与tomcat配合完成。
Nginx专为性能优化⽽开发,性能是其最重要的考量,实现上⾮常注重效率,能经受⾼负载的考验,有报告表明能⽀持⾼达50,000个并发连接数。
1.3 正向代理Nginx 不仅可以做反向代理,实现负载均衡。
还能⽤作正向代理来进⾏上⽹等功能。
正向代理:如果把局域⽹外的 Internet 想象成⼀个巨⼤的资源库,则局域⽹中的客户端要访问Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理。
1.4 反向代理反向代理,其实客户端对代理是⽆感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择⽬标服务器获取数据后,在返回给客户端,此时反向代理服务器和⽬标服务器对外就是⼀个服务器,暴露的是代理服务器地址,隐藏了真实服务器 IP地址。
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的网站都钟意其优异的性能表现,如果是相对比较大的网站,节约下来的服务器成本无疑是客观的。
nginx模块开发指南(中文)
Emiller的Nginx模块开发指南作者:Evan Miller草稿: 2009年8月13日译者:姚伟斌 草稿:2009年9月21日内容目录0. 预备知识 (1)1. Nginx模块任务委派的主要轮廓 (1)2. Nginx模块的组成 (3)2.1. 模块的配置结构体 (3)2.2. 模块的指令 (4)2.3. 模块的上下文 (6)2.3.1. 创建位置结构体(create_loc_conf) (8)2.3.2. 初始化结构体(merge_loc_conf) (8)2.4. 模块定义 (9)2.5. 模块注册 (10)3. 处理模块、过滤模块和 负载均衡模块 (10)3.1. 剖析处理模块(非代理) (10)3.1.1. 获得位置配置结构体 (10)3.1.2. 产生回复 (11)3.1.3. 发送HTTP头部 (12)3.1.4. 发送HTTP主体 (13)3.2. 上游模块剖析(又称代理模块) (14)3.2.1.代理模块回调函数的概要 (14)3.2.2. create_request 回调函数 (16)3.2.3. process_header 回调函数 (17)3.2.4. 状态保持 (18)3.3.处理模块的注册 (19)4 过滤模块 (19)4.1. 剖析头部过滤函数 (19)4.2. 剖析主体过滤函数 (20)4.3 过滤函数的注册 (22)5. 剖析负载均衡模块 (24)5.1.激活指令 (24)5.2.注册函数 (25)5.3.上游主机初始化函数 (27)5.4.同伴初始化函数 (28)5.5.负载均衡函数 (30)5.6. 同伴释放函数 (31)6. 完成并编译自定义模块 (32)7.高级话题 (33)中文版本修改日志 (33)翻译说明:在nginx的模块编写过程中,时常苦于文档的不足,而源代码中又没多少注释。
只有Emiller的这篇英文文档带我入门,在自己研读的过程中,就想将其翻译出来,让其他人能快速的浏览,但是如果你想更深入的进入nginx的代码开发,最好是多读nginx的代码。
Nginx模块开发手册
1. 预备知识你应当比较熟悉C语言。
不光是“C-语法",你起码还得知道结构体和预处理指令,同时保证看到指针和函数引用出现时心里不会发毛。
否则的话,就算信春哥也是没用的,看看K&R吧。
你得对HTTP协议有一定的了解,毕竟你是在和一个web server打交道。
如果你熟悉Nginx的配置文件就太好不过了。
如果不熟悉,也没关系,这里简单介绍一下,知道概念先:Nginx配置文件主要分成四部分:main(全局设置)、server(主机设置)、upstream(上游服务器设置)和location(URL匹配特定位置后的设置)。
每部分包含若干个指令。
main部分设置的指令将影响其它所有设置;server部分的指令主要用于指定主机和端口;upstream的指令用于设置一系列的后端服务器;location部分用于匹配网页位置(比如,根目录“/”,“/images”,等等)。
他们之间的关系式:server继承main,location继承server;upstream既不会继承指令也不会被继承。
它有自己的特殊指令,不需要在其他地方的应用。
在下面很多地方都会涉及这四个部分,切记。
好了,让我们开始吧。
2. Nginx模块委派概述Nginx的模块有三种角色:* handlers 处理http请求并构造输出* filters 处理handler产生的输出* load-balancers 当有多于一个的后端服务器时,选择一台将http请求发送过去许多可能你认为是web server的工作,实际上都是由模块来完成的:任何时候,Nginx提供文件或者转发请求到另一个server,都是通过handler来实现的;而当需要Nginx用gzip压缩输出或者在服务端加一些东东的话,filter就派上用场了;Nginx的core模块主要管理网络层和应用层协议,并启动针对特定请求的一系列后续模块。
这种分散式的体系结构使得由你自己来实现强大的内部单元成为了可能。
Emiller的nginx模块开发指引
要非常感谢nginx,它帮助我更加了解蝙蝠侠这个喜剧角色。
蝙蝠侠很快,nginx也很快。
蝙蝠侠在与罪恶斗争,nginx在与浪费CPU、内存泄漏等现象做斗争。
蝙蝠侠在压力下能保持良好状态,nginx在强大的服务请求压力下表现出色。
但是,蝙蝠侠如果没有那根蝙蝠侠万能腰带(batman utility belt),那他就什么都不是。
在任何时候,蝙蝠侠的万能腰带都应该包括一个锁扣、几个batarang(蝙蝠侠的特殊武器)、几个bat-cuff(护腕)、夜视眼镜、bat-tracer(跟踪器?)、几个bat-darts(蝙蝠镖)...或者还包括一个apple iphone。
当蝙蝠侠需要使他的敌人失明、失聪、或者晕倒,或者当他需要跟踪他的敌人,或者给他的敌人发个短信,你最好相信他正在他的万能腰带上找一个合适的工具。
这根腰带对蝙蝠侠的行动如此至关重要,所以,当蝙蝠侠在选择穿裤子还是穿腰带的时候,他肯定会选择穿腰带。
事实上他确实选择了腰带,这就是为什么蝙蝠侠穿着紧绷的橡胶衣,而没有穿裤子。
虽然nginx没有这样一条万能腰带,但是nginx有一个模块链(module chain),当nginx需要对应答进行gzip或chunked编码时,它会拿出一个模块来做这个工作。
当nginx基于IP或http认证来阻拦对某些资源的访问时,也是由一个模块来做这些工作的。
同样,当nginx需要和memcahed或者fastCGI交互时,也分别由对应的模块来做相应的工作。
尽管蝙蝠侠的万能腰带上有很多小玩意,但是有时候他还是需要一个新的小工具。
也许他有新的敌人,而他现在的武器(如batarang或bat-cuff)都不足以对付这个敌人。
也许他需要有新的技能,比如在水下呼吸。
所以他会让Lucius Fox来帮他设计这些小工具。
这个文档会告诉你nginx模块链表(module chain)的一些细节,这样你就可以做到像Lucius Fox一样。
nginx入门菜鸟教程
nginx入门菜鸟教程Nginx是一款高性能的开源Web服务器和反向代理服务器,被广泛应用于构建高效、可靠的网络应用。
本文将为初学者介绍Nginx的基本概念、安装和配置,以及常见的应用场景和优化技巧。
一、Nginx简介Nginx(发音为“Engine X”)是由Igor Sysoev于2004年开发的一款高性能的Web服务器和反向代理服务器。
其设计目标是处理大量并发连接,具有内存占用低、稳定性高、易于扩展等特点。
目前,Nginx已成为广泛应用的Web服务器,在全球排名第二二、Nginx的安装和配置1. 安装Nginx首先,我们要在服务器上安装Nginx。
具体安装方式根据操作系统的不同略有差异。
以Ubuntu为例,可以使用以下命令进行安装:```sudo apt-get updatesudo apt-get install nginx```2.基本配置- 服务器监听端口:默认情况下,Nginx监听80端口。
可以通过修改`listen`指令来改变监听端口。
- 虚拟主机配置:Nginx支持虚拟主机,可以在配置文件中添加多个`server`块,代表不同的虚拟主机。
每个`server`块可以配置不同的域名和应用程序。
- 反向代理配置:Nginx还可以作为反向代理服务器,将客户端的请求转发给后端的应用程序。
可以通过在配置文件中添加`location`指令来配置反向代理。
3.配置文件的重新加载和重启配置Nginx后,需要重新加载配置文件使得修改生效。
可以使用以下命令进行重新加载:```sudo nginx -s reload```需要注意的是,如果修改了配置文件中的监听端口,则需要重启Nginx使得修改生效:```sudo service nginx restart```三、Nginx的应用场景1.静态文件服务器Nginx的高性能和低内存占用使得它非常适合作为静态文件服务器。
可以将静态文件(如图片、CSS和JavaScript文件)放在Nginx的根目录下,Nginx会快速、高效地将这些文件传输给客户端。
nginx模块开发例子
nginx模块开发例子Nginx是一款轻量级的Web服务器,也可以用作反向代理服务器、负载均衡器和HTTP缓存。
它的开发模块允许开发人员通过为Nginx添加自定义功能来扩展其功能。
下面给出了一些关于Nginx 模块开发的例子。
1. 创建一个简单的Hello World模块:这个模块可以在每个HTTP请求的响应中添加一个"Hello World"的字符串。
通过在Nginx的配置文件中添加该模块,可以在服务器的每个HTTP响应中看到"Hello World"。
2. 实现IP限流模块:这个模块可以根据IP地址对请求进行限流。
通过配置该模块,可以限制每个IP地址在一定时间内可以发送的请求数量,从而增强服务器的安全性和性能。
3. 自定义访问日志模块:这个模块可以根据开发人员的需求自定义访问日志的格式和内容。
通过编写自定义的日志模块,可以记录更详细的访问日志信息,以便进行更好的分析和监控。
4. 实现简单的URL重写模块:这个模块可以根据正则表达式将URL重写为指定的格式。
通过配置该模块,可以实现URL的美化和优化,提升网站的用户体验和SEO效果。
5. 实现动态内容生成模块:这个模块可以根据请求的参数生成动态的内容。
通过编写自定义的模块,可以根据用户的请求参数动态生成页面内容,实现个性化和定制化的网页。
6. 自定义SSL证书模块:这个模块可以根据开发人员的需求自定义SSL证书的生成和使用方式。
通过编写自定义的SSL证书模块,可以提供更灵活和安全的SSL证书管理功能。
7. 实现反向代理缓存模块:这个模块可以将请求的响应缓存在Nginx中,以提高网站的性能和响应速度。
通过配置该模块,可以根据需求设置缓存的过期时间、缓存的大小和缓存的失效策略。
8. 自定义HTTP请求处理模块:这个模块可以根据开发人员的需求自定义HTTP请求的处理方式。
通过编写自定义的模块,可以实现更灵活和定制化的HTTP请求处理逻辑,满足不同场景的需求。
Nginx开发从入门到精通-04、upstream模块
upstream模块(100%)nginx模块一般被分成三大类:handler、filter和upstream。
前面的章节中,读者已经了解了handler、filter。
利用这两类模块,可以使nginx轻松完成任何单机工作。
而本章介绍的upstream模块,将使nginx跨越单机的限制,完成网络数据的接收、处理和转发。
数据转发功能,为nginx提供了跨越单机的横向处理能力,使nginx摆脱只能为终端节点提供单一功能的限制,而使它具备了网路应用级别的拆分、封装和整合的战略功能。
在云模型大行其道的今天,数据转发是nginx有能力构建一个网络应用的关键组件。
当然,鉴于开发成本的问题,一个网络应用的关键组件一开始往往会采用高级编程语言开发。
但是当系统到达一定规模,并且需要更重视性能的时候,为了达到所要求的性能目标,高级语言开发出的组件必须进行结构化修改。
此时,对于修改代价而言,nginx的upstream模块呈现出极大的吸引力,因为它天生就快。
作为附带,nginx的配置系统提供的层次化和松耦合使得系统的扩展性也达到比较高的程度。
言归正传,下面介绍upstream的写法。
upstream模块接口从本质上说,upstream属于handler,只是他不产生自己的内容,而是通过请求后端服务器得到内容,所以才称为upstream(上游)。
请求并取得响应内容的整个过程已经被封装到nginx内部,所以upstream模块只需要开发若干回调函数,完成构造请求和解析响应等具体的工作。
这些回调函数如下表所示:memcached模块分析memcache是一款高性能的分布式cache系统,得到了非常广泛的应用。
memcache定义了一套私有通信协议,使得不能通过HTTP请求来访问memcache。
但协议本身简单高效,而且memcache使用广泛,所以大部分现代开发语言和平台都提供了memcache支持,方便开发者使用memcache。
Nginx模块Lua-Nginx-Module学习笔记(二)Lua指令详解(Directives)
Nginx模块Lua-Nginx-Module学习笔记(⼆)Lua指令详解(Directives)Nginx与Lua编写脚本的基本构建块是指令。
指令⽤于指定何时运⾏⽤户Lua代码以及如何使⽤结果。
下⾯是显⽰指令执⾏顺序的图。
当⼀个请求发起⼀个“⼦请求”的时候,按照 Nginx 的术语,习惯把前者称为后者的“⽗请求”(parent request)。
location /main {echo_location /foo; # echo_location发送⼦请求到指定的locationecho_location /bar;}location /foo {echo Tinywan_foo;}location /bar {echo Tinywan_bar;}重启Nginx,curl访问root@iZ236j3sofdZ:/usr/local/nginx/conf # service nginx restart* Stopping Nginx Server... [ OK ]* Starting Nginx Server... [ OK ]root@iZ236j3sofdZ:/usr/local/nginx/conf # curl 'http://localhost/main'Tinywan_fooTinywan_bar 这⾥,main location就是发送2个⼦请求,分别到foo和bar,这就类似⼀种函数调⽤。
“⼦请求”⽅式的通信是在同⼀个虚拟主机内部进⾏的,所以 Nginx 核⼼在实现“⼦请求”的时候,就只调⽤了若⼲个 C 函数,完全不涉及任何⽹络或者 UNIX 套接字(socket)通信。
我们由此可以看出“⼦请求”的执⾏效率是极⾼的。
协程(Coroutine)协程类似⼀种多线程,与多线程的区别有:1. 协程并⾮os线程,所以创建、切换开销⽐线程相对要⼩。
2. 协程与线程⼀样有⾃⼰的栈、局部变量等,但是协程的栈是在⽤户进程空间模拟的,所以创建、切换开销很⼩。
Nginx开发从入门到精通-05、其他模块
其他模块(40%)Nginx的模块种类挺多的,除了HTTP模块,还有一些核心模块和mail系列模块。
核心模块主要是做一些基础功能,比如Nginx的启动初始化,event处理机制,错误日志的初始化,ssl的初始化,正则处理初始化。
mail模块可以对imap,pop3,smtp等协议进行反向代理,这些模块本身不对邮件内容进行处理。
core模块(40%)Nginx的启动模块(40%)启动模块从启动Nginx进程开始,做了一系列的初始化工作,源代码位于src/core/nginx.c,从main 函数开始:1.时间、正则、错误日志、ssl等初始化2.读入命令行参数3.OS相关初始化4.读入并解析配置5.核心模块初始化6.创建各种暂时文件和目录7.创建共享内存8.打开listen的端口9.所有模块初始化10.启动worker进程event模块(40%)event的类型和功能(40%)Nginx是以event(事件)处理模型为基础的模块。
它为了支持跨平台,抽象出了event模块。
它支持的event处理类型有:AIO(异步IO),/dev/poll(Solaris 和Unix特有),epoll(Linux特有),eventport(Solaris 10特有),kqueue(BSD特有),poll,rtsig(实时信号),select等。
event模块的主要功能就是,监听accept后建立的连接,对读写事件进行添加删除。
事件处理模型和Nginx的非阻塞IO模型结合在一起使用。
当IO可读可写的时候,相应的读写事件就会被唤醒,此时就会去处理事件的回调函数。
特别对于Linux,Nginx大部分event采用epoll EPOLLET(边沿触发)的方法来触发事件,只有listen端口的读事件是EPOLLLT(水平触发)。
对于边沿触发,如果出现了可读事件,必须及时处理,否则可能会出现读事件不再触发,连接饿死的情况。
上述是event处理抽象出来的关键结构体,可以看到,每个event处理模型,都需要实现部分功能。
Nginx搭建(完整版)
目录1搭建nginx需要的安装包-----------------------------------------------------------------------2 2前期准备--------------------------------------------------------------------------------------------22.1 检测-----------------------------------------------------------------------------------------22.2安装libiconv-1.13--------------------------------------------------------------------------22.3安装libmcrypt-2.5.8.----------------------------------------------------------------------22.4安装mhash-0.9.9.9-------------------------------------------------------------------------22.5安装mcrypt-2.6.8--------------------------------------------------------------------------33安装mysql------------------------------------------------------------------------------------------3 3.1创建用户和组--------------------------------------------------------------------------------3 3.2安装编译--------------------------------------------------------------------------------------3 3.3创建MySQL数据库存放目录------------------------------------------------------------3 3.4创建f配置文件-----------------------------------------------------------------------3 3.5创建管理MySQL数据库的shell脚本---------------------------------------------------5 3.6创建账户,赋予关闭的权限----------------------------------------------------------------6 4安装编译php----------------------------------------------------------------------------------------6 4.1 编译php---------------------------------------------------------------------------------------6 4.2编译安装PHP扩展模块--------------------------------------------------------------------74.2.1编译memcache--------------------------------------------------------------------------74.2.2编译eaccelerator-0.9.5.3--------------------------------------------------------------74.2.3编译PDO_MYSQL-1.0.2-------------------------------------------------------------74.2.4编译ImageMagick----------------------------------------------------------------------74.2.5编译imagick-2.2.2-----------------------------------------------------------------------74.3 修改php配置文件------------------------------------------------------------------------74.4配置eAccelerator加速PHP--------------------------------------------------------------84.5创建www用户和组------------------------------------------------------------------------84.6创建虚拟机目录-----------------------------------------------------------------------------84.7创建php-fpm配置文件--------------------------------------------------------------------84.8启动php-cgi进程---------------------------------------------------------------------------12 5安装编译nginx-----------------------------------------------------------------------------------125.1安装Nginx所需的pcre库---------------------------------------------------------------125.2安装Nginx----------------------------------------------------------------------------------125.3建Nginx配置文件-------------------------------------------------------------------------125.4启动Nginx-----------------------------------------------------------------------------------125.5配置开机自动启动Nginx + PHP--------------------------------------------------------135.6优化Linux内核参数-----------------------------------------------------------------------135.7在不停止Nginx服务的情况下平滑变更Nginx配置--------------------------------135.7.1检查配置文件---------------------------------------------------------------------------135.7.2 nginx进程--------------------------------------------------------------------------------145.8编写每天定时切割Nginx日志的脚本---------------------------------------------------145.8.1创建脚本---------------------------------------------------------------------------------145.8.2添加自动任务----------------------------------------------------------------------------146 安装编译memcached-------------------------------------------------------------------------------156.1 安装编译libevent-----------------------------------------------------------------------------156.2 安装编译memcached------------------------------------------------------------------------156.3 启动memcached守护进程-----------------------------------------------------------------156.4 php使用测试--------------------------------------------------------------------------------156.5 停止memcached服务-----------------------------------------------------------------------151、搭建nginx需要的安装包放在219.234.83.29服务器上cd /home/chenjl/software/nginx0.8_basepacage2、前期准备2.1需要安装一些常用的包,在安装服务器时选择安装开发工具,会安装一些常用的包,如果安装了yum,可以用检测一下(【适用CentOS操作系统】)yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers2.2安装libiconv-1.13.tar.gztar zxvf libiconv-1.13.tar.gzcd libiconv-1.13/./configure --prefix=/usr/localmakemake install2.3安装libmcrypt-2.5.8.tar.gztar zxvf libmcrypt-2.5.8.tar.gzcd libmcrypt-2.5.8/./configuremakemake install/sbin/ldconfigcd libltdl/./configure --enable-ltdl-installmakemake install2.4安装mhash-0.9.9.9.tar.gztar zxvf mhash-0.9.9.9.tar.gzcd mhash-0.9.9.9/./configuremakemake installln -s /usr/local/lib/ /usr/lib/ln -s /usr/local/lib/libmcrypt.so /usr/lib/libmcrypt.soln -s /usr/local/lib/libmcrypt.so.4 /usr/lib/libmcrypt.so.4ln -s /usr/local/lib/libmcrypt.so.4.4.8 /usr/lib/libmcrypt.so.4.4.8ln -s /usr/local/lib/libmhash.a /usr/lib/libmhash.aln -s /usr/local/lib/ /usr/lib/ln -s /usr/local/lib/libmhash.so /usr/lib/libmhash.soln -s /usr/local/lib/libmhash.so.2 /usr/lib/libmhash.so.2ln -s /usr/local/lib/libmhash.so.2.0.1 /usr/lib/libmhash.so.2.0.12.5安装mcrypt-2.6.8.tar.gztar zxvf mcrypt-2.6.8.tar.gzcd mcrypt-2.6.8//sbin/ldconfig./configuremakemake install3、安装mysql3.1 创建用户和组/usr/sbin/groupadd mysql/usr/sbin/useradd -g mysql mysql3.2 安装编译tar zxvf mysql-5.1.38.tar.gzcd mysql-5.1.38/./configure --prefix=/usr/local/mysql/ --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-big-tables --with-readline --with-ssl --with-embedded-server --enable-local-infile --with-plugins=innobasemake && make installchmod +w /usr/local/mysqlchown -R mysql:mysql /usr/local/mysqlmkdir -p /usr/local/mysqldata/3.3创建MySQL数据库存放目录chown -R mysql:mysql /usr/local/mysql/data//usr/local/mysql/bin/mysql_install_db --basedir=/usr/local/mysql --datadir=/usr/local/mysql /data --user=mysql3.4创建f配置文件输入以下内容:###############################[client]default-character-set = utf8port = 3306socket = /tmp/mysql.sock[mysql]prompt="(\u::)[\d]> "no-auto-rehash[mysqld]#default-character-set = utf8user = mysqlport = 3306socket = /tmp/mysql.sockbasedir = /usr/local/mysqldatadir = /usr/local/mysql/dataopen_files_limit = 10240back_log = 600max_connections = 3000max_connect_errors = 6000table_cache = 614external-locking = FALSEmax_allowed_packet = 32Msort_buffer_size = 2Mjoin_buffer_size = 2Mthread_cache_size = 300thread_concurrency = 8query_cache_size = 32Mquery_cache_limit = 2Mquery_cache_min_res_unit = 2kdefault-storage-engine = MyISAMdefault_table_type = MyISAMthread_stack = 192Ktransaction_isolation = READ-COMMITTED tmp_table_size = 246Mmax_heap_table_size = 246Mlong_query_time = 1log_long_formatlog-bin = /data0/mysql/3306/binlogbinlog_cache_size = 4Mbinlog_format = MIXEDmax_binlog_cache_size = 8Mmax_binlog_size = 512Mexpire_logs_days = 7key_buffer_size = 256Mread_buffer_size = 1Mread_rnd_buffer_size = 16Mbulk_insert_buffer_size = 64Mmyisam_sort_buffer_size = 128Mmyisam_max_sort_file_size = 10Gmyisam_max_extra_sort_file_size = 10G myisam_repair_threads = 1myisam_recoverskip-name-resolvemaster-connect-retry = 10slave-skip-errors = 1032,1062,126,1114,1146,1048,1396server-id = 1innodb_additional_mem_pool_size = 16Minnodb_buffer_pool_size = 2048Minnodb_data_file_path = ibdata1:1024M:autoextendinnodb_file_io_threads = 4innodb_thread_concurrency = 8innodb_flush_log_at_trx_commit = 2innodb_log_buffer_size = 16Minnodb_log_file_size = 128Minnodb_log_files_in_group = 3innodb_max_dirty_pages_pct = 90innodb_lock_wait_timeout = 120innodb_file_per_table = 0[mysqldump]quickmax_allowed_packet = 32M以上数据,根据需要做修改;3.5创建管理MySQL数据库的shell脚本#!/bin/shmysql_port=3306mysql_username="chenjl"mysql_password="cjl1981"function_start_mysql(){printf "Starting MySQL...\n"/bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/usr/local/mysql/f 2>&1 > /dev/null &}function_stop_mysql(){printf "Stoping MySQL...\n"/usr/local/mysql/bin/mysqladmin -u ${mysql_username} -p${mysql_password} -S /tmp/mysql.sock shutdown}function_restart_mysql(){printf "Restarting MySQL...\n"function_stop_mysqlsleep 5function_start_mysql}function_kill_mysql(){kill -9 $(ps -ef | grep 'bin/mysqld_safe' | grep ${mysql_port} | awk '{printf $2}')kill -9 $(ps -ef | grep 'libexec/mysqld' | grep ${mysql_port} | awk '{printf $2}')}if [ "$1" = "start" ]; thenfunction_start_mysqlelif [ "$1" = "stop" ]; thenfunction_stop_mysqlelif [ "$1" = "restart" ]; thenfunction_restart_mysqlelif [ "$1" = "kill" ]; thenfunction_kill_mysqlelseprintf "Usage: /data0/mysql/${mysql_port}/mysql {start|stop|restart|kill}\n"fichmod 755 /usr/local/mysql/bin/mysql.sh3.6 创建账户,赋予关闭的权限/usr/local/mysql/bin/mysql -u root -p -S /tmp/mysql.sockGRANT ALL PRIVILEGES ON *.* TO 'chenjl'@'localhost' IDENTIFIED BY 'cjl1981';GRANT ALL PRIVILEGES ON *.* TO 'chenjl'@'127.0.0.1' IDENTIFIED BY 'cjl1981;4、安装编译php4.1 编译phptar zxvf php-5.2.10.tar.gzgzip -cd php-5.2.10-fpm-0.5.11.diff.gz | patch -d php-5.2.10 -p1cd php-5.2.10/./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-iconv-dir=/usr/local --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-discard-path --enable-safe-mode --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --with-curlwrappers --enable-mbregex --enable-fastcgi --enable-fpm --enable-force-cgi-redirect --enable-mbstring --with-mcrypt --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-ldap --with-ldap-sasl --with-xmlrpc --enable-zip --enable-soap --without-pearmake ZEND_EXTRA_LIBS='-liconv'make installcp php.ini-dist /usr/local/php/etc/php.inicurl /go-pear | /usr/local/php/bin/php4.2编译安装PHP扩展模块4.2.1 编译memcachetar zxvf memcache-2.2.5.tgzcd memcache-2.2.5//usr/local/php/bin/phpize./configure --with-php-config=/usr/local/php/bin/php-configmakemake install启动方式:/usr/local/bin/memcached -d -m 64 -u root -l 127.0.0.1 -p 11211 -c 1024 -P /tmp/memcached.pid4.2.2 编译eaccelerator-0.9.5.3tar jxvf eaccelerator-0.9.5.3.tar.bz2cd eaccelerator-0.9.5.3//usr/local/php/bin/phpize./configure --enable-eaccelerator=shared --with-php-config=/usr/local/php/bin/php-configmakemake install4.2.3编译PDO_MYSQL-1.0.2tar zxvf PDO_MYSQL-1.0.2.tgzcd PDO_MYSQL-1.0.2//usr/local/php/bin/phpize./configure --with-php-config=/usr/local/php/bin/php-config --with-pdo-mysql=/usr/local/mysqlmakemake install4.2.4编译ImageMagicktar zxvf ImageMagick.tar.gzcd ImageMagick-6.5.1-2/./configure tar zxvf imagick-2.2.2.tgzmakemake instal4.2.5 编译imagick-2.2.2tar zxvf imagick-2.2.2.tgzcd imagick-2.2.2//usr/local/php/bin/phpize./configure --with-php-config=/usr/local/php/bin/php-configmakemake install4.3 修改php配置文件手工修改:查找/usr/local/php/etc/php.ini中的extension_dir = "./"修改为extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/"并在此行后增加以下几行,然后保存:extension = "memcache.so"extension = "pdo_mysql.so"extension = "imagick.so"再查找output_buffering = Off修改为output_buffering = On4.4配置eAccelerator加速PHPmkdir -p /usr/local/eaccelerator_cachevi /usr/local/php/etc/php.ini按shift+g键跳到配置文件的最末尾,加上以下配置信息:[eaccelerator]zend_extension="/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/eacceler ator.so"eaccelerator.shm_size="64"eaccelerator.cache_dir="/usr/local/eaccelerator_cache"eaccelerator.enable="1"eaccelerator.optimizer="1"eaccelerator.check_mtime="1"eaccelerator.debug="0"eaccelerator.filter=""eaccelerator.shm_max="0"eaccelerator.shm_ttl="3600"eaccelerator.shm_prune_period="3600"eaccelerator.shm_only="0"press="1"press_level="9"4.5创建www用户和组usr/sbin/groupadd www/usr/sbin/useradd -g www www4.6创建虚拟机目录Mkdir /usr/local/wwwChown –R www:www /usr/local/www4.7创建php-fpm配置文件<?xml version="1.0" ?><configuration>All relative paths in this config are relative to php's install prefix<section name="global_options">Pid file<value name="pid_file">/usr/local/php/logs/php-fpm.pid</value>Error log file<value name="error_log">/usr/local/php/logs/php-fpm.log</value>Log level<value name="log_level">notice</value>When this amount of php processes exited with SIGSEGV or SIGBUS ...<value name="emergency_restart_threshold">10</value>... in a less than this interval of time, a graceful restart will be initiated.Useful to work around accidental curruptions in accelerator's shared memory. <value name="emergency_restart_interval">1m</value>Time limit on waiting child's reaction on signals from master<value name="process_control_timeout">5s</value>Set to 'no' to debug fpm<value name="daemonize">yes</value></section><workers><section name="pool">Name of pool. Used in logs and stats.<value name="name">default</value>Address to accept fastcgi requests on.Valid syntax is 'ip.ad.re.ss:port' or just 'port' or '/path/to/unix/socket'<value name="listen_address">127.0.0.1:9000</value><value name="listen_options">Set listen(2) backlog<value name="backlog">-1</value>Set permissions for unix socket, if one used.In Linux read/write permissions must be set in order to allow connections from web server.Many BSD-derrived systems allow connections regardless of permissions.<value name="owner"></value><value name="group"></value><value name="mode">0666</value></value>Additional php.ini defines, specific to this pool of workers.<value name="php_defines"><value name="sendmail_path">/usr/sbin/sendmail -t -i</value><value name="display_errors">1</value></value>Unix user of processes<value name="user">www</value>Unix group of processes<value name="group">www</value>Process manager settings<value name="pm">Sets style of controling worker process count.Valid values are 'static' and 'apache-like'<value name="style">static</value>Sets the limit on the number of simultaneous requests that will be served.Equivalent to Apache MaxClients directive.Equivalent to PHP_FCGI_CHILDREN environment in original php.fcgiUsed with any pm_style.<value name="max_children">128</value>Settings group for 'apache-like' pm style<value name="apache_like">Sets the number of server processes created on startup.Used only when 'apache-like' pm_style is selected<value name="StartServers">20</value>Sets the desired minimum number of idle server processes.Used only when 'apache-like' pm_style is selected<value name="MinSpareServers">5</value>Sets the desired maximum number of idle server processes.Used only when 'apache-like' pm_style is selected<value name="MaxSpareServers">35</value></value></value>The timeout (in seconds) for serving a single request after which the worker process will be terminatedShould be used when 'max_execution_time' ini option does not stop script execution for some reason'0s' means 'off'<value name="request_terminate_timeout">0s</value>The timeout (in seconds) for serving of single request after which a php backtrace will be dumped to slow.log file'0s' means 'off'<value name="request_slowlog_timeout">0s</value>The log file for slow requests<value name="slowlog">logs/slow.log</value>Set open file desc rlimit<value name="rlimit_files">65535</value>Set max core size rlimit<value name="rlimit_core">0</value>Chroot to this directory at the start, absolute path<value name="chroot"></value>Chdir to this directory at the start, absolute path<value name="chdir"></value>Redirect workers' stdout and stderr into main error log.If not set, they will be redirected to /dev/null, according to FastCGI specs<value name="catch_workers_output">yes</value>How much requests each process should execute before respawn.Useful to work around memory leaks in 3rd party libraries.For endless request processing please specify 0Equivalent to PHP_FCGI_MAX_REQUESTS<value name="max_requests">102400</value>Comma separated list of ipv4 addresses of FastCGI clients that allowed to connect.Equivalent to FCGI_WEB_SERVER_ADDRS environment in original php.fcgi (5.2.2+) Makes sense only with AF_INET listening socket.<value name="allowed_clients">127.0.0.1</value>Pass environment variables like LD_LIBRARY_PATHAll $V ARIABLEs are taken from current environment<value name="environment"><value name="HOSTNAME">$HOSTNAME</value><value name="PATH">/usr/local/bin:/usr/bin:/bin</value><value name="TMP">/tmp</value><value name="TMPDIR">/tmp</value><value name="TEMP">/tmp</value><value name="OSTYPE">$OSTYPE</value><value name="MACHTYPE">$MACHTYPE</value><value name="MALLOC_CHECK_">2</value></value></section></workers></configuration>注:请将以下的<value name="display_errors">0</value>改为<value name="display_errors">1</value>,以便显示PHP错误信息,否则,Nginx 会报状态为500的空白错误页)4.8启动php-cgi进程,监听127.0.0.1的9000端口,进程数为200(如果服务器内存小于3GB,可以只开启64个进程),用户为www:ulimit -SHn 65535/usr/local/php/sbin/php-fpm start注:/usr/local/php/sbin/php-fpm还有其他参数,包括:start|stop|quit|restart|reload|logrotate,修改php.ini后不重启php-cgi,重新加载配置文件使用reload。
nginx模块编译
nginx模块编译Nginx是一个高性能的开源Web服务器和反向代理服务器。
它具有模块化的架构,通过编写Nginx模块,我们可以对Nginx进行扩展和定制,以满足特定需求。
本文将介绍Nginx模块的编译过程和相关知识。
一、Nginx模块的概念和作用Nginx模块是一段用C语言编写的代码,用于扩展和定制Nginx的功能。
通过编写模块,我们可以添加新的功能、修改现有功能或者屏蔽某些功能。
模块可以与Nginx的核心模块进行交互,通过回调函数实现对请求的处理和响应。
二、Nginx模块的编译过程1.准备开发环境在编写Nginx模块之前,我们首先需要准备好开发环境。
需要安装好Nginx和相关的编译工具,比如gcc、make等。
2.编写模块代码编写Nginx模块的代码需要遵循一定的规范,包括定义模块的结构体、实现模块的初始化函数和回调函数等。
在编写代码时,可以参考Nginx的源码和官方文档,以确保代码的正确性和可靠性。
3.配置Nginx编译参数在编译Nginx时,需要指定模块的路径和相关参数。
可以使用--add-module选项指定模块的路径,也可以使用--with模块名选项启用某个已经编译好的模块。
4.编译和安装Nginx完成配置后,通过make命令进行编译,然后使用make install命令进行安装。
安装完成后,新的模块将会被添加到Nginx的安装目录中。
5.配置和启动Nginx在Nginx的配置文件中,需要添加对新模块的引用。
可以通过指令load_module或者include将模块的配置文件包含进来。
然后通过启动Nginx服务,新的模块将会生效。
三、常见的Nginx模块类型1.核心模块核心模块是Nginx的基础功能模块,包括HTTP模块、事件模块、日志模块等。
它们提供了Nginx的基本功能,如处理HTTP请求、管理连接、记录日志等。
2.第三方模块第三方模块是由开发者自行编写并发布的模块,用于扩展Nginx的功能。
Nginx开发从入门到精通【pdf】版
使用简介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
nginx 特点介绍 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Nginx 开发从入门到精通
发布 0.1 taobao server platform
2013 年 01 月 25 日
前言
i
ii
目录
前言
i
1 缘起
1
2 版权申明
3
3 目录
5
3.1 上篇:nginx 模块开发篇 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
部分 handler 模块的分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.1.4 过滤模块 (90%) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
nginx 基础概念 (100%) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
基本数据结构 (20%) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Nginx模块开发入门(转)
Nginx 模块开发⼊门(转)前⾔Nginx 是当前最流⾏的HTTP Server 之⼀,根据W3Techs 的统计,⽬前世界排名(根据Alexa )前100万的⽹站中,。
与Apache 相⽐,。
Nginx 属于典型的微内核设计,其内核⾮常简洁和优雅,同时具有⾮常⾼的可扩展性。
Nginx 最初仅仅主要被⽤于做反向代理,后来随着HTTP 核⼼的成熟和各种HTTP 扩展模块的丰富,Nginx 越来越多被⽤来取代Apache ⽽单独承担HTTP Server 的责任,例如⽬前淘宝内各个部门正越来越多使⽤Nginx 取代Apache ,据笔者了解,在腾讯和新浪等公司也存在类似情况。
同时,⼤量的第三⽅扩展模块也令Nginx 越来越强⼤。
例如,由淘宝的⼯程师清⽆(王晓哲)和春来(章亦春)所开发的可以将Lua 语⾔嵌⼊到Nginx 配置中,从⽽利⽤Lua 极⼤增强了Nginx 本⾝的编程能⼒,甚⾄可以不⽤配合其它脚本语⾔(如PHP 或Python 等),只靠Nginx 本⾝就可以实现复杂业务的处理。
⽽春来所开发的更是通过集成等组件,将Nginx 本⾝变成了⼀个完全的应⽤开发平台。
⽬前淘宝数据平台与产品部量⼦统计的产品都是基于ngx_openresty 所开发。
对ngxin_lua_module 或ngx_openresty 感兴趣的朋友可以参考我在关键词上给出的链接,后续我也可能会写⼀些与其有关的⽂章。
本⽂将会重点关注Nginx 模块开发⼊门及基础。
⽬前Nginx 的学习资料⾮常少,⽽扩展模块开发相关的资料⼏乎只有《》⼀⽂,此⽂⼗分经典,但是由于Nginx 版本的演进,其中少许内容可能有点过时。
本⽂是笔者在研读这篇⽂章和Nginx 源代码的基础上,对⾃⼰学习Nginx 模块开发的⼀个总结。
本⽂将通过⼀个完整的模块开发实例讲解Nginx 模块开发的⼊门内容。
本⽂将基于Nginx 最新的版本,操作系统环境为Linux (Ubuntu10.10)。
手把手教你开发Nginx模块
手把手教你开发Nginx模块手把手教你开发Nginx模块关于Nginx模块开发的博客资料,网上很多,很多。
但是,每篇博客都只提要点,无法"stepbystep"照着做,对于初次接触Nginx开发的同学,只能像只盲目的蚂蚁瞎燥急!该篇文章没有太多技术深度,只是一步一步说明白Nginx模块的开发过程。
开发环境搭建工欲善其事,必先利其器。
个人推荐EclipseCDT作为IDE,原因很简单,代码提示与补全功能很全,完胜Codeblock这类...相信与否,试过就知道。
在ubuntu下搭建开发环境:安装GCC编译器apt-getinstallbuild-essential安装pcre/openssl/zlib开发库apt-getinstalllibpcre3-devapt-getinstalllibssl-devapt-getinstalllibzip-dev必需安装nginx核心模块依赖的pcre,openssl,zilib开发库安装JRE/EclipseCDTapt-getinstallopenjdk-8-jrewgethttp://ftp.yz.yamagata-u.ac.jp/pub/eclipse//technology/epp/downloads/release/neon/ R/eclipse-cpp-neon-R-linux-gtk-x86_64.tar.gz&&tzr-xzvfeclipse-cpp-neon-R-linux-gtk-x86_64.tar.gz下载nginx源码wget/download/nginx-1.10.1.tar.gz&&tar-xzvfnginx-1.10.1.tar.gz配置CDTBuildEnvironment添加变量,值Nginxsrc下各模块路径,用冒号分隔,例如:/root/Workspace/nginx-1.10.1/src/core:/root/Workspace/nginx-1.10.1/src/event:/root/Workspace/nginx-1.10.1/src/http:/root/Workspace/nginx-1.10.1/src/mail:/root/Workspace/nginx-1.10.1/src/stream:/root/Workspace/nginx-1.10.1/src/os/unix添加环境变量,创建C项目时自动作为-I选项imageimageNginx模块编译流程Nginx使用configure脚本分析环境,自动生成objs结果。
Nginx开发从入门到精通-02、handler模块
handler模块简介相信大家在看了前一章的模块概述以后,都对nginx的模块有了一个基本的认识。
基本上作为第三方开发者最可能开发的就是三种类型的模块,即handler,filter和load-balancer。
Handler模块就是接受来自客户端的请求并产生输出的模块。
有些地方说upstream模块实际上也是一种handler模块,只不过它产生的内容来自于从后端服务器获取的,而非在本机产生的。
在上一章提到,配置文件中使用location指令可以配置content handler模块,当Nginx系统启动的时候,每个handler模块都有一次机会把自己关联到对应的location上。
如果有多个handler模块都关联了同一个location,那么实际上只有一个handler模块真正会起作用。
当然大多数情况下,模块开发人员都会避免出现这种情况。
handler模块处理的结果通常有三种情况: 处理成功,处理失败(处理的时候发生了错误)或者是拒绝去处理。
在拒绝处理的情况下,这个location的处理就会由默认的handler模块来进行处理。
例如,当请求一个静态文件的时候,如果关联到这个location上的一个handler模块拒绝处理,就会由默认的ngx_http_static_module模块进行处理,该模块是一个典型的handler模块。
本章主要讲述的是如何编写handler模块,在研究handler模块编写之前先来了解一下模块的一些基本数据结构。
模块的基本结构在这一节我们将会对通常的模块开发过程中,每个模块所包含的一些常用的部分进行说明。
这些部分有些是必须的,有些不是必须的。
同时这里所列出的这些东西对于其他类型的模块,例如filter模块等也都是相同的。
模块配置结构基本上每个模块都会提供一些配置指令,以便于用户可以通过配置来控制该模块的行为。
那么这些配置信息怎么存储呢?那就需要定义该模块的配置结构来进行存储。
Nginx开发从入门到精通-03、过滤模块
过滤模块简介(90%)执行时间和内容(90%)过滤(filter)模块是过滤响应头和内容的模块,可以对回复的头和内容进行处理。
它的处理时间在获取回复内容之后,向用户发送响应之前。
它的处理过程分为两个阶段,过滤HTTP回复的头部和主体,在这两个阶段可以分别对头部和主体进行修改。
在代码中有类似的函数:就是分别对头部和主体进行过滤的函数。
所有模块的响应内容要返回给客户端,都必须调用这两个接口。
执行顺序(90%)过滤模块的调用是有顺序的,它的顺序在编译的时候就决定了。
控制编译的脚本位于auto/modules 中,当你编译完Nginx以后,可以在objs目录下面看到一个ngx_modules.c的文件。
打开这个文件,有类似的代码:从write_filter到not_modified_filter,模块的执行顺序是反向的。
也就是说最早执行的是not_modified_filter,然后各个模块依次执行。
所有第三方的模块只能加入到copy_filter和headers_filter模块之间执行。
Nginx执行的时候是怎么按照次序依次来执行各个过滤模块呢?它采用了一种很隐晦的方法,即通过局部的全局变量。
比如,在每个filter模块,很可能看到如下代码:ngx_http_top_header_filter是一个全局变量。
当编译进一个filter模块的时候,就被赋值为当前filter 模块的处理函数。
而ngx_http_next_header_filter是一个局部全局变量,它保存了编译前上一个filter 模块的处理函数。
所以整体看来,就像用全局变量组成的一条单向链表。
每个模块想执行下一个过滤函数,只要调用一下ngx_http_next_header_filter这个局部变量。
而整个过滤模块链的入口,需要调用ngx_http_top_header_filter这个全局变量。
ngx_http_top_body_filter的行为与header fitler类似。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
手把手教你开发Nginx模块前面的哪些话关于Nginx模块开发的博客资料,网上很多,很多。
但是,每篇博客都只提要点,无法"step by step"照着做,对于初次接触Nginx开发的同学,只能像只盲目的蚂蚁瞎燥急!该篇文章没有太多技术深度,只是一步一步说明白Nginx模块的开发过程。
开发环境搭建工欲善其事,必先利其器。
个人推荐Eclipse CDT 作为IDE,原因很简单,代码提示与补全功能很全,完胜Codeblock这类...相信与否,试过就知道。
在ubuntu下搭建开发环境:安装GCC编译器apt-get install build-essential安装pcre/openssl/zlib开发库apt-get install libpcre3-devapt-get install libssl-devapt-get install libzip-dev必需安装nginx核心模块依赖的pcre,openssl,zilib开发库安装JRE/Eclipse CDTapt-get install openjdk-8-jrewget http://ftp.yz.yamagata-u.ac.jp/pub/eclipse//technology/epp/downloads/release/neon/R/eclipse-cpp-neon-R-linux-gtk-x86_64.tar.gz && tzr -xzvf eclipse-cpp-neon-R-linux-gtk-x86_64.tar.gz下载nginx源码wget /download/nginx-1.10.1.tar.gz && tar -xzvf nginx-1.10.1.tar.gz配置CDT Build Environment添加变量,值Nginx src下各模块路径,用冒号分隔,例如:/root/Workspace/nginx-1.10.1/src/core:/root/Workspace/nginx-1.10.1/src/event:/root/Workspace/nginx-1.10.1/src/http:/root/Workspace/nginx-1.10.1/src/mail:/root/Workspace/n ginx-1.10.1/src/stream:/root/Workspace/nginx-1.10.1/src/os/unix添加环境变量,创建C项目时自动作为-I选项imageimageNginx模块编译流程Nginx使用configure脚本分析环境,自动生成objs结果。
哪么configure如何编译第三方模块?答案是--add-module指定第三方模块目录,并将目录存为$ngx_addon_dir环境变量。
执行$ngx_addon_dir/config脚本,读取模块配置。
在config中的环境变量分为2种:小写的本地环境变量,大写的全局环境变量。
例如:ngx_addon_name=ngx_http_mytest_moduleHTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_moudle.c"CORE_LIBS="$CORE_LIBS -lpcre"HTTP_MODULES中的ngx_http_mytest_module就是NGX_ADDON_SRCS中源码(如果有多个,都要写上)ngx_http_mytest_module.c中定义的ngx_module_t类型的全局变量。
可见,第三方模块的入口点就是ngx_module_t类型全局变量,该变量又关联ngx_http_module_t类型static变量,与ngx_command_t类型static数组。
在ngx_http_module_t中定义上下文配置nginx.conf解析的回调方法。
在ngx_command_t中定义配置项处理的set回调方法。
Nginx的全部操作都是异步的。
在上述的方法中根据需要又会使用其他handler方法。
以上可以看成Nginx第三方模块的起式。
Upstream例子源码configngx_addon_name=ngx_http_mytest_moduleHTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c"源代码#include <ngx_config.h>#include <ngx_core.h>#include <ngx_http.h>#include <ngx_stream.h>typedef struct {ngx_http_upstream_conf_t upstream;} mytest_conf_t;typedef struct {ngx_http_status_t status;ngx_str_t backendServer;} mytest_ctx_t;static void *mytest_create_loc_conf(ngx_conf_t *cf);static char *mytest_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);static ngx_int_t mytest_upstream_create_request(ngx_http_request_t *r);static ngx_int_t mytest_upstream_process_status_line(ngx_http_request_t *r);static ngx_int_t mytest_upstream_process_header(ngx_http_request_t *r);static void mytest_upstream_finalize_request(ngx_http_request_t *r,ngx_int_t rc);static ngx_int_t mytest_handler(ngx_http_request_t *r);static char *mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);static ngx_http_module_t mytest_ctx = {NULL,NULL,NULL,NULL,NULL,NULL,mytest_create_loc_conf,mytest_merge_loc_conf};static ngx_command_t mytest_commands[] = {{ngx_string("mytest"),NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, mytest,NGX_HTTP_LOC_CONF_OFFSET,0,NULL},ngx_null_command};ngx_module_t ngx_http_mytest_module = {NGX_MODULE_V1,&mytest_ctx,mytest_commands,NGX_HTTP_MODULE,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NGX_MODULE_V1_PADDING};static ngx_str_t mytest_upstream_hide_headers[] ={ngx_string("Date"),ngx_string("Server"),ngx_string("X-Pad"),ngx_string("X-Accel-Expires"),ngx_string("X-Accel-Redirect"),ngx_string("X-Accel-Limit-Rate"),ngx_string("X-Accel-Buffering"),ngx_string("X-Accel-Charset"),ngx_null_string};static void *mytest_create_loc_conf(ngx_conf_t *cf){mytest_conf_t *mycf;mycf = (mytest_conf_t *)ngx_pcalloc(cf->pool, sizeof(mytest_conf_t));if(mycf == NULL){return NULL;}mycf->upstream.connect_timeout = 60000;mycf->upstream.send_timeout = 60000;mycf->upstream.read_timeout = 60000;mycf->upstream.store_access = 0600;mycf->upstream.buffering = 0;mycf->upstream.bufs.num = 8;mycf->upstream.bufs.size = ngx_pagesize;mycf->upstream.buffer_size = ngx_pagesize;mycf->upstream.busy_buffers_size = 2 * ngx_pagesize;mycf->upstream.temp_file_write_size = 2 * ngx_pagesize;mycf->upstream.max_temp_file_size = 1024 * 1024 *1024;mycf->upstream.hide_headers = NGX_CONF_UNSET_PTR;mycf->upstream.pass_headers = NGX_CONF_UNSET_PTR;return mycf;}static char *mytest_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child){mytest_conf_t *prev = (mytest_conf_t *)parent;mytest_conf_t *conf = (mytest_conf_t *)child;ngx_hash_init_t hash;hash.max_size = 100;hash.bucket_size = 1024; = "proxy_headers_hash";if(ngx_http_upstream_hide_headers_hash(cf,&conf->upstream, &prev->upstream,mytest_upstream_hide_headers,&hash)!=NGX_OK){ return NGX_CONF_ERROR;}return NGX_CONF_OK;}static ngx_int_t mytest_upstream_create_request(ngx_http_request_t *r){static ngx_str_t backendQueryLine = ngx_string("GET /search?q=%V HTTP/1.1\r\nHost: \r\nConnection: close\r\n\r\n");ngx_int_t queryLineLen = backendQueryLine.len + r->args.len - 2;ngx_buf_t *b = ngx_create_temp_buf(r->pool, queryLineLen);if(b == NULL) return NGX_ERROR;b->last = b->pos + queryLineLen;ngx_snprintf(b->pos, queryLineLen, (char *)backendQueryLine.data, &r->args);r->upstream->request_bufs = ngx_alloc_chain_link(r->pool);if(r->upstream->request_bufs == NULL) return NGX_ERROR;r->upstream->request_bufs->buf = b;r->upstream->request_bufs->next = NULL;r->upstream->request_sent = 0;r->upstream->header_sent = 0;r->header_hash = 1;return NGX_OK;}static ngx_int_t mytest_upstream_process_status_line(ngx_http_request_t *r){size_t len;ngx_int_t rc;ngx_http_upstream_t *u;mytest_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module);if(ctx == NULL) return NGX_ERROR;u = r->upstream;rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status);if(rc == NGX_AGAIN) return rc;if(rc == NGX_ERROR){ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent to valid HTTP/1.0 header");r->http_version = NGX_HTTP_VERSION_9;u->state->status = NGX_HTTP_OK;return NGX_OK;}if(u->state){u->state->status = ctx->status.code;}u->headers_in.status_n = ctx->status.code;len = ctx->status.end - ctx->status.start;u->headers_in.status_line.len = len;u->headers_in.status_line.data = ngx_pcalloc(r->pool, len);if(u->headers_in.status_line.data == NULL) return NGX_ERROR;ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len);u->process_header = mytest_upstream_process_header;return mytest_upstream_process_header(r);}static ngx_int_t mytest_upstream_process_header(ngx_http_request_t *r){ngx_int_t rc;ngx_table_elt_t *h;ngx_http_upstream_header_t *hh;ngx_http_upstream_main_conf_t *umcf;umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);for(;;){rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1);if(rc == NGX_OK){h = ngx_list_push(&r->upstream->headers_in.headers);if(h == NULL) return NGX_ERROR;h->hash = r->header_hash;h->key.len = r->header_name_end - r->header_name_start;h->value.len = r->header_end - r->header_start;h->key.data = ngx_pcalloc(r->pool, h->key.len + 1 + h->value.len + 1 + h->key.len);if(h->key.data == NULL) return NGX_ERROR;h->value.data = h->key.data + h->key.len + 1;h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;ngx_memcpy(h->key.data, r->header_name_start, h->key.len);h->key.data[h->key.len]='\0';ngx_memcpy(h->value.data, r->header_start, h->value.len);h->value.data[h->value.len] = '\0';if(h->key.len == r->lowcase_index){ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);}else{ngx_strlow(h->lowcase_key, h->key.data, h->key.len);}hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, h->lowcase_key, h->key.len);if(hh && hh->handler(r, h, hh->offset)!=NGX_OK) return NGX_ERROR;continue;}if(rc == NGX_HTTP_PARSE_HEADER_DONE){if(r->upstream->headers_in.server == NULL){h = ngx_list_push(&r->upstream->headers_in.headers);if(h == NULL) return NGX_ERROR;h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r');ngx_str_set(&h->key, "Server");ngx_str_null(&h->value);h->lowcase_key = (u_char *)"server";}if(r->upstream->headers_in.date == NULL){h = ngx_list_push(&r->upstream->headers_in.headers);if(h == NULL) return NGX_ERROR;h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e');ngx_str_set(&h->key, "Date");ngx_str_null(&h->value);h->lowcase_key = (u_char *)"date";}return NGX_OK;}if(rc == NGX_AGAIN) return NGX_AGAIN;ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "upstream sent invalid header");return NGX_HTTP_UPSTREAM_FT_INVALID_HEADER;}}static void mytest_upstream_finalize_request(ngx_http_request_t *r, ngx_int_t rc){ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "mytest_upstream_finalize_request");}static char *mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){ngx_http_core_loc_conf_t *clcf;clcf = ngx_http_conf_get_module_loc_conf(cf,ngx_http_core_module);clcf->handler = mytest_handler;return NGX_CONF_OK;}static ngx_int_t mytest_handler(ngx_http_request_t *r){mytest_ctx_t *myctx = ngx_http_get_module_ctx(r, ngx_http_mytest_module);if(myctx == NULL){myctx = ngx_pcalloc(r->pool, sizeof(mytest_ctx_t));if(myctx == NULL) return NGX_ERROR;ngx_http_set_ctx(r, myctx, ngx_http_mytest_module);}if(ngx_http_upstream_create(r)!=NGX_OK){ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_http_upstream_create() failed");return NGX_ERROR;}mytest_conf_t *mycf = (mytest_conf_t *)ngx_http_get_module_loc_conf(r, ngx_http_mytest_module);ngx_http_upstream_t *u = r->upstream;u->conf = &mycf->upstream;u->buffering = mycf->upstream.buffering;u->resolved = (ngx_http_upstream_resolved_t *) ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));if(u->resolved == NULL){ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_pcalloc resolved error. %s", strerror(errno));return NGX_ERROR;}static struct sockaddr_in backendSockAddr;struct hostent *pHost = gethostbyname((char *)"");if(pHost == NULL){ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "gethostbyname fail. %s", strerror(errno));return NGX_ERROR;}backendSockAddr.sin_family = AF_INET;backendSockAddr.sin_port = htons((in_port_t)80);char *pDmsIP = inet_ntoa(*(struct in_addr *)(pHost->h_addr_list[0]));backendSockAddr.sin_addr.s_addr = inet_addr(pDmsIP);myctx->backendServer.data = (u_char *)pDmsIP;myctx->backendServer.len = strlen(pDmsIP);u->resolved->sockaddr = (struct sockaddr *)&backendSockAddr;u->resolved->port = htons((in_port_t)80);u->resolved->socklen = sizeof(struct sockaddr_in);u->resolved->naddrs = 1;u->create_request = mytest_upstream_create_request;u->process_header = mytest_upstream_process_status_line;u->finalize_request = mytest_upstream_finalize_request;r->main->count++;ngx_http_upstream_init(r);return NGX_DONE;}注意:《Nginx深入解析》的demo少了这句:“u->resolved->port = htons((in_port_t)80);”,否则报错“2016/09/09 11:24:18 [error] 28352#0: *1 no port in upstream "", client: 127.0.0.1, server: localhost, request: "GET /mytest?q=test HTTP/1.1", host: "localhost"”编译脚本./configure --prefix=/usr/local/nginx --add-module=/root/Workspace/nginx-modules/ngx_http_mytest_module --with-debugsudo makesudo make install安装后即可到/usr/local/nginx下配置nginx.conf进行测试。