Ubuntu 14.04系统上使用Apache2.4.10+PHP5+FastCGI的WordPress网站大量php5-cgi defunct引起网站访问异常缓慢

最近网站访问异常缓慢,网站响应时间明显延迟很多,观察系统的处理器占用,一点都不高,带宽也在合理范围之内,因此分析 Apache-2.4.10的错误日志

发现大量的出现

如下图:

感觉很奇怪,于是看了一下 php相关的进程,执行命令

执行结果如下图:

发现大量的 php5-cgi进程处于 defunct状态(僵尸状态),导致达到了进程数量的限制上限,无法继续提供服务。

但是上面的日志,是已经出现问题的时候的日志,既然进程不足了,自然无法提供服务了,继续向上追踪,发现大量的进程崩溃日志

感觉很奇怪,最初以为是由于调整 Apache-2.4.10服务器,多次在正常运行中重启服务器,导致正在服务的 php5-cgi进程变成了僵尸进程。但是重启服务器之后,过了几天后,问题依旧发生了。

于是网上搜索了一下,感觉应该更像是 PHP-CGI进程本身存在内存泄漏问题,导致进程长时间执行之后,由于资源开销问题导致进程崩溃。

目前我的服务器上启用的是 Apache2Event MPM模块,查看其中的配置文件:

可以看到里面的内容如下:

发现,设置 MaxConnectionsPerChild参数为0,根据 Apache MPM Common Directives 里面的介绍,这个参数的作用就是一个进程处理多少个请求后就退出。而如果设置了 0 则代表,除非出现了异常,否则进程会一直存在。这样的话,一旦资源泄漏,进程就会各种异常了。因此需要设置一下这个参数,一般这个参数设置为 1000- 5000左右,根据实际情况自己调整一下参数。

注意一下这个介绍的最后一句话,讲的就是这个参数可以修正资源泄漏问题,如下:

修改参数后,需要重启服务生效。

按照上面的方法实现后,过了一个礼拜后,这个现象再次发生了。

观察了一下 Apache2当前已经启用的模块

发现,由于是从 Apache2.2升级到的 Apache2.4,或许是某次的配置,导致 fastcgifcgi两个模块同时被启用了。

是不是两个相同功能的模块同时启用导致功能冲突了呢?

先尝试禁用 fastcgi(这个模块已经被 fcgi替换了).

目前看来,问题依旧发生了!!!

查看 Apache2中的 FastCGI的配置信息

可以看到如下内容

其中的 AddHandler中的 .php引起了注意,因为在日志中出现问题之前一直会出现如下的错误日志:

而这个配置项是从 Ubuntu 12.04中手工引入的,我们尝试去掉这个。另外,可以看到

也就是 FastCGI的最大进程数是被设置成了 10,但是,我这边限制 PHP-FPM的最大进程数为 5,是不是 FastCGI的进程数如果大于 PHP-FPM能够提供服务的数量的时候,会导致 FastCGI进程出现僵尸状态呢? 是不是这个原因导致的呢? 于是修改后的结果如下:

经过这几天的观察,貌似现象不再出现了,这个应该是 Apache 2.4版本引入的 BUG,以前的配置的 Apache 2.2版本上是没有任何问题的,究竟原因是 mod_fcgid无法处理 .php格式的脚本导致,还是由于 mod_fcgid进程数高于 php-fpm的进程数导致 mod_fcgid进程长时间无法获取到可用的 php-fpm连接,导致进程被饿死,这个暂时不详细追究了。

今天在修改配置的时候,由于配置错误,导致 PHP-FPM服务无法正常启动,但是整个服务器竟然一直可以正常访问,那么结论就是 Apache 2.4在当前的配置下,根本就没有使用 PHP-FPM模式进行通信,而是使用标准的 FastCGI的方式调度的。
于是网上搜索半天,结合自己的尝试,找到了根本原因:

上面的配置在 Apache 2.2版本上是不影响后面启用的 PHP-FPM配置的,对于 PHP的请求,最终都是定向到 PHP-FPM的。但是相同的配置在 Apache 2.4上面,则被定向到了 FastCGI上面。因此修改方式如下(至少要高于2.4.10,否则配置无效):

至此,应该才是从根本上解决了服务器上的问题。

开始的时候忽略了一个基础的问题,那就是 php5-cgiphp5-fpm进程本身就不应该同时存在,如果服务器使用 php5-fpm,那么 php5-cgi的进程就不应该被调用,这个问题没有重视,导致了整个问题分析时间冗长,反复。

本质上是服务器的配置错误导致问题。

Ubuntu 14.04使用OpCache提升PHP5.5+程序性能

概述


PHP 5.5以后内建了 OpCache, OpCache的加速原理是把编译后的 bytecode存储在内存里面, 避免重复编译 PHP 所造成的资源浪费. Ubuntu 14.04默认自带 PHP 5.5.9,已经集成了这个功能。但是默认是不启用的。

启用


修改 php.ini 文件

在文件最后面加入:

重启服务器

效果


加速效果极端明显,强烈建议启用这个功能。

Ubuntu 14.04(64位)编译安装PHP7.0.5后编译安装libssh2-php

在使用Ubuntu 14.04(64位)源码编译安装PHP7并配置Apache2支持之后,无法直接通过命令安装 libssh2-php,因此需要手工编译安装。

1.安装编译 libssh2-php需要的依赖库

2.下载 libssh2-php的源代码

3.解压缩文件

4.切换到目录

5.使用 phpize配置插件编译环境

6.配置编译环境

7.编译并安装

执行之后,文件被安装到了 /opt/php-7.0.5/lib/php/extensions/no-debug-zts-20151012目录下面。

8.配置 php.ini加载插件

找到如下内容

在最下面增加

9.重启 Apache2加载动态模块

Ubuntu 14.04(64位)源码编译安装PHP7并配置Apache2支持

下载PHP7源代码


解压缩到当前目录


安装编译需要的依赖


安装 libxml2-dev

安装 gcc

安装依赖的库

安装 apache2-dev,否则无法指定 --with-apxs2=/usr/bin/apxs来生成 libphp7.so

切换到编译目录

配置并编译


配置开启 php-fpm支持,开启多线程支持 --enable-maintainer-zts,否则无法使用 Apache2Event MPM功能。

配置并安装PHP7


拷贝PHP7的配置文件


设置PHP7的配置文件 php.ini


PHP7已经默认加载 opcache.so了,因此不需要声明 zend_extension=opcache.so.

启用 Apache2PHP7模块


启用 Apache2Event模块


参考链接


ubuntu 14.04上源码编译安装php7
How to install PHP 7 as PHP-FPM & FastCGI for ISPConfig 3 on Debian 8 (Jessie)

Ubuntu 14.04 关闭PHP服务器上返回的X-Powered-By信息

最近在分析网站性能的时候,发现服务器返回了" X-Powered-By"字段,这个字段中携带了PHP的版本号,系统的版本号。如下图:
X-Powered-By

而出于安全考虑,这两个信息是不应该被返回给客户端的。

Ubuntu 14.04下服务器禁止返回" X-Powered-By"的设置如下:
对于使用 Apache2内置PHP的服务器,则需要修改 Apache2对应目录下的配置文件

对于使用 PHP-FPM调度的服务器,则需要同时修改 PHP-FPM, FastCGI对应目录下的配置文件

找到

把其中的 expose_php = On调整为: expose_php = Off,调整后的结果如下:

接下来,重启 Apache2

重启 PHP-FPM,如果配置了的话。

再次请求服务器后,发现" X-Powered-By"已经不会再返回了。

X-Powered-By-Off

PHP中$_SERVER中的SERVER_NAME和HTTP_HOST的区别

最近在开发站群软件,用到了根据访问域名判断子站点的相关问题。PHP获取当前域名有两个变量 HTTP_HOST 和 SERVER_NAME,我想知道两者的区别以及哪个更加可靠。

首先我想说,百度上那些转来转去的文章都是扯淡!
有说相同的,有说不同的,都没说明原因,没经过验证就互相转来转去的,浪费观众时间。

下面说说本人经过亲自验证 + 查阅官方文档 + 官方BUG列表 + 官方邮件列表 + sitepoint + webmasterworld + google的总结:

相同点:
当满足以下三个条件时,两者会输出相同信息。
1. 服务器为80端口
2. apache的conf中ServerName设置正确
3. HTTP/1.1协议规范

不同点:
1. 通常情况:
_SERVER["HTTP_HOST"] 在HTTP/1.1协议规范下,会根据客户端的HTTP请求输出信息。
_SERVER["SERVER_NAME"] 默认情况下直接输出apache的配置文件httpd.conf中的ServerName值。

2. 当服务器为非80端口时:
_SERVER["HTTP_HOST"] 会输出端口号,例如:mobibrw.com:8080
_SERVER["SERVER_NAME"] 会直接输出ServerName值
因此在这种情况下,可以理解为:HTTP_HOST = SERVER_NAME : SERVER_PORT

3. 当配置文件httpd.conf中的ServerName与HTTP/1.0请求的域名不一致时:
httpd.conf配置如下:

客户端访问域名www.mobibrw.com
_SERVER["HTTP_HOST"] 输出 www.mobibrw.com
_SERVER["SERVER_NAME"] 输出 mobibrw.com

所以,在实际程序中,应尽量使用_SERVER["HTTP_HOST"] ,比较保险和可靠。

参考链接:
php $_SERVER中的SERVER_NAME 和HTTP_HOST的区别

PHP 如何获取当前的域名

原文链接:PHP 如何获取当前的域名

Ubuntu 12.04 Apache2 安装 PHP-FPM 增强 PHP5-CGI 的功能

FPM(FastCGI 进程管理器)用于替换 PHP FastCGI 的大部分附加功能,对于高负载网站是非常有用的。

它的功能包括:

  • 支持平滑停止/启动的高级进程管理功能;
  • 可以工作于不同的 uid/gid/chroot 环境下,并监听不同的端口和使用不同的 php.ini 配置文件(可取代 safe_mode 的设置);
  • stdout 和 stderr 日志记录;
  • 在发生意外情况的时候能够重新启动并缓存被破坏的 opcode;
  • 文件上传优化支持;
  • "慢日志" - 记录脚本(不仅记录文件名,还记录 PHP backtrace 信息,可以使用 ptrace或者类似工具读取和分析远程进程的运行数据)运行所导致的异常缓慢;
  • fastcgi_finish_request() - 特殊功能:用于在请求完成和刷新数据后,继续在后台执行耗时的工作(录入视频转换、统计处理等);
  • 动态/静态子进程产生;
  • 基本 SAPI 运行状态信息(类似Apache的 mod_status);
  • 基于 php.ini 的配置文件。

1.安装PHP-FPM 支持模块

2.重启 Apache2

这时候使用

可以看到,进程中大约出现四五个 php5-fpm 进程。

注意 php5-cgi 进程的最大数量可以在 /etc/apache2/mods-available/fcgid.conf 中配置 DefaultMaxClassProcessCount 来限制。

ubuntu下安装Apache+PHP+Mysql

步骤一,安装apache2

安装完成。
运行如下命令重启下:

在浏览器里输入http://localhost或者是http://127.0.0.1,如果看到了It works!,那就说明Apache就成功的安装了,Apache的默认安装,会在/var下建立一个名为www的目录,这个就是Web目录了,所有要能过浏览器访问的Web文件都要放到这个目录里。

步骤二 ,安装php:

此外,建议安装扩展php5-gd php5-mysql,安装方式同上.

安装完后,我们要重新启动Apache,让它加载PHP模块:

接下来,我们就在Web目录下面新建一个test.php文件来测试PHP是否能正常的运行,命令:

然后输入:

接着保存文件,在浏览器里输入http://127.0.0.1/test.php,如果在网页中显示hello,world!!,那就说明PHP已经正常运行了。

步骤三,安装mysql数据库:

apt-get程序会自动下载安装最新的mysql版本。在安装的最后,它会要求里输入root的密码,注意,这里的root密码可不是Ubuntu的root密码啊,是你要给MySQL设定的root密码。

步骤四,安装phpmyadmin-Mysql数据库管理

phpmyadmin设置:

在安装过程中会要求选择Web server:apache2或lighttpd,使用空格键选定apache2,按tab键然后确定。然后会要求输入设置的Mysql数据库密码连接密码Password of the database’s administrative user。

然后将phpmyadmin与apache2建立连接,以我的为例:www目录在/var/www,phpmyadmin在/usr/share /phpmyadmin目录,所以就用命令:

建立链接。

phpmyadmin测试:在浏览器地址栏中打开http://localhost/phpmyadmin。

以上ALMP的基本组件就安装完毕了,下面我们再来看一些其他的设置:

步骤五,设置Ubuntu文件执行读写权限

LAMP组建安装好之后,PHP网络服务器根目录默认设置是在:/var/www。由于Linux系统的安全性原则,改目录下的文件读写权限是只允许root用户操作的,所以我们不能在www文件夹中新建php文件,也不能修改和删除,必须要先修改/var/www目录的读写权限。在界面管理器中通过右键属性不能修改文件权限,得执行root终端命令:

然后就可以写入html或php文件了。777是linux中的最高权限,表示可读,可写,可执行。