Web服务器
php是为web而生的一种后端语言,但是php也仅仅只是一种后端语言,要实现web开发, 我们需要html,javascript,css等开发语言的协助才能将网页展示在网页上。另外,我们知道,在web开发中,我们需要配置自己的开发环境,包括php、apache/nginx/iis、mysql,有时候还需要redis、memchaed、mongdb等。在这些软件中,nginx、apache、iis就被称之为web服务器。web服务器的作用就是接受用户的请求,如浏览器的Http请求,并将请求的数据,例如:header头,参数,请求内容等,转发到相应的应用程序,如php、java、python、c开发的程序,并将执行结果返回给浏览器。
在PHP web开发中,我们知道,如果浏览器请求的是html、jpg、css、js等静态文件,是不需要由PHP处理,直接返回给浏览器的。这就是为什么伪静态需要配置在nginx/apache上。
CGI
由于web服务器只能处理静态资源,不能直接运行php、asp、jsp、py等等,只能由各个应用程序自己内部处理。所以,web服务器与php、asp等进行了接口约定,要求双方按照协议(接口)来进行实现,web服务器只需要将请求的数据转发到对应的接口上,就完成了自己的工作。应用程序则按照协议要求的返回接口,返回给web服务器,由web服务器返回浏览器即可。
在这个请求过程中,我们把双方约定的协议(接口)称为CGI协议。
CGI协议,Common Gateway Interface,公共网关接口,是web服务器和外部应用程序直接传递信息的接口标准。也就是说,CGI实际上是一个接口标准,我们通常所说的CGI指的是CGI程序,即实现了CGI接口标准的程序,如 php-cgi等。
CGI的问题:
由于web服务器一般只处理静态资源,对于动态资源,web服务器会开启一个新的进程来启动CGI进程,将请求的数据交给CGI进程。CGI的启动需要加载配置文件(php.ini)、扩展等等,再解析动态脚本,将结果返回到web服务器,随后,web服务器关闭掉重新开启的进程。这种效率是十分低下的,并且对于高并发,是很浪费服务器资源的。
我们来看下Apache的处理过程:
在配置Apache的配置中:我们需要在配置文件httpd.conf中加上:
LoadModule php7_module "D:/phpServer/php72/php7apache2_4.dll"
AddType application/x-httpd-php .php .html .htm
当用户通过浏览器访问时,Apache判断是动态资源时,启动php7_module,php7_module通过SAPI(类似于socket的通信)调用PHP。在这种模式下,apahce请求一次,就会产生一条进程,进程内包含PHP的配置文件、扩展、数据处理计算等等。当用户过多,并发过多时,服务器就会出现问题。
而且,把mod_php放进apache内,很难定位是Apache的问题,还是php的问题。
FastCGI
fastcgi是cgi的升级版,fasgcgi会启动一个master(长驻在内存中),解析配置文件,加载扩展,启动多个worker(php-cgi)。当web服务器转发请求过来时,fastcgi会分配worker,然后接受下一个请求,当worker处理完请求时,并不会退出,而且继续等待下一个请求任务。这样就避免重复加载配置文件、扩展等一系列的启动工作,效率是很高的。当然。fastgcgi也是一种协议(接口),通常所说的fastcgi 是指实现了fastcgi协议的应用程序。
PHP-FPM
php-cgi 就是PHP实现的自带的fastcgi管理器。但是phpcgi性能很差,而且不能平滑重启,主要体现在,修改php.ini文件后,需要重启才能生效这一点上。
在2004年,Andrei Nigmatulin开发了 php-fpm,彻底打破了这种局面,是一个PHP专用的fastcgi管理器,并且在php5.3之后,内置在php内部。
由于PHP-CGI只是一个CGI程序,只能解析请求,返回结果,不能进行进程管理,所以php-fpm也是用于调度管理PHP解析器php-cgi的管理程序。
php-fpm 内部是通过生成新的子进程实现php.ini修改后的平滑重启。