NGINXPHP 是一对很好的搭档,那么 nginx 是如何与 php 结合实现 对外的网络访问呢?

首先 NGINX 作为一个 web 服务器只能处理静态请求,关于动态请求,是通过 CGI 具备的动态请求能力。

NGINX会将动态请求交给 CGI 处理,CGI 将处理结果返回给 NGINXNGINX 再将请求的结果返给给浏览器

CGI 的作用

当在浏览器中输入一个动态地址时,如 /index.php, 通过 DNS 解析,最终请求会到 web 服务器上,当 NGINX 发现请求时动态请求。会交给 PHP 解释器处理此请求,那再给 NGINX 需要给 PHP 解释器传输哪些数据呢?请求地址,请求方法,请求参数这些东西总归是要有的,但是也不能仅仅是这些,像请求头和 cookie … 也应该包含其中。

那么怎么确定到底该传输哪些数据,以及以什么样的格式传输呢? CGI 就是解决这个问题而生的。

CGI 全程通用网关接口 (英语:Common Gateway Interface,CGI) 是为提供网络服务而执行控制台应用的程序,提供于服务器上实现动态网页的通用协议。通常情况下,一次请求对应一个CGI 脚本的执行,生成一个 HTML。

CGI 接口规定了 nginx 与动态解释器之前传输数据的参数和格式,为 nginx 和脚本解释器之间建立起了一个桥梁。

CGI 的存在使 web 服务器与动态语言之间的关系进行了解耦,使得 web 服务器可以处理的动态请求,但是 CGI 的设计使通过进程的方式来处理动态请求的,当动态请求过来后,CGI 会起一个进程进行处理,请求结束后关闭进程.

进程的频繁创建和销毁是存在开销的,这也就导致了 CGI 很难应对高并发的场景, FastCGI 的出现解决了这个问题.

FastCGI

快速通用网关接口Fast Common Gateway Interface/FastCGI)是一种让交互程序与Web服务器通信的协议。FastCGI是早期通用网关接口(CGI)的增强版本。

FastCGI致力于减少 nginx 与CGI程序之间交互的开销,从而提升服务器处理并发的能力。

  1. Web Server 启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module,nginx 下 fastcgi 与服务器是分离的,fastcgi 可有 lighttpd 下的spawan-cgi或者 php-fpm 来管理));
  2. FastCGI进程管理器自身初始化,启动多个CGI解释器进程 (在任务管理器中可见多个php-cgi.exe)并等待来自Web Server的连接。
  3. 当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi.exe。
  4. FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在WebServer中)的下一个连接。 在正常的CGI模式中,php-cgi.exe在此便退出了。

​ 在上述情况中,你可以想象CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部dll扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

php-fpm 是什么

PHP-FPM(FastCGI Process Manager:FastCGI进程管理器)是一个PHPFastCGI管理器, 也就是说 FastCGI 是接口,php-fpm 是 FastCGI 的具体实现。php-fpm 专门用于执行 PHP 的代码,并将响应结果通过 NGINX 返回给浏览器。

Conclusion

NGINX 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。在 WEB 开发中主要用户处理静态文件的响应,其本身并不具备动态请求的解析能力。 CGI 是定义了一套接口,用于连接 NGINX 与动态语言,使 NGIXN 具备了动态请求的处理能力。

FastCGI: 为了解决 CGI 的性能问题,FastCGI 采用 master-worker 的形式,通过进程管理使得 CGI 能够处理多个请求,即不用频繁的创建和销毁进程,也不需要频繁的初始化配置,从而提升并发处理能力。

php-fpm: FastCGI 在 PHP 语言层面的具体实现,用于执行 PHP 代码。

Reference

What is CGI, FastCGI

FastCGI