PHP与服务器之间的通信方式

很久不写技术类的文章,之后看了别人写的技术类文章发现再不努力总结的话,慢慢的技术会全忘光。今天说下自己对PHP,Apache,Nginx,php-fpm的简单理解。

1. 启动服务器

PHP常搭配使用的服务器有Nginx,Apache,Lighttpd,我们拿Apache和Nginx来举例说说这两款主流服务器和PHP协作的方式。

Nginx:Nginx是一个轻量级并且独立解耦的服务器,只能通过FastCGI的方式调用PHP-CGI(PHP解析器)。所以Nginx的启动并不会预先加载PHP模块,因为他根本不关心谁来处理FastCGI接口。Java,Python都可以来处理。因此我们只需要在nginx.conf里面配置FastCGI的端口和名称。然后通过socket方式实现连接。

Apache:Apache是一个重量级的服务器,他可以通过3种方式去调用PHP,分别是CGI模式,加载php5.so,FastCGI模式(与Nginx一样)。而我们通常使用的是加载php5.so文件这种模式。所以在启动Apache的时候,默认会先加载一遍PHP,再释放。这样做的好处是可以检查PHP的环境是否搭建好。如果PHP的配置文件有问题,Apache服务器会启动失败。当然,Apache在启动的时候会将PHP的一些模块初始化。

2.启动FastCGI

Nginx必须要配合FastCGI使用,Apache可以通过FastCGI的方式调用解析器。而php-fpm实现了FastCGI协议(这里很重要,FastCGI是一种协议),所以启动php-fpm后就能愉快的与PHP玩耍了。具体怎么玩耍的?

首先启动php-fpm的时候,php-fpm会预先加载多个php-cgi(解析PHP的)。当有请求来的时候就能直接用,不需要马上启动php-cgi。请求结束后php-fpm也能及时的回收资源。

3.执行PHP

php-cgi接到请求后对请求做初始化处理,包括扩展请求的初始化(php.ini中的扩展模块在服务器或者FastCGI开启的时候已经加载完了,但未初始化)分配资源,错误的处理等。然后将PHP代码交给ZE引擎,ZE会对代码做翻译执行,程序运行结束ZE会做一些垃圾回收操作,并等待下一次请求。

4.Apache与Nginx的对比

都说Nginx承受的高并发压力是Apache 的10++倍,我一直在想为什么会差别这么大。通过我们上面的分析可以知道部分原因。

一.对于静态资源比如,图片文件,js,css的请求。Nginx可以直接处理,不需用分发到php-fpm,Nginx起一个线程速度非常快。而Apache由于在开启时就初始化了PHP资源,对于静态资源Apache起一个线程产生的消耗远大于nginx,在数量级到百万千万之后就是滚雪球了。

二.Apache处理请求是采用select IO接口的方式,而Nginx是采用epoll IO接口的方式。其中select 是轮询阻塞式,而epoll是触发非阻塞式。所以Nginx支持高并发优于Apache。那为什么Apache不换到epoll模式?首先Apache的大多数模块都是采用select模式,epoll模式在很多平台无法实现。最重要的是阻塞模式相比非阻塞模式更稳定。而Apache的发展方向就是稳定+移植性。

当然,这些年的发展Nginx也相当稳定了,而Apache在高并发上也努力着,比如增加了event非阻塞模块。不过我们选择哪款服务器还是应该根据实际情况来看。比如追求稳定和安全就选择Apache,追求高并发和响应速度就选择Nginx。

PS:我不是专业做运维的,说的不对的地方请指证。