Nginx
Nginx
是一个高性能的
Web
服务器,能够同时处理大量的并发请求。它结合多进程机制和异步机制,异步机制使用的是异步非阻塞方式 ,接下来就给大家介绍一下 Nginx
的多线程机制和异步非阻塞机制 。
多进程机制
服务器每当收到一个客户端时,就有 服务器主进程 (
master process
)生成一个 子进程(worker process )出来和客户端建立连接进行交互,直到连接断开,该子进程就结束了。使用进程的好处是各个进程之间相互独立,不需要加锁,减少了使用锁对性能造成影响,同时降低编程的复杂度,降低开发成本。其次,采用独立的进程,可以让进程互相之间不会影响 ,如果一个进程发生异常退出时,其它进程正常工作, master
进程则很快启动新的
worker
进程,确保服务不会中断,从而将风险降到最低。缺点是操作系统生成一个子进程需要进行 内存复制等操作,在资源和时间上会产生一定的开销。当有大量请求时,会导致系统性能下降 。
异步非阻塞机制
每个工作进程 使用 异步非阻塞方式 ,可以处理 多个客户端请求 。当某个 工作进程 接收到客户端的请求以后,调用 IO
进行处理,如果不能立即得到结果,就去 处理其他请求 (即为 非阻塞 );而 客户端 在此期间也 无需等待响应 ,可以去处理其他事情(即为 异步 )。当 IO
返回时,就会通知此 工作进程 ;该进程得到通知,暂时 挂起 当前处理的事务去 响应客户端请求 。
使用未定义的服务器名称来阻止处理请求
只需将请求删除的服务器就可以定义为:
Server{
listen 80;
server_name "";
return 444;
}
这里,服务器名被保留为一个空字符串,它将在没有
“
主机
”
头字段的情况下匹配请求,而一个特殊的Nginx
的非标准代码
444
被返回,从而终止连接。
一般推荐
worker
进程数与
CPU
内核数一致,这样一来不存在大量的子进程生成和管理任务,避免了进程之间竞争CPU
资源和进程切换的开销。而且
Nginx
为了更好的利用 多核特性 ,提供了
CPU亲缘性的绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来Cache 的失效。
对于每个请求,有且只有一个工作进程 对其处理。首先,每个
worker
进程都是从
master
进程fork 过来。在
master
进程里面,先建立好需要
listen
的
socket
(
listenfd
) 之后,然后再
fork
出多个 worker
进程。
所有
worker
进程的
listenfd
会在新连接到来时变得可读 ,为保证只有一个进程处理该连接,所有worker 进程在注册
listenfd
读事件前抢占
accept_mutex
,抢到互斥锁的那个进程注册
listenfd
读事件 ,在读事件里调用 accept
接受该连接。
当一个
worker
进程在
accept
这个连接之后,就开始读取请求、解析请求、处理请求,产生数据后,再返回给客户端 ,最后才断开连接。这样一个完整的请求就是这样的了。我们可以看到,一个请求,完全由 worker
进程来处理,而且只在一个
worker
进程中处理。
在 Nginx
服务器的运行过程中, 主进程和工作进程 需要进程交互。交互依赖于
Socket
实现的管道来实现。
Nginx服务器上的Master和Worker进程分别是什么
- 主程序 Master process 启动后,通过一个 for 循环来 接收 和 处理外部信号 ;
- 主进程通过 fork() 函数产生 worker 子进程 ,每个子进程执行一个 for循环来实现Nginx服务器对事件的接收和处理 。