nginx的基础概念

http://tengine.taobao.org/book/index.html   算是看书笔记吧,太多了就用自己的话写一下了
nginx是以多进程 的方式来工作的,启动时会有一个master进程和多个worker进程,多个worker进程之间是对等的,一般我们的worker进程数设置为与机器cpu核数一致,这样就不会存在争抢资源了。
nginx启动后,我们操作其实是与master进程通信,worker受master控制,当一个请求过来,每个进程都有可能处理,那就要抢一个accept_mutex,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接,之后就开始处理连接(读取请求,解析请求,处理请求,产生数据再返回)。
worker如何处理高并发呢?是创建线程来应对吗?肯定不是了,要是那么多线程,光切换也要费好多开销了。nginx是用异步非阻塞处理的,注意是异步,具体到系统调用就是你select/poll/epoll/kqueue这样的系统调用。事件没准备好先放在epoll里面,准备好后再去处理。此时的线程只有一个,同时处理的请求也只有一个,只是在请求间不断的切换,这里的切换是没有开销的,因为主动让出的。TODO 此处要查资料
对于一个web服务器来说,事件通常有三种类型:网络事件,信号,定时器。
Connection:
nginx启动时,会解析配置文件,得到监听的端口与ip,然后在master进程中初始化这个监控的socket。
连接数=worker_connections*worker_processes。如果http作为反向代理则并发数量要除2,因为要与后端服务的连接。
一个连接过来,多个worker如何保证公平?还记得上面提到的accept_mutex吗,只有拿到这个锁才可以加accept事件,nginx有一个设置可以控制进程要不要支竞争accept_mutex锁,ngx_accept_disabled的值。这个值 如何确定呢?
它是nginx单进程的所有连接总数的八分之一减去剩下的空闲连接数量,也就是说,空间的连接数越小,这个值就会越大,当这个值 大于0时就不会去获取accept_mutex锁,就等于把机会让出去,数值越大,让出的机会就越多。
request:
也就是http请求,在nginx中的数据结构是ngx_http_request_t。它是对一个http请求的封装。对nginx来说,一个请求是从ngx_http_init_requeset开始的,在这个函数中会设置读事件ngx_http_process_request_line(处理请求行),要处理就要读取请求数据ngx_http_read_request_header,读取好了用ngx_http_parse_request_line函数来解析请求行。整个请求行解析到的参数会保存到Ngx_http_request_t结构当中。
在解析完请求行后,nginx会设置读事件的handler为ngx_http_process_request_headers,后续的处理就在这个函数中进行,读取和解析跟上面一样,ngx_http_read_request_header,ngx_http_parse_header_line,请求头保存在ngx_http_headers_t的域headers_in中。headers_in是一个链表结构,保存所有的请求头。一些特殊处理的请求头与请求函数会放在一个映射表里面ngx_http_headers_in。
当nginx解析到有两个回画换行符时,表示请求头结束,会调用ngx_http_process_request来处理请求,具体读写事件(ngx_http_request_t中的read_event_handler或write_event_handler)处理函数为ngx_http_request_handler,然后再调用ngx_http_handler来真正处理一个完整的http请求。
请求头读取完了,nginx先不读取请求的body,会把read_event_handler设置为ngx_http_block_reading;真正处理数据是在ngx_http_handler里设置write_event_handler为ngx_http_core_run_phases并执行。
ngx_http_core_run_phases执行多阶段请求处理,因为它最后会产生数据,产生的响应头会放在ngx_http_request_t的headers_out中。
keepalive
长连接:在一个连接上面执行多人请求,前提要先确定请求头与响应体的长度。
http1.0 响应头用content-length,http1.1用Transfer-encoding为chunked传输。
keepalive_timeout为0表示关掉keepalive。
pipe
pipeline其实就是流水线作业
lingering_close
延迟关闭,当nginx关闭连接时,并非立即关闭,而是先关闭tcp连接的写,再等待一段时间后再关掉连接的读。
...
原文地址:https://www.cnblogs.com/javage/p/10568349.html