关于nginx架构探究(3)
Nginx 模块综述
Nginx 所有的代码都是以模块的新式组织的,包括核心模块和功能模块。Nginx加载模块的时候不想Apache一样动态加载,它是直接被编译到二进制执行文件中,所以,如果想要加载新的模块,需要我们重新编译Nginx源码。比如:
./configure --with-http_flv_module
执行上述编译选项后,就可以生成http_flv功能模块了。根据模块的功能性质,Nginx的模块大致可以分为以下四类:
. handlers:协同完成客户端请求的处理、产生响应数据,比如ngx_http_rewrite_module模块,用于处理客户端请求的地址重写,ngx_http_static_module模块负责处理客户端的静态页面请求,ngx_http_log_module模块,负责记录请求访问日志。
. filters:对handlers产生的响应数据作各种过滤处理,比如模块ngx_http_not_modified_filter_module,对响应数据进行过滤检测,如果通过时间戳判断出前后响应没有变化,就响应304,让客户端使用本地缓存。
. upstream:如果存在后端真实服务器,Nginx可以利用upstream模块充当反向代理(例如和uwsgi 一起搭建flask框架web程序),对客户端发起的请求值负责转发。
. load-balance:在Nginx充当中间代理角色时,由于后端真实服务器往往多余一个,对于某一次客户端的请求,如何选择对应的后端真实服务器来进行处理,实现负载均衡算法。
- Handler 模块
对于客户端http请求的处理,Nginx为了获得更强的控制能力,Nginx将整个过程细分为多个阶段,每个阶段可以有多个回调函数来处理,这样以来,当我们在处理Handlers模块是,必须把模块功能处理函数挂在正确的阶段点上。例如:http请求的整个过程一共被分为11个阶段,每个阶段对应的处理功能都比较单一,这样能尽量让Nginx模块代码更为内聚。如下图所示为http请求对应的11个阶段:
序号0表示的阶段是指当Nginx成功接收到一个客户端请求后(accept返回FD之后),针对该请求所做的第一个实际工作就是读取客户端发过来的请求头内容。并调用相应的回调函数进行解析。
序号1表示的阶段和3阶段都属于地址重写阶段,前者用于server上下文的重写、后者location上下文的重写,先做server的定位,然后调用3阶段的回调函数作location的定位。
序号2表示的阶段不执行任何回调函数,因为它的任务主要是查找Location的位置,位置找到后,进入3阶段读取配置值,重写地址。
序号4主要是作安全检查的,即查看是否做了过多的内部跳转(比如地址重写、redirect等),我们不能让对一个请求的处理在Nginx内部跳转多次,这样非常消耗性能。Nginx规定跳转次数最大值为10。
序号5、6、7主要是做访问权限检查工作,如果当前请求没有访问权限,那么直接返回状态403,序号10是日志模块处理的阶段。
阶段-回调函数对应表如下所示:

- Filter 模块
对于http请求处理handlers产生的响应内容,在输出到客户端之前需要作过滤处理,这些过滤处理对于完成功能的增强实现与性能的提升是非常有必要的。由于响应数据包括响应头和响应体,所以与此相对应,Filter模块必须提供处理header、body的响应函数, 所有的header过滤模块和body过滤模块各自形成自己的过滤链。如果头过滤失败,响应体过滤可以不必进行。
- Upstream模块
Upstream模块与具体的协议无关,其除了支持HTTP外,还支持包括FASTCGI、UWSGI等在内的多种协议。在Nginx配置文件中location设置了upstream,即表示对该location的请求需要后端真实服务器来处理。upstream模块的优先级最高,所以一旦进入upstream模块之后,再调用其他模块,获取配置参数如server、location,不过这一动作由upstream中的回调函数完成。对于任何一个Upstream模块而言,最核心的实现是7个回调函数。交互过程如下所示:

其中create_request的功能是根据Nginx与后端服务器通信协议,将客户端的HTTP请求信息转化为对应的发送到后端的真实请求,这也就是为什么后端获取变量的方式都是:request.Form,request.json等。process_headers的功能是根据Nginx与后端服务器通信协议,将后端服务其返回的头信息转换为HTTP响应头。input_filter_init以及input_filter则是处理后端服务其返回的响应体。
- Load-balance模块
Load-balance模块是一个辅助模块,与前面介绍的模块不一样,它主要为Upstream模块服务,目标单一,即如何从后台服务器中选择一台合适的服务其来处理当前请求。要实现Load-balance模块,需要实现如下的4个回调函数:
ngx_http_upstream_init_round_robin:解析配置文件过程中被调用,根据upstream里的各个配置变量作初始准备工作,配置文件解析完接不在被调用
ngx_http_upstream_init_round_robin_peer():在每次Nginx准备转发客户端请求到后端服务器前都会调用该函数,该函数为选择合适的后端服务器作初始准备工作。
ngx_http_upstream_get_round_robin_peer():该函数实现具体的调度逻辑,加权选择当前权值最高的后端服务器
ngx_http_upstream_free_round_robin_peer():跟新相关数值,如权重,负载。
Nginx默认采用round-robin加权算法,如果选择其他算法,比如IP_hash算法,需要在upstream中配置说明。加权轮询调度算法思路如下:
假设有一组服务器S = {S0, S1, …, Sn-},W(Si)表示服务器Si的权值,一个
指示变量i表示上一次选择的服务器,指示变量cw表示当前调度的权值,max(S)
表示集合S中所有服务器的最大权值,gcd(S)表示集合S中所有服务器权值的最大
公约数。变量i初始化为-,cw初始化为零。
while (true) {
i = (i + ) mod n;
if (i == ) {
cw = cw - gcd(S);
if (cw <= ) {
cw = max(S);
if (cw == )
return NULL;
}
}
if (W(Si) >= cw)
return Si;
}
IP_hash算法流程如下:
int hash = ;
for(int i = ; i < ; i++) {
hash = (hash * + rand_num[i]) % ; //hash运算
}
hash = hash % peer_number;//peer_number是后端server数目
result[hash]++; //统计hash值命中
关于nginx架构探究(3)的更多相关文章
- 关于nginx架构探究(1)
nginx的架构主要是有一个主监控进程:master;三个工作进程:worker:还有Cache的两个进程.back-end-server是后端服务器,主要是处理后台逻辑.nginx作为代理服务器需要 ...
- 关于nginx架构探究(4)
事件管理机制 Nginx是以事件驱动的,也就是说Nginx内部流程的向前推进基本都是靠各种事件的触发来驱动,否则Nginx将一直阻塞在函数epoll_wait()或suspend函数,Nginx事件一 ...
- 关于nginx架构探究(2)
nginx 数据结构 1.Hash table nginx 对虚拟主机的管理使用到了HASH数据结构,假设配置文件里有如下的配置. Server{ listen 192.168.0.1 server_ ...
- Nginx学习笔记(一) Nginx架构
Nginx架构 Nginx全程是什么? Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. ...
- Nginx架构的企业级应用
Nginx架构的企业级应用 ==================================================== 实现HA高可用集群 实现LB负载均衡集群 Nginx实现反向代理 ...
- [转载] 深入 nginx 架构
原文: http://www.cnbeta.com/articles/402709.htm 了解 nginx 架构帮助我们学习如何开发高性能 web 服务. 为了更好地理解设计,你需要了解NGINX是 ...
- nginx架构与基础概念
1 Nginx架构 Nginx 高性能,与其架构有关. Nginx架构: nginx运行时,在unix系统中以daemon形式在后台运行,后台进程包含一个master进程和多个worker ...
- Nginx从入门到放弃-第5章 Nginx架构篇
5-1 Nginx常见问题_架构篇介绍 5-2 Nginx常见问题_多个server中虚拟主机读取的优先级 5-3 Nginx常见问题_多个location匹配的优先级1 5-4 Nginx常见问题_ ...
- 转:初探nginx架构(一)
来源:http://tengine.taobao.org/book/chapter_02.html 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么nginx究竟是怎么样的呢? ...
随机推荐
- 【转】Contrary to the answers here, you DON'T need to worry about encoding!
For those goals, I honestly do not understand why people keep telling you that you need the encoding ...
- Hbase 设计与开发实战
Hbase 概述 大数据及 NoSQL 的前世今生 传统的关系型数据库处理方式是基于全面的 ACID 保证,遵循 SQL92 的标准表设计模式(范式)和数据类型,基于 SQL 语言的 DML 数据交互 ...
- L - Vases and Flowers - hdu 4614(区间操作)
题意:有两种操作,第一种从A开始插花,如果有花就跳到下一个,然后输出最后一个花瓶的编号,如果花瓶不够把多余的花丢掉.操作2把区间清空 分析:很明显的线段树操作,就是插花的时候麻烦一下,需要先找出来他剩 ...
- 微信/易信公共平台开发(二):自定义菜单的PHP实现(提供源码)
微信把公众号分成订阅号和服务号两种,服务号可以自定义菜单, 菜单大大方便了用户操作. 比如:公众服务号 "中国南方航空" 的自定义菜单如下图: 点菜单就可以直接进入操作了,方便! ...
- cmake编译错误:“No CMAKE_C_COMPILER could be found”的原因
发生此错误,原因在于,进行configure命令时,没有选择正确的编译器,比如电脑上安装的是VS2012,想编译位64位,选择了VS2012 X64,这样就会报错了,选择VS2012就对了,一样可以编 ...
- Spring 3 来创建 RESTful Web Services
Spring 3 创建 RESTful Web Services 在 Java™ 中,您可以使用以下几种方法来创建 RESTful Web Service:使用 JSR 311(311)及其参考实现 ...
- sql为了实现转换的行列
全名 学科 成绩 牛芬 语文 81 牛芬 数学 88 牛芬 英语 84 张三 语文 90 张三 数学 98 张三 英语 90 (表一) 现有一个表如(表一) 姓名 语文 数学 英语 牛芬 81 88 ...
- HDU 1199 - Color the Ball 离散化
[题意]现在有几个球排成一排,编号从1开始,开始时所有球为黑色,现在有n(<=2000)次操作,每次操作将l[i]至r[i](均在int范围)的球凃成颜色c[i](黑色'b'或白色'w'),然后 ...
- 富文本 Htmll类 html标签
HTML类可解析的标签 在手机上显示从网络端获取的数据有两种方式,一种是WebView,另一种是TextView,WebView大家都知道,功能强大但不灵活,下面主要说下TextView. 通过查看a ...
- JAVA彩色图片变灰处理
File file = new File("F:/firefox.png"); File destFile = new File("F:/pic/" + Sys ...