Nginx
2013-04-12
Nginx在Apache快要一统天下的局面下,以卓越的性能和稳定性后来居上。 为了提高性能,nginx采用异步事件框架,使所有需要阻塞的过程都分解为异步事件,避免阻塞的性能消耗。
##处理阶段对应的事件
Phase
建立TCP连接
开始接收用户请求
接收到用户请求并分析已接收的请求是否完整
接收完整的请求后开始处理
由目标静态文件读取部分内容直接发送给用户
对非keep-alive请求在发送完文件后关闭连接
用户关闭连接结束请求
Event
接收到TCP的SYN包
接收到TCP中的ACK包表示连接建立
接收到用户的数据包
接收到用户的数据包
接收到用户的数据包或ACK包表示用户已接收数据包,TCP窗口向前滑动
接收到ACK包表示用户已接收到之前发送的所有数据包
接收到FIN包
nginx模块组成是这样的
┌—— ngx_conf_module //配置模块
│
└── ngx_mail_module //定义mail模块
│ ├── ngx_mail_core_module
│ ├── ngx_mail_imap_module
│ ├── ngx_mail_proxy_module
│ ├── ngx_mail_pop3_module
│ ├── ngx_mail_ssl_module
│ └── ngx_mail_smtp_module
│
├── ngx_http_module //定义http模块
│ ├── ngx_http_core_module
│ ├── ngx_http_headers_filter_module
│ ├── ngx_http_log_module
│ ├── ngx_http_write_filter_module
│ ├── ngx_http_upstream_module
│ ├── ngx_http_rewrite_module
│ ├── ngx_http_static_module
│ └── ngx_http_proxy_module
│
├── ngx_events_module //定义事件模块
│ ├── ngx_event_core_module
│ ├── ngx_epoll_module
│ ├── ngx_selet_module
│ ├── ngx_kqueue_module
│ ├── ngx_poll_module
│ └── ngx_aio_module
│
├── ngx_core_module
│
├── ngx_openssl_module
│
└── ngx_errlog_module
核心结构体
typedef struct {
//核心模块名称
ngx_str_t name;
//解析配置项前,Nginx框架调用create_conf方法
void *(*create_conf)(ngx_cycle_t *cycle);
//解析配置项完成后,Nginx框架会调用init_conf方法
char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
} ngx_core_module_t;
typedef struct ngx_listening_s ngx_listening_t;
struct_ngx_listening_s {
//socket套接字句柄
ngx_socket_t fd;
//监听sockaddr地址
struct sockaddr *sockaddr;
//sockaddr地址长度
socketlen_t socklen;
//存储IP地址的字符串addr_text最大长度,指定了addr_text所分配的内存大小
size_t addr_text_max_len;
//以字符串形式存储IP地址
ngx_str_t addr_text;
//套接字类型,当type是SOCK_STREAM时,表示TCP
int type;
//TCP实现监听时的backlog队列,表示允许正在通过三次握手建立TCP连接但还没
//有任何进程处理的连接的最大个数
int backlog;
//内核中对于这个套接字的接收缓冲区大小
int rcvbuf;
//内核中对于这个套接字的发送缓冲区大小
int sndbuf;
//新TCP连接建立成功后的处理方法
ngx_connection_handler_pt handler;
//保留指针,目前用于http或mail等模块保存当前监听端口对应的所有主机名
void *server;
//log和logp都是可用的日志对象指针
ngx_log_t log;
ngx_log_t *logp;
//为新连接建立内存池的初始大小
size_t pool_size;
//TCP_DEFER_ACCEPT选项将在建立TCP连接成功且接收到用户的请求数据后,
//才向对监听套接字感兴趣的进程发送事件通知,而连接建立成功后,如果
//post_accept_timeout秒后仍然没有收到用户数据,则内核直接丢弃连接
ngx_msec_t post_accept_timeout;
//
}
模块化,没那么简单。