对比 PHP 各种运行模式

比较主流的 PHP 运行模式有三种,分别是:

  1. Apache + mod_php 直接挂载模块运行代码,无进程通讯;
  2. Nginx + php-fpm 通过 FastCGI 处理进程间通讯;
  3. Cpanel、DirectAdmin 所使用的 suPHP 相当于 CGI 模式。

Hostker&主机壳选择的是第一种,使用服务器、VPS 的团队通常选择第二种,虚拟主机厂商基本上都是第三种。我们先了解他们的运行原理,再对比一下优点和缺点,最后看性能。想直接查看性能对比可以直接拉到本文最下面。

Apache + mod_php

几年前 LAMP(Linux Apache MySQL PHP)非常火爆,然而现在使用 Apache 似乎有一点非主流的味道。大众对 Apache 的印象是速度慢,配置难。不过到了 Apache 2.4,性能已经基本和 Nginx 相当。

我们选择 Apache 的主要原因是他可以直接将 PHP 当作一个模块挂载在进程中运行,选择 Prefork 预派生进程模式,Apache 会维护一个进程池,提前启动一群 httpd 进程等待请求进来,可以直接在进程中运行 PHP 并返回处理结果。处理完成后进程不会退出,而是继续等待下一个请求。

结合 Apache 的 .htaccess 可以实现无需重启即可重载绝大多数配置,可以让用户非常自由的定制各项配置参数。因此这是性能最好、配置最灵活的方案。

不过这样运行的进程全部的系统用户都是同一个,安全方面就需要十分谨慎,其它虚拟主机厂商无法使用的原因是用户可以非常轻松的跨到其它虚拟主机去读数据,非常危险。因此我们在 PHP 层面开发了一套沙箱解决这一问题,具体细节移步《Hostker 沙箱环境介绍》阅读。

Nginx + php-fpm

在大多数人眼中,Nginx 和 Apache 扮演的角色是一样的。其实不是,Nginx 是一个反向代理服务,而 Apache 是一个可以直接运行 PHP 的 HTTP 服务。也就是说,除了 PHP 之外,NodeJS、Golang 等语言在运行的时候,都是需要自行处理 HTTP 或者 FastCGI 协议的,Nginx 只管将 HTTP 请求或者是 FastCGI 转发给其它进程。而 Apache 则是直接在自己进程内部完成 PHP 的运行并直接返回结果。

因此 Nginx 在运行 PHP 时,需要 PHP 自己启动 php-fpm 管理一个进程池,并监听在一个 TCP 端口(最常见的 9000 / 9001)或者 Unix Socket 等待 Nginx 通过 FastCGI 转发请求过来。所以性能方面无论如何都躲避不了进程通讯的 IO 性能消耗,这点不如 Apache 性能好。

不过鉴于大多数运维都比较熟悉 Nginx 的配置文件,配置项相比 Apache 也稍微简单一些,因此一些自己维护服务器的运维会选择这个模式。

suPHP(类似 CGI)

大概 20 年前,CGI 是最流行的运行动态网站所使用的接口标准。在一个请求到达 HTTP 服务(Apache)之后,HTTP 服务会根据 CGI 配置通过命令启动一个进程处理这一请求,处理完成之后再关闭进程。

相信读到这里,我不需要做性能对比,读者就明白这肯定是性能最差的方案。那么虚拟主机厂商为什么都喜欢这个模式?因为使用 Cpanel、DirectAdmin 等方案的他们没有比较好的用户隔离方法,只能通过新建不同的 Linux 系统用户运行 PHP 来隔开用户。

suPHP 模块可以实现当请求到达 Apache 之后,判断这个虚拟主机归属哪个用户,通过对应用户启动一个 PHP 进程来处理,并在处理完成之后关闭这个进程。因此是市面上虚拟主机最常用的模式。

性能对比

以下对比使用的配置是单核 768M 内存 512M Swap 的虚拟机,测试使用的是 phpinfo() 函数返回的结果有 80 KB 长度,这一函数在运行过程中会扫描 PHP 的所有环境配置项,因此能比较直观的看出初始化和进程通讯所产生的性能影响。

PHP 版本是 7.0.8,Apache 和 Nginx 版本在截图中。进程配置(Apache 和 php-fpm)是统一初始化 15 个进程,最大限制 100 个进程。

使用测试工具是 ab,发起 100 并发,总计 1000 次请求。

Apache + mod_php 测试结果是每秒完成 412 次请求

apache_mod

Nginx + php-fpm 测试结果是每秒完成 352 次请求。FastCGI 的进程间通讯还是拉低了性能。

nginx_fpm

最后是同行所使用的 suPHP ,每秒完成 41 次请求

apache_cgi

每次启动和关闭进程造成的性能影响惨不忍睹,我们的性能是同行的 10 倍!

《对比 PHP 各种运行模式》上有2条评论

  1. 『不过到了 Apache 2.4,性能已经基本和 Nginx 相当。』关于这一点能否在后续的文章里再介绍一下呢?例如在2.4版本中apache做了哪些优化实现了性能的提升之类的。

    1. Apache到2.4版本Event模式已经脱离实验期可以用于生产环境了,并且MPM有了异步读写支持,对于Apache不如Nginx的说法就是2.4以前的Event不太成熟而已。不过用户习惯上跑静态资源或者反向代理还是喜欢Nginx所以没人注意到

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.