应用场景

在 LNMP (linux、nginx,mysql、php)中的作用或角色:Nginx 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。
LNMP 中的作用或角色:nginx 本身不能处理 PHP,它只是个 web 服务器,当接收到请求后,如果是 php 请求,则发给 php 解释器处理,并把结果返回给客户端。
php-fpm 是一个守护进程(FastCGI 进程管理器)用于替换 PHP FastCGI 的大部分附加功能,对于高负载网站是非常有用的。
sudo apt-get install -y php7.0-fpm

安装

sudo apt-get update
sudo apt-get install -y nginx

启动

所有的启动配置文件都在 /etc/init.d/nginx 这个目录下,所以相关操作都可以在这个文件夹启动命令,这其实就是一个启动脚本。
sudo /etc/init.d/nginx start
sudo service nginx start

原理

Nginx 是以多进程的方式来工作的,当然 Nginx 也是支持多线程的方式的。

Nginx 启动后,在 unix 系统中会以 daemon (守护进程)的方式在后台运行,后台进程包含一个 master 进程和多个 worker 进程(你可以理解为工人和管理员)。
image.png

worker 进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供 80 端口的 http 服务时,一个连接请求过来,每个进程都有可能处理这个连接。那么问题来了,到底最后怎样处理,是由什么决定的呢?我们来看一看一个完整的请求是怎样通过互相的协作来实现的:

(1)首先,每个 worker 进程都是从 master 进程 fork 过来,在 master 进程里面,先建立好需要 listensocketlistenfd)之后,然后再 fork 出多个 worker 进程。

(2)所有 worker 进程的 listenfd 会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有 worker 进程会在注册 listenfd 读事件前抢 accept_mutex,抢到互斥锁的那个进程注册 listenfd 读事件,然后在读事件里调用 accept 接受该连接。

(3)当一个 worker 进程在 accept 这个连接之后,就开始读取请求、解析请求、处理请求。产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。

我们可以看到:一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。

也许你还有个疑问,那就是 Nginx 采用多 worker 的方式来处理请求,每个 worker 里面只有一个主线程,那能够处理的并发数很有限啊,多少个 worker 就能处理多少个并发,何来高并发呢?这就是 Nginx 的高明之处,Nginx 采用了 异步非阻塞 的方式来处理请求,也就是说,Nginx 是可以同时处理成千上万个请求的。

这里补充一下异步非阻塞的概念:

异步的概念是和同步相对的,也就是不同事件之间不是同时发生的。

非阻塞的概念是和阻塞对应的,阻塞是事件按顺序执行,每一事件都要等待上一事件的完成,而非阻塞是如果事件没有准备好,这个事件可以直接返回,过一段时间再进行处理询问,这期间可以做其他事情。

Nginx 本身做的工作实际很少,当它接到一个 HTTP 请求时,它仅仅是通过查找配置文件将此次请求映射到一个 location block,而此 location 中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看做 Nginx 真正的劳动工作者。

  • 通常一个 location 中的指令会涉及一个 handler 模块和多个 filter 模块(当然,多个 location 可以复用同一个模块)。

    • handler 模块负责处理请求,完成响应内容的生成;
    • filter 模块对响应内容进行处理。

白风之下
10 声望3 粉丝

« 上一篇
编译知识总结
下一篇 »
vscode笔记