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)的更多相关文章

  1. 关于nginx架构探究(1)

    nginx的架构主要是有一个主监控进程:master;三个工作进程:worker:还有Cache的两个进程.back-end-server是后端服务器,主要是处理后台逻辑.nginx作为代理服务器需要 ...

  2. 关于nginx架构探究(4)

    事件管理机制 Nginx是以事件驱动的,也就是说Nginx内部流程的向前推进基本都是靠各种事件的触发来驱动,否则Nginx将一直阻塞在函数epoll_wait()或suspend函数,Nginx事件一 ...

  3. 关于nginx架构探究(2)

    nginx 数据结构 1.Hash table nginx 对虚拟主机的管理使用到了HASH数据结构,假设配置文件里有如下的配置. Server{ listen 192.168.0.1 server_ ...

  4. Nginx学习笔记(一) Nginx架构

    Nginx架构 Nginx全程是什么? Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. ...

  5. Nginx架构的企业级应用

    Nginx架构的企业级应用 ==================================================== 实现HA高可用集群 实现LB负载均衡集群 Nginx实现反向代理 ...

  6. [转载] 深入 nginx 架构

    原文: http://www.cnbeta.com/articles/402709.htm 了解 nginx 架构帮助我们学习如何开发高性能 web 服务. 为了更好地理解设计,你需要了解NGINX是 ...

  7. nginx架构与基础概念

    1       Nginx架构 Nginx 高性能,与其架构有关. Nginx架构: nginx运行时,在unix系统中以daemon形式在后台运行,后台进程包含一个master进程和多个worker ...

  8. Nginx从入门到放弃-第5章 Nginx架构篇

    5-1 Nginx常见问题_架构篇介绍 5-2 Nginx常见问题_多个server中虚拟主机读取的优先级 5-3 Nginx常见问题_多个location匹配的优先级1 5-4 Nginx常见问题_ ...

  9. 转:初探nginx架构(一)

    来源:http://tengine.taobao.org/book/chapter_02.html 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么nginx究竟是怎么样的呢? ...

随机推荐

  1. ASPNET登陆总结

    昨天晚上看了视频,今天早上起来就凭着记忆与视频里的代码试着做了一个登陆,基本功能是实现了. 0x0:首先,第一步是做一个界面....直接扒别人做好的页面.....各种改改路径啥的,用浏览器打开,恩,发 ...

  2. STL_iterator迭代器(3)——函数和函数对象

    STL中,函数被称为算法,也就是说它们和标准C库函数相比,它们更为通用.STL算法通过重载operator()函数实现为模板类或模板函数.这些类用于创建函数对象,对容器中的数据进行各种各样的操作.下面 ...

  3. 如何给DropDownList控件设置样式(ASP.NET MVC)

    前话: 应学校领导要求,要给后台管理系统添加一个搜索功能,提供可选择选项.我选择使用DropDownList去实现,熟悉.net控件的都知道,DropDownList的样子非常丑,不论是边框长宽还是里 ...

  4. ulimit开启coredump时核心转储

    [root@localhost ~]# ulimit -c [root@localhost ~]# ulimit -a core data seg size (kbytes, -d) unlimite ...

  5. 枚举的基本使用方法 Enumerations

    枚举的基本使用方法 Enumerations Enumeration  enum SomeEnumeration{ case enumeration1 case enumeration2 case   ...

  6. [Javascript] What is JavaScript Function Currying?

    Currying is a core concept of functional programming and a useful tool for any developer's toolbelt. ...

  7. 双向链表JAVA代码

      //双向链表类 publicclassDoubleLinkList{       //结点类     publicclassNode{           publicObject data;   ...

  8. (转徐明吉)C#生成随机数

    private static char[] constant = { ', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p ...

  9. Config配置文件读写

    config文件读写操作(文字说明附加在程序中) App.config文件 <?xml version="1.0" encoding="utf-8" ?& ...

  10. hdu 2200

    bc上的题目,很水,有很多方法做吧,题意大概就是给定你票数,然后让你求出票数最多的那个下标...... 之前我用两个for循环分开写,一个是读入,然后是判断,提交就wa,后来网上看了别人的,就是不能分 ...