当一个url请求发送的web server后,是如何解析并返回结果的呢?
先介绍下今天的几个主角:
Nginx,cgi,php-cgi,FastCgi,php-fpm
正式因为这几个主角的存在,当一个url请求发送到服务器后,才能完成调度,解析,并返回结果。
当一个请求,比如 /index.html 发送到web server(apache or Nginx),web server配置文件检测到这是一个简单的请求静态文件,于是便可以在文件系统中寻找的该文件直接返回。但是如果是一个 /index.php 请求,web server发现其不是一个静态文件,便无法再解析,于是,它便起到了一个传递者的作用,把这个请求传递给能解析它的人手里,然后接受解析结果,并返回给web.
web server :一个内容的传递者
当一个动态请求,比如 /index.php 发送到 web server(Nginx)后,Nginx无法解析,便会启动对应的Cgi程序,这里就是PHP解析器,PHP解析器会解析php.ini文件,然后初始化php执行环境,解析请求,并返回结果。
Cgi:只是个协议,web server根据这个协议知道要启动那个程序
这一切看起来很流畅,但是仔细读上面的流程会发现一个问题“接收到一个请求,PHP会解析php.ini文件,初始化执行环境”,这tm会非常耗时啊,初始化环境操作啊,这个在高并发下是绝对不能忍受的,于是便出现了Fast-Cgi,所以Fast-Cgi也是协议,它只是Cgi的升级版。
Fast-Cgi:Cgi协议的升级版,优化了该协议,提高了性能
Fast-Cgi是如何提高性能的?首先它会启动一个master,来解析php.ini文件,初始化php执行环境。然后会根据配置文件启动一些woker进程。当master接收到一个请求后,会立即转给一个worker,然后又继续准备接受请求。worker接收到请求后,会解析,并按照fast-cgi协议约定的格式返回给web。这就大大的提高了性能。
而php-fpm就是完成了上述功能,及实现了Fast-Cgi协议的东西。
php-fpm:实现了Fast-Cgi协议,完成了对php解析器的进程管理
php-cgi:只是个cgi程序,只能解析请求,并返回结果,不负责进程方面的事情
小结
当一个请求发送到web server(apache/nginx)后,如果是静态文件,则直接返回文件系统中的该文件,如果是非静态文件,nginx则无法处理, 便会启动对应的cgi程序,及php-cgi,php-cgi是个老人了,每次解析配置文件,初始化环境很慢,因此引入了fast-cgi,fast-cgi只是个协议,它不是进程,也不受任何人管理,它做的事情就是有一个master和一定数量的worker,接收每个请求,并且在高并发的情况下,能很好的处理,看起来像个年轻人一样高效,轻便。但是由谁来实现这个高效,年轻的协议,管理众多php-cgi进程呢?这就是php-fpm,原本php-fpm是php的插件,但是因为它越来越优秀,已经被php官方收录,成为了php的一员。
ok,这就是完整的过程了。
一个有意思的故事
你是php,想和法国人(nginx)做生意。
你说php语言,法国人说C语言,你们之间无法共同怎么办?
需要把你们的语言按照标准的通用的协议转换成一种通用的语言英语(fast-cgi)。
那么谁来转换呢?
你需要使用翻译机(php-fpm)。
nginx有它自己的翻译机。
然后你们就可以做生意啦.....