nginx源码分析
文章平均质量分 95
参考深入理解nginx,对nginx源码进行详细分析
ApeLife
这个作者很懒,什么都没留下…
展开
-
nginx负载均衡的关闭
在前面的文章中,已经分析了nginx如何结束一个http请求,可以调用http框架的ngx_http_finalize_request或者调用http框架提供的接口ngx_http_terminate_request暴力的终止一个请求。 但接收一个upstream负载均衡请求却不能调用这两个接口,因此调用这两个接口的话,nginx与下游客户端的请求与tcp连接是释放了,但nginx与上游服务器的连原创 2017-10-02 17:12:06 · 2394 阅读 · 2 评论 -
nginx负载均衡之加权轮询
当nginx作为代理服务器时,需要将客户端的请求转发给后端服务器进行处理,如果后端服务器有多台,那如何选择合适的后端服务器来处理当前请求,也就是本篇文章要介绍的内容。nginx尽可能的把请求分摊到各个后端服务器进行处理,以保证服务的可用性和可靠行,提供给客户端更好的用户体验。负载均衡的直接目的只有一个,尽量发挥多个后端服务器的整体性能,实现1+1大于2的效果。 nginx原创 2017-10-02 15:06:15 · 1686 阅读 · 0 评论 -
nginx处理post请求(http响应包体收发之上游网速优先策略)
上一篇文章分析了在下游网速优先策略下,nginx是如何接收来自后端服务器的响应包体,以及如何把来自后端服务器的响应包体转发给客户端的。本篇文章接着分析另一种http响应包体收发策略----上游网速优先策略。 上游网速优先,即nginx接收后端服务器的响应包体要比下游客户端接收来自nginx的响应包体更快。在这种情况下,nginx需要开辟多个缓冲区,尽可能多的缓存来自后端服务器的响原创 2017-10-02 07:11:17 · 3034 阅读 · 0 评论 -
nginx处理post请求(http响应包体收发之下游网速优先策略)
nginx接收来自后端服务器响应包括两个阶段,一个是接收来自后端服务器的http响应头部, 在上一篇文章已经详细分析了这个过程;另一个是接收来自后端服务器的http响应包体。 不论接收来自后端服务器的http响应头部还是http响应包体, 这都是一个接收过程。 以此同时nginx作为代理服务器,在接收到来自后端服务器的响应后,是需要把响应数据发给下游客户端的, 这是一个发送过程原创 2017-09-22 07:31:29 · 1839 阅读 · 0 评论 -
nginx处理post请求(http响应头部的收发)
上一篇文章分析了nginx如何发送来自客户端的请求数据到后端服务器, 本篇文章开始将分析nginx如何接收来自后端服务器的响应。nginx接收来自后端服务器的响应分为两个过程,一个是接收来自后端服务器的http响应头部, 另一个是接收来自后端服务器的响应包体。 有必要在最前面说明,也是很重要的几点。(1)nginx在收到来自客户端的全部请求数据后,采用边发送请求数据到后端服务器,原创 2017-09-16 12:37:30 · 25807 阅读 · 1 评论 -
nginx处理post请求之数据转发
上一篇文章分析了nginx在处理post请求时,如何启动upstream这个负载均衡模块。它是一个http框架,由它来调度具体的模块,例如fastcgi, proxyd反向代理等,这些模块负责将来自客户端 的请求包体,请求包体转为与后端服务器通信的格式。本篇文章来分析nginx是如何将已经转换后的报文发给后端服务器。一、转发请求数据到后端服务器流程//与后端服务器建立连接,并注册读写事件的原创 2017-09-15 06:42:50 · 13645 阅读 · 1 评论 -
nginx处理post请求(负载均衡启动)
NGX_HTTP_CONTENT_PHASE阶段的checker方法为:ngx_http_core_content_phase//NGX_HTTP_CONTENT_PHASE阶段的checker方法ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph){ //fa原创 2017-08-05 06:45:20 · 6202 阅读 · 0 评论 -
nginx子请求并发处理
子请求并发http协议标准的概念,可以说是nginx所特有的设计, 为什么需要子请求呢? 一般认为这主要是为了提高nginx内部对单个客户端请求处理的并发能力。如果客户端的某个主请求访问了多长资源(例如通过ssi功能包含了a.html, b.hmtl、c.html三个资源), 那么对每一处资源访问建立一个子请求并让它们同时进行,效率自然会更高。 所谓的子请求,并不是由客户端直接发起的,它是由ng...原创 2017-07-13 07:11:15 · 6443 阅读 · 3 评论 -
nginx延迟关闭机制SO_LINGER
经过前面文章的分析可以知道,nginx在释放一个请求时,到底要不要释放在这个请求基础上的TCP连接,是由keepalive机制与延迟关闭机制决定的。虽然http请求是被释放了, 但可能在这个TCP连接上稍后还有其他http请求到来,因此请求是被释放了,但TCP连接可能没有马上被释放。keepalive机制在上一篇文章已经分析了,现在来分析下延迟关闭的处理过程。一、延迟关闭背景介绍...原创 2017-07-12 06:31:06 · 6294 阅读 · 1 评论 -
nginx长连接keepalive与pipeline
tcp与http都支持keepalive机制,但两者是不同的。先看下tcp的keepalive机制。当客户端与服务器建立了tcp连接后,如果客户端一直不发送数据,或者隔很长时间才发送一次数据,当链接很久没有数据报文传输时,服务器如何去确定对方还在线。到底是掉线了还是确实没有数据传输,连接还需不需要保持,这种情况在TCP协议设计中是需要考虑到的。TCP协议通过一种巧妙的方式去解决这个问题,当超过一.........原创 2017-07-11 06:11:28 · 4462 阅读 · 2 评论 -
nginx释放请求与tcp连接
前面的文章分析了nginx服务器如何接收http请求行、请求头部、然后调用各个模块共同协作处理请求、以及接收包体等过程。现在来分析下nginx服务器是如何结束一个http请求的(关闭http请求与tcp连接)。结束一个http请求的过程就复杂多了,在结束一个请求过程中,nginx考虑了各种可能出现的场景。例如: (1)在客户端访问的文件不存在时,如果指定了error page指令,则在请求结束时发...原创 2017-07-08 06:10:12 · 10062 阅读 · 3 评论 -
nginx丢弃http包体处理
http框架丢弃http请求包体和上一篇文章http框架接收包体, 都是由http框架提供的两个方法,供http各个模块调用,从而决定对包体做什么处理。是选择丢弃还是接收,都是由模块决定的。例如静态资源模块,如果接收到来自浏览器的get请求,请求某个文件时,则直接返回这个文件内容给浏览器就可以了。没有必要再接收包体数据,get请求实际上也不会有包体。因此静态资源模块将调用http框架提供的丢弃包体原创 2017-06-30 08:10:05 · 3878 阅读 · 1 评论 -
nginx接收包体处理
在http中,一个请求通常由必选的请求行、请求头部、以及可选的包体组成。因此在接收完http头部后,就使用状态机调度各个http模块处理请求了,然后由各个http模块决定如何处理包体。 http框架提供了2种处理包体的方法供http模块调用(接收包体与丢弃包体), 这两种处理包体的方法对http各个模块来说是透明的,也就是说http模块不需要关心框架是如何处理包体的。 http模块只需要调用ht原创 2017-06-29 23:46:00 · 5314 阅读 · 0 评论 -
nginx断点续传
有些时候客户端可能只需要请求nginx服务器上的部分数据, 例如: 我们在看电影时, 常常拖动快进条,跳到指定的位置开始观看。 这其实是nginx的断点续传功能, 从指定位置开始观看,相当于向nginx服务器请求某个位置开始的以后的内容。假设nginx服务器上有一个文件,文件的内容为: "0123456789abcdef"一共16个字节。如果客户端只需要2345共4个字节的数据, 则可以在http原创 2017-06-23 00:32:18 · 11952 阅读 · 0 评论 -
nginx过滤器模块
nginx服务器给客户端发送响应时,包括http响应头部、http响应包体内容。可以调用http框架提供的两个函数ngx_http_send_header,ngx_http_output_filter,分别用于给客户端发送http响应头部、http响应包体。这两个函数会调用各个过滤器模块,对将要发送给客户端的响应头部、响应包体进行过滤处理。例如: 是否需要添加http响应头部字段、是否需要断点续传原创 2017-01-15 22:42:11 · 3711 阅读 · 0 评论 -
nginx静态模块分析
在上一篇文章中,已经分析了http框架是如何调度各个http模块,共同协作完成一个请求的。现在分析静态模块,看下这个具体的http模块做了些什么。ngx_http_static_module静态模块会从客户端发来的http请求行中获取到文件名(例如: /GET /home/abc.txt HTTP/1.1),在服务器中查找相应的文件名,并给客户端返回文件内容。在ngx_http_block函数中原创 2017-01-15 17:12:48 · 2385 阅读 · 0 评论 -
nginx处理http请求
上一篇文章分析了ngixn服务器如何接收客户端发来的http请求行、http请求头部。本文在这基础上分析nginx服务器收到http请求行、请求头部后,http框架是如何调度各个http模块共同完成这个http请求。例如: http框架调度静态模块,获取服务器目录下的某个html页面返回给客户端; 或者http框架调度access权限访问模块,判断这个客户端是否有权限访问服务器。一、event原创 2017-01-15 14:56:53 · 5718 阅读 · 3 评论 -
ngxin请求行与请求头处理
上一篇文件分析了nginx服务器接收到客户端的连接后,会创建一个连接对象,但此时没有涉及到任何的http模块。本文在上一章基础下分析nginx接收到http请求后的初始化流程、接收http请求行、接收http请求头部的流程。原创 2017-01-15 01:15:47 · 2487 阅读 · 0 评论 -
nginx事件模块之客户端连接与超时管理
上一篇文章分析了nginx是如何管理监听事件,并把监听事件注册到epoll事件管理器中。接下来在这基础上分析当有客户端连接请求到来时,nginx是如何与客户端建立tcp连接,以及连接建立后又是如何管理超时事件。一、连接事件管理 在函数ngx_event_process_init中,会设置读事件的回调为ngx_event_accept。 这样设置后,在nginx...原创 2016-12-27 07:26:34 · 3276 阅读 · 0 评论 -
nginx监听事件流程
在前面的几篇文章中已经分析了master进程、work进程的初始化流程。但一直没有分析监听socket的创建流程,nginx服务器只有在创建socket, 绑定socet,监听socket执行完成后,才能处理来自客户端的连接。ngx_cycle_t结构中有一个listening成员,存放的就是所有监听socket。接下来分析下首先分析socket内部结构,然后分析什么时候把监听socket添加到l原创 2016-12-15 07:51:20 · 5028 阅读 · 0 评论 -
nginx配置解析之配置合并
上一篇文件分析了解析nginx.conf的流程,解析完成后将把各个配置项存放到各个模块的上下文结构中。这没有对http模块、server模块、location模块公共部分进行合并处理。接下来分析nginx是如何合并http模块、server模块、location模块公共部分。假设nginx.conf配置文件结构如下http{ //server块1 server { //loc原创 2016-12-11 23:31:34 · 5529 阅读 · 0 评论 -
nginx配置解析流程
上一篇文章分析了nginx配置文件缓冲区的管理,接下来将详细分析nginx是如何解析配置文件的。包含模块上下文结构的创建、core核心模块的解析、event事件模块的解析、http模块的解析。一、模块上下文结构创建 nginx中的核心模块、事件模块、http模块、赋值均衡模块,反向代理模块等,每一个模块都有一个上下文结构。在解析nginx.conf配置文件时,会将解析出的命令原创 2016-12-11 14:43:58 · 2586 阅读 · 3 评论 -
nginx配置解析之缓冲区管理
nginx服务器的master进程在解析nginx.conf时,会使用一个4k大小的缓存区存放部分配置文件信息。nginx会从配置文件中读取4k大小的内容到缓冲区,之后对缓冲区中的内容进行逐个字符扫描,从而解析出配置项、配置值。例如server_name 127.0.0.1; 则逐个字符扫描得到配置项server_name, 配置值127.0.0.1。当然nginx不会每次都去读取文件,而是读取原创 2016-12-10 21:46:06 · 3936 阅读 · 0 评论 -
nginx启动流程之work初始化
一、work进程的创建在master进程的ngx_start_worker_processes函数中,会调用ngx_spawn_process函数开始创建work进程。创建完成后master进程、work进程同时工作,分别执行不同的业务逻辑。ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, voi原创 2016-12-09 23:52:29 · 3069 阅读 · 0 评论 -
nginx启动流程之master进程初始化
1、获取系统错误码已经对应的描述信息ngx_strerror_init函数会开辟135个空间,存放系统的错误码以及对应的字符串形式的描述信息。在nginx进程运行过程中,如果出错就可以调用gx_log_errno函数获取出错的错误码以及对应的字符串内容,方便排错。2、解析nginx启动过程中的命令下参数。例如以下面几种方式 ./nginx -s reload;原创 2016-12-08 01:14:45 · 2996 阅读 · 0 评论 -
nginx哈希表数组的构造
前面二章已经分析了nginx普通哈希表,通配符哈希表的初始化流程以及查找流程。在分析前两章时,要创建一个哈希表,都假设要插入到哈希表中的数据已经准备好了。本节将分析nginx如何对要插入到哈希表中的数据进行转换。例如: 前置通配符转换为cn.com.baidu; 后置通配符转换为www.baidu.com。下面是一张使用哈希表的整体流程。可以参考ngx_http_server_names函数的实原创 2016-11-10 08:15:33 · 983 阅读 · 0 评论 -
nginx普通哈希表
nginx的各个模块都在使用哈希表结构。例如:在解析nginx.conf时,为了解析www.baidu.com.*后置通配符, *.baidu.com后置通配符, 以及www.baidu.com正常server关键字时,会使用哈希表进行存储。nginx实现了3个哈希表,分别为普通哈希表、前置通配符哈希表、后置通过符哈希表。 这三个哈希表都只实现了初始化接口,查询接口,而没有实现插入接口。也就是说n原创 2016-11-08 07:56:27 · 1743 阅读 · 0 评论 -
nginx通配符哈希表
nginx服务器的配置文件支持前置通配符或者后置通配符(例如: *.baidu.com, www.sina.*), 不支持通配符在中间位置。在解析nginx.conf时,如果server_name配置项存在通配符时,会把通配符存放到通配符哈希表中。一、初始化哈希表 对于后置通配符www.baidu.com.*, 则nginx以.为界限分割每一个单词,得到"www", "ba原创 2016-11-09 22:05:53 · 2990 阅读 · 0 评论 -
nginx链表
nginx服务器接收到客户端的http请求头部时,或者nginx发送响应头部给客户端,这些头部字段都会保存到链表数组中。例如:content_type:text/html。内存布局如下图所示。图:http头部链表一、链表结构//链表头结点typedef struct { ngx_list_part_t *last; //指向链表最后一个节点 ngx_原创 2016-11-06 08:19:29 · 840 阅读 · 0 评论 -
nginx文件结构
nginx服务器接收到客户端的http请求包体后,会将包体存放到内存中。然而内存空间是有限的,如果客户端发送了一个2G的大文件,则这2G数据是无法全部存放到内存中的。nginx服务器接收到一定量的数据后,会把剩余的数据缓存到文件中。文件对象结构:struct ngx_file_s { ngx_fd_t fd; //文件描述名 ngx原创 2016-11-05 16:06:14 · 4068 阅读 · 0 评论 -
nginx缓冲区链表chain
nginx接收nginx服务器的http请求包头、包体,以及响应客户端的应答包头、包体都会存放到chain链表缓冲区中。一、chain链表缓冲区数据结构//ngx_chain_t链表节点struct ngx_chain_s { ngx_buf_t *buf; ngx_chain_t *next;};//缓冲区结构struct ngx_buf_s {原创 2016-11-02 22:52:22 · 2330 阅读 · 0 评论 -
nginx内存池
一、nginx内存池的使用nginx对内存采用内存池对内存进行管理。即先开辟一个内存池空间,之后就从内存池中获取空间了,避免频繁的调用malloc/free操作。如何内存池空间不够,才会调用malloc分配一个新的内存块,并加入到内存池中。1、对于每一个客户端发起的http请求,nginx服务器都需要开辟空间来接收客户端的请求行,请求包头、以及请求的包体。这些都是从内存池中获取空间,并原创 2016-11-01 08:08:55 · 3484 阅读 · 1 评论