将 apache 从 prefork 切换到 Ubuntu 16 中的事件,让 php 7 正常工作

S. *_*Imp 14 php-fpm apache-2.4 php7 ubuntu-16.04 mpm-event

Apache 在生产中运行缓慢。搜索了一段时间的答案后,我终于去了#apache IRC频道,专业人士让我用这个命令检查apache模式:

sudo apachectl -V
Run Code Online (Sandbox Code Playgroud)

并且惊讶地发现Server MPMprefork。他们强调说不要在生产服务器上使用 PREFORK。事实证明,Ubuntu 软件包(大概是从 Debian 继承的?)坚持在 prefork 模式下运行 apache,尽管推荐的使用 Apache 运行 PHP 的方法明确推荐了 proxy_fcgi 和 php-fpm,然后是 fcgid 并最终说你不应该使用预分叉:

为什么你不应该再将 mod_php 与 prefork mpm 一起使用

  • mod_php 一直加载到每个 httpd 进程中。即使当 httpd 提供静态/非 php 内容时,该内存也在使用中。
  • mod_php 不是线程安全的,并迫使您坚持使用 prefork mpm(多进程,无线程),这是最慢的配置

该页面还包含有关 PHP-FPM 的一些详细信息,但这似乎有点复杂和不清楚,并且似乎涉及很多手动配置。我很失望也很惊讶 Ubuntu 16 没有用于 fastCGI 模式或其他东西的包选项。

我尝试使用 a2enmod将 apache 切换到事件模式,当我尝试启动 apache 备份时,出现错误:

Apache 正在运行线程 MPM,但您的 PHP 模块未编译为线程安全的。你需要重新编译PHP

无论如何,我想知道是否有人有一些最小的分步说明,以通过尽可能依赖软件包安装程序在带有 PHP 7.0Ubuntu 16 上运行 fastCGI 模式我目前正在查看很多解释不清、含糊不清的说明,而且我担心会因错误的决定而破坏我的生产环境。

此外,有人应该添加 mpm-event 作为标签选项。这就是#apache IRC 人推荐的。

S. *_*Imp 17

ezra-s提出了一个很好的方法,但它不包括一些可能会让依赖包管理器的人感到困惑的细节。注意:我不确定这些步骤是否准确。如果有人遇到麻烦或看到问题,请告诉我,我会更新这篇文章。

首先,在撰写本文时,如果您想安装 PHP,Ubuntu 的 apache2 软件包坚持使用 prefork。但是,不要绝望,因为您仍然可以使用软件包安装程序来安装和更新 PHPapache2,并且仍然可以使用Apache wiki 推荐的PHP-FPM在事件模式下使用Apache 进行配置,并在High-使用 mod_proxy_fcgi 和 php-fpm 在 apache httpd 2.4.x 上性能 PHP。基本思想是 apache2 和 PHP-FPM 通过套接字进行通信,而不是作为 Apache 模块运行的 PHP。

1)删除或禁用Apache PHP模块

因为Ubuntu的包在安装PHP的时候坚持要prefork Apache,所以我们必须把它们分开。我通过使用 apt 卸载 libapache2-mod-php7.0 来做到这一点,因为我不再需要这个包:

sudo apt-get remove libapache2-mod-php7.0
Run Code Online (Sandbox Code Playgroud)

或者,您可以改为禁用 php7.0 Apache 模块,但这不会从您的系统中删除 apt 包,这会留下烦人的系统碎片。

sudo a2dismod php7.0
Run Code Online (Sandbox Code Playgroud)

2)将Apache切换到事件模式并启用fcgid

我相信这些命令应该可以解决问题:

sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo a2enmod proxy_fcgi
Run Code Online (Sandbox Code Playgroud)

3) 安装 PHP-FPM

我已经安装了 PHP 7 及其各种模块,所以我只需使用以下命令安装 PHP-FPM:

sudo apt-get install php7.0-fpm
Run Code Online (Sandbox Code Playgroud)

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/
Run Code Online (Sandbox Code Playgroud)

重要这指示 Apache 使用 PHP-FPRM 处理 PHP 文件请求,并且该指令中的路径(/run/php/php7.0-fpm.sock)必须与文件/etc/php 中listen指令指定的路径匹配/7.0/fpm/pool.d/www.conf

5)重启Apache

sudo service apache2 restart
Run Code Online (Sandbox Code Playgroud)

要检查事件模式是否已启用,请使用以下命令:

sudo apachectl -V
Run Code Online (Sandbox Code Playgroud)

在输出中,您应该看到:

Server MPM:     event
Run Code Online (Sandbox Code Playgroud)

尝试创建一个 phpinfo 页面并在浏览器中访问它。您应该Server API: FPM/FastCGI在输出中看到。

  • 我建议不要使用 ProxyPassMatch ,因为它不允许在目录中使用 .htaccess 。改用它: <FilesMatch \.php$> SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost/" </FilesMatch> (5认同)

ezr*_*a-s 7

为了方便,发行版提供了“mod_php”方法。

而最高效的方式是 apache w/event + mod_proxy_fcgi -> php-fpm。

也许他们应该与时俱进,但是当如此多的框架以一种“即插即用”的方式带有 .htaccess mod_php 配置时,这对他们来说很难。最后,只有管理员负责正确管理和配置他们的站点。

如果您在生产中,我建议您使用测试服务器来练习升级和更改。

关于维基,我更喜欢或建议您使用“处理程序”方法。 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>
Run Code Online (Sandbox Code Playgroud)

编辑:

通过这种方式,您使用哪个 PHP 版本并不重要,因为 Apache 不在乎,它只会将适当的请求反向代理到 php-fpm。

另外,不要忘记卸载 mod_php 以便能够使用 mpm_event。

编辑2:

根据要求,您不需要从 debian/ubuntu 卸载 mod_php 包,Apache 只关心其配置,因此卸载模块即可。