IT

nginx学习笔记——架构

Posted by Loksin on 2017-05-17

简介

nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。一般在Unix系统上运行。(摘自百度百科)

架构

 chapter-2-1.png
1.nginx启动后,在unix系统中会以的方式在后台运行,这些后台进程包含一个master进程和多个worker进程。
2.nginx支持多线程和多进程方式,主流是多进程(nginx的默认方式)。
3.master进程主要用来管理worker进程,接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态。worker退出会自动启动新的worker进程。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。
4.worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致。
5.老式操作nginx方式,用户可以给master进程发型不同类型的信号,让master进程来管理worker进程干不同的事情;新的操作方式,nginx在0.8版本之后,引入了一系列命令行参数,来方便管理,比如,./nginx -s reload,就是来重启nginx。
6.master进程在接到信号后,会先重新加载配置文件,然后再启动新的worker进程,并向所有老的worker进程发送信号,告诉他们退出。若老的进程有未处理完的任务则先等任务处理完成才退出,进程接收到信号之后不在接收任何请求任务。
7.worker进程处理请求流程:
  • [x] ①建立好需要listen的socket(listenfd文件描述符)。
  • [x] ②master 进程fork多个worker进程。
  • [x] ③worker进程的listenfd变为可读。
  • [x] ④所有worker进程抢占互斥锁accept_mutex
  • [x] ⑤抢到的那个进程注册listenfd读事件,在读事件里调用accept接受该连接。
  • [x] ⑥读取请求,解析请求,处理请求,产生数据后,再返回给客户端。
  • [x] ⑦断开链接。

(注:一个请求,完全由worker进程来处理,而且只在一个worker进程中处理。)

8.nginx采用了异步非阻塞的方式来处理请求(网络事件),有体到系统调用就是像select/poll/epoll/kqueue这样的系统调用。关IO的解释请点开。
9.事件通常有三种类型,网络事件、信号、定时器,网络事件通过异步非阻塞来解决(8中)。信号,若nginx正在等待事件(epoll_wait时),如果收到信号,在信号处理函数处理完后,epoll_wait会返回错误,然后程序可再次进入epoll_wait调用。定时器,epoll_wait函数在调用的时候可以设置一个超时时间nginx借助这个超时时间来实现定时器,当没有事件产生,也没有中断信号时,epoll_wait会超时,也就是说,定时器事件到了。之后,nginx会检查所有的超时事件,将他们的状态设置为超时,然后再去处理网络事件,因此在处理网络事件的回调函数时,通常做的第一个事情就是判断超时,然后再去处理网络事件。
事件处理模型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
while (1) {
for (t in run_tasks) { /* 任务队列 */
t.handler();
}
update_time(&now);
timeout = ETERNITY;
for (t in wait_tasks) { /* 循环处理等待队列 */
if (t.time <= now) { // 判断超时
t.timeout_handler(); // 处理网络事件
} else {
timeout = t.time - now;
break;
}
}
nevents = poll_function(events, timeout);
for (i in nevents) {
task t;
if (events[i].type == READ) {
t.handler = read_handler;
} else { /* events[i].type == WRITE */
t.handler = write_handler;
}
run_tasks_add(t);
}
}