Nginx.pdf

C10K 问题

软件上的解决方案:最大化硬件资源的使用效率

请求到来

首先,操作系统内核会将完成三次握手的连接 socket,放入1个 Accept 队列(如果打开了reuseport,内核会选择某个worker进程对应的队列),某个 Nginx Worker 进程事件模块中的代码,需要调用 accept 函数取出 socket

建立好连接并分配 ngx_connection_t 对象后,Nginx 会为它分配1个内存池,它的默认大小是512字节(可以由 connection_pool_size 指令修改),只有这个连接关闭的时候才会去释放。

接下来 Nginx 会为这个连接添加一个默认 60 秒的定时器,其中需要将内核的 socket 读缓冲区里的 TCP 报文,拷贝到用户态内存中。此时会将连接内存池扩展到 1KB 来拷贝消息内容,如果在这段时间之内没有接收完请求,则返回失败并关闭连接。

Untitled

收到请求

当接收完 http uri 和 header,分配另一个默认 4KB 的请求内存池。

Nginx 会通过协议状态机解析接收到的字符流,如果 1KB 内存还没有接收到完整的HTTP头部,就会再从请求内存池上分配出 32KB,继续接收字符流。其中,这 32KB 默认是分成 4 次分配,每次分配 8KB,这样可以避免为少量的请求浪费过大的内存。

Untitled

请求的反向代理

请求的反向代理是 Nginx 的重点应用场景,这种场景下游客户端走的是公网,所以网络环境差,如果简单用一个缓冲区从客户端收一点发给上游服务器,那上游服务器的压力会很大。因为上游服务器往往效率高,一个请求被处理完之前不会再处理下一个请求。