首先需要记住的是,任何一种web服务器(Apache、Nginx等)都是被设计成向用户发送HTML、图片等静态资源的,web服务器自身并不能解释任务动态脚本语言(PHP、Java等)
PHP解释器就是用来解释web应用中的PHP代码,并将它解释成HTML或其他静态资源,然后将解析的结果传给web服务器,最后再有web服务器传给用户
因此,Apache和Nginx都需要PHP解释器来处理PHP代码,web服务器和PHP解释器是通过SAPI来进行通信的,简单来说,SAPI指的是PHP具体应用的编程接口,就像PC一样,无论安装哪种操作系统,只要满足了PC的接口规范都可以正常在PC上运行,PHP脚本要执行有很多种方式,下面就说说PHP的几种运行方式:
1、cli:就是命令行模式,例如你可以在控制台输入:
php index.php
2、CGI:公共网关接口,web service与你或其他机器上的程序(index.php)进行交谈的一种工具,其程序必须运行在网络服务器上,在服务器环境中,为程序提供标准的接口(规则),通过这个接口,程序可以与服务器进行交流,程序的语言没有要求,不同类型的语言写的程序只要符合CGI标准,就能作为一个CGI程序和web service就行交互。
以CGI方式运行时,web service将用户请求以消息的方式转交给PHP独立进程,PHP与web服务器之间无从属关系
web服务器和一个独立进程之间的协议:把HTTP request的header设置成进程的环境变量,HTTP request的正文设置成进程的标准输入,而进程的标准输出就是HTTP response包括header和正文,服务器要支持CGI就要提供CGI中要求的环境变量。
web服务器使用了Unix shell环境变量来保存web服务器传递出去的参数,然后生成一个运行CGI的独立进程
3、Fastcgi:CGI有很多缺点,没接收一个请求就要fork一个进程处理,只能接受一个请求做出一个相应。请求结束后该进程就会结束,而fastcgi会事先启动起来,作为一个CGI的管理服务器存在,预先启动一系列的子进程来等待处理,然后等待web服务器发过来的请求,一旦接受到请求就有子进程处理,这样由于不需要在接受到请求后启动CGI,会快很多,fastcgi使用进程/线程池来处理一连串的请求,这些进程/线程有fastcgi服务器管理,而不是web服务器。当进来一个请求时,web服务器把环境变量和这个页面请求通过一个socket长连接传递给fastcgi进程,fastcgi像是一个常驻型的CGI,它可以一直执行,在请求到达时不会花费时间去fork一个进程来处理。因为它只是一个通信协议,它还支持分布式的运算,即fastcgi程序可以在网站服务器以外的主机上执行并且接受来自其他网站服务器的请求(分布式原理)
Fastcgi整个流程:
1. web服务器启动时载入fastcgi进程管理器
2. fastcgi自身初始化,启动多个CGI解释器进程(可见多个PHP-CGI)并等待来自web服务器的请求(只初始化一次,有有个好处是,可以持续化数据库连接)
3. 当请求web服务器时,web服务器通过socket请求fastcgi进程管理器,fastcgi进程管理器选择并连接到一个CGI解释器,web服务器将CGI环境变量和标准输入发送到fastcgi子进程PHP-CGI
4. fastcgi子进程处理完成后将标准输出和错误从同一连接返回给web服务器,当fastcgi子进程结束后请求便结束了。fastcgi子进程接着等待处理来自fastcgi进程管理器的下一个连接,在CGI模式中,PHP-CGI在此便退出了
4、mod_php:即Apache运行PHP的默认方式,将PHP作为web服务器的子进程控制,两者之间有从属关系,最明显的例子就是在CGI模式下,如果修改了php.ini的配置文件,不用重启web服务便可生效(每次都会加载php.ini的配置,这也是导致性能能地下的一个原因),而模块模式下需要重启web服务。以mod_php模式运行PHP,意味着PHP是作为Apache的一个模块来启动的,因此只有在Apache启动的时候会读取php.ini配置文件并加载扩展模块,在Apache运行期间是不会再去读取和加载扩展模块的
Apache的工作模式 prefork的工作原理
一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache总是试图保持一些备用的 (spare)或是空闲的子进程用于迎接即将到来的请求。这样客户端就无需在得到服务前等候子进程的产生。在Unix系统中,父进程通常以root身份运行以便邦定80端口,而 Apache产生的子进程通常以一个低特权的用户运行。User和Group指令用于配置子进程的低特权用户。运行子进程的用户必须要对他所服务的内容有读取的权限,但是对服务内容之外的其他资源必须拥有尽可能少的权限。
关于Apache的工作模式可以参考:http://kimi.it/339.html
感觉这种模式把PHP嵌入到Apache中,相当于给Apache加入了解析PHP文件的功能