Apache 在生产环境中运行缓慢。经过一段时间的搜索,我终于进入了 #apache IRC 频道,专家让我使用以下命令检查 apache 模式:
sudo apachectl -V
并惊讶地发现服务器 MPM是预分叉。他们强调说请勿在生产服务器上使用 PREFORK。事实证明,Ubuntu 软件包(可能是从 Debian 继承而来?)坚持以 prefork 模式运行 apache,尽管使用 Apache 运行 PHP 的推荐方法明确推荐使用 proxy_fcgi 和 php-fpm,然后是 fcgid,最后说不应该使用 prefork:
为什么你不应该再使用 mod_php 和 prefork mpm
- mod_php 始终加载到每个 httpd 进程中。即使 httpd 正在提供静态/非 php 内容,该内存也在使用中。
- mod_php 不是线程安全的,并迫使你坚持使用 prefork mpm(多进程,无线程),这是最慢的配置
该页面还包含一些PHP-FPM 详细信息但这似乎有点复杂和不清楚,似乎涉及大量手动配置。我很失望和惊讶 Ubuntu 16 没有 fastCGI 模式或类似的东西的包选项。
我尝试将 apache 切换到事件模式使用 a2enmod 并尝试重新启动 apache 时,出现错误:
Apache 正在运行线程 MPM,但您的 PHP 模块未编译为线程安全的。您需要重新编译 PHP
无论如何,我想知道是否有人有一些简单的分步说明,以便在使用 PHP 7.0 的 Ubuntu 16 上运行 fastCGI 模式尽可能地依赖包安装程序。我目前正在查看大量解释不清、模糊的说明,我担心错误的决策会破坏我的生产环境。
另外,有人应该添加 mpm-event 作为标签选项。这就是 #apache IRC 人员推荐的。
答案1
以斯拉提出了一个很好的方法,但它没有包含一些可能会让依赖包管理器的人们感到困惑的细节。笔记:我不确定这些步骤是否准确。如果有人遇到麻烦或发现问题,请告诉我,我会更新此帖子。
首先,截至撰写本文时,Ubuntu 的 apache2 软件包坚持要求在安装 PHP 时使用 prefork。不过,不要绝望,因为您仍然可以使用软件包安装程序来安装和更新 PHP和apache2,仍然可以使用 Apache 进行配置事件使用 PHP-FPM 模式作为Apache wiki 推荐并在使用 mod_proxy_fcgi 和 php-fpm 在 apache httpd 2.4.x 上实现高性能 PHP. 基本思想是apache2和PHP-FPM通过socket进行通信而不是PHP作为Apache模块运行。
1)删除或禁用 Apache PHP 模块
因为 Ubuntu 软件包在安装 PHP 时坚持使用 prefork Apache,所以我们必须将它们分开。我使用 apt 卸载了 libapache2-mod-php7.0,因为我不再需要该软件包:
sudo apt-get remove libapache2-mod-php7.0
或者,您可以禁用 php7.0 Apache 模块,但这不会从系统中删除 apt 包,从而留下令人讨厌的系统垃圾。
sudo a2dismod php7.0
2)将Apache切换到事件模式并启用fcgid
我相信这些命令应该可以解决问题:
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo a2enmod proxy_fcgi
3)安装PHP-FPM
我已经安装了 PHP 7 及其各种模块,因此我只需使用以下命令安装 PHP-FPM:
sudo apt-get install php7.0-fpm
4)编辑您的VirtualHost配置以使用PHP-FPM处理PHP文件:
就我而言,我编辑了默认 SSL 主机,/etc/apache2/sites-available/default-ssl.conf,并在顶部附近添加了这一行:
ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/run/php/php7.0-fpm.sock|fcgi://localhost/var/www/html/
重要的这指示 Apache 使用 PHP-FPRM 和此指令中的路径来处理 PHP 文件请求(/运行/php/php7.0-fpm.sock)必须与指定的路径匹配听文件中的指令/etc/php/7.0/fpm/pool.d/www.conf
5)重新启动Apache
sudo service apache2 restart
要检查事件模式是否已启用,请使用以下命令:
sudo apachectl -V
在输出中,你应该看到以下内容:
Server MPM: event
尝试创建一个 phpinfo 页面并在浏览器中访问它。您应该Server API: FPM/FastCGI
在输出中看到。
答案2
为了方便起见,发行版提供了“mod_php”方法。
而性能最佳的方式是 apache w/event + mod_proxy_fcgi -> php-fpm。
也许他们应该与时俱进,但对于他们来说,这很困难,因为许多框架都以“即插即用”的方式附带 .htaccess mod_php 配置。最后,只有管理员负责正确管理和配置他们的网站。
如果您正在生产中,我建议您使用测试服务器来练习升级和更改。
关于 wiki,我更喜欢或者建议您使用“处理程序”方法。 https://wiki.apache.org/httpd/PHP-FPM#Proxy_via_handler。
也就是说,配置 php-fpm 以准备好套接字并具有足够的权限以便 Apache 用户向其发送请求并配置 Apache 使用它。
一个简单的例子:
# needed modules for reverse proxying to php-fpm
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
<Virtualhost *:443>
ServerName whatever.example.com
#other typical directives here
<Directory /var/www/php-app>
<FilesMatch \.php>
SetHandler "proxy:unix:/path/to/app.sock|fcgi://localhost/"
<FilesMatch>
</Directory>
</VirtualHost>
编辑:
通过这种方式,您使用哪个 PHP 版本并不重要,因为 Apache 并不关心,它只会将适当的请求反向代理到 php-fpm。
另外,不要忘记卸载 mod_php 以便能够使用 mpm_event。
编辑2:
根据要求,您不需要从 debian/ubuntu 中卸载 mod_php 包,Apache 只关心其配置,因此卸载模块就可以了。