从搬家到VPS算起已经一个月了,一直用的apache的prefork模式,但是时不时的apache就来一次崩溃,要不就是mysql崩溃,后来通过看日志发现问题所在,原来是apache在访问量突发的情况下内存溢出,遂不断的去网上找合适的prefork设置参数,不断的调整,最后终于找到了合适的参数
1 2 3 4 5 6 7 |
<IfModule mpm_prefork_module> StartServers 2 MinSpareServers 2 MaxSpareServers 13 MaxClients 14 MaxRequestsPerChild 200 </IfModule> |
在MaxClients=14的时候通过了压力测试,这时候的可用内存Cache+buffers在50M左右,CPU达到了100%,算是极限了。14个进程啊,这就到极限了啊,每个apache2进程都几乎用了100M的内存和10%的cpu啊,网上不是都说一个apache进程就5M么,算下来1G内存轻松80个进程没问题啊,骗人么这不是,而且用了这么多资源,但为什么每次打开网页还是卡得像史一样的慢啊。
最后终于下定决心还是换吧,虽然网上说prefork稳定,但是实在是受不了这么占资源,遂开始了漫长的寻找教程之路,发现网上中文教程都没法看,只能自己寻找英文教程,然后发现可能也是人格特质展现,没有一次顺利走完教程,每次都卡在不同的步骤。最后终于成功的开启了fastcgi的那一刹那,实在是不能用言语表达。
环境
- Apache/2.2.22 (Debian)
- PHP/v5.4.36-0+deb7u3
- Debian 7.8 Wheezy 64-bit
注意
WordPress的网站如果启用了缓存插件,在安装php-fpm前需要先停用相关插件,不然在安装配置完php-fpm之后网站将无法访问。
安装组件
首先,安装
1 |
# apt-get install apache2-mpm-worker |
如果运行的Apache使用的是默认的prefork模式,系统会询问是否移除 apache2-mpm-prefork 和 libapache2-mod-php5 这两个已安装的组件,选择同意
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
root@vps:~# apt-get install apache2-mpm-worker Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: libffi5 libglib2.0-0 libglib2.0-data libgssglue1 libnfsidmap2 libtirpc1 shared-mime-info Use 'apt-get autoremove' to remove them. The following packages will be REMOVED: apache2-mpm-prefork libapache2-mod-php5 The following NEW packages will be installed: apache2-mpm-worker 0 upgraded, 1 newly installed, 2 to remove and 0 not upgraded. Need to get 0 B/2,238 B of archives. After this operation, 9,219 kB disk space will be freed. Do you want to continue [Y/n]? |
之后,安装下面的两个,一个是fastcgi的运行库,另一个就是核心组件php5-fpm了
1 |
apt-get install libapache2-mod-fastcgi php5-fpm |
完成安装之后接下来就来进行相关的设置
设置配置文件
Apache2.4可以直接新建配置文件 "/etc/apache2/conf-available/php5-fpm.conf" ,然后通过命令 a2enconf php5-fpm 来启用配置文件。Apache2.2的话可以直接在 /etc/apache2/apache2.conf 主配置文件的最底下添加,也可以在 /etc/apache2/sites-available 的虚拟主机配置中添加,或者可以直接新建配置文件到 /etc/apache2/conf.d/php5-fpm.conf 都可以达到效果。最后一种是最像Apache2.4的方式,只不过不需要启用,直接就生效。如果虚拟主机比较多,推荐第一种和第三种方式设置配置文件。
在选择一种方式之后,添加参数到文件中
1 2 3 4 5 6 |
<IfModule mod_fastcgi.c> AddHandler php5-fcgi .php Action php5-fcgi /php5-fcgi Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization </IfModule> |
第一行是将php文件交给php5-fcgi来处理,第二行是告诉apache,php5-fcgi在/php5-fcgi目录下,第三行是将所有访问/php5-fcgi的请求转向/usr/lib/cgi-bin/php5-fcgi目录,最后一行是将所有指向/usr/lib/cgi-bin/php5-fcgi的请求都发往php5-fpm的socket监听地址。
为了让Apache执行以上语句,需要开启Apache的fastcgi、action和alias模块,执行如下命令
1 |
a2enmod actions fastcgi alias |
接着为了让上面第四行的命令中从Apache发往php5-fpm的指令能够被接受,还需要在php5-fpm中设置监听地址,打开/etc/php5/fpm/pool.d/www.conf 配置文件,寻找如下字段
1 2 3 4 5 6 7 8 9 |
; The address on which to accept FastCGI requests. ; Valid syntaxes are: ; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on ; a specific port; ; 'port' - to listen on a TCP socket to all addresses on a ; specific port; ; '/path/to/unix/socket' - to listen on a unix socket. ; Note: This value is mandatory. listen = /var/run/php5-fpm.sock |
其中 listen = /var/run/php5-fpm.sock 这句指定了监听的端口,把它改为之前第四句中的相同监听地址。
最后,重新加载apache配置
1 |
service apache2 reload |
创建一个 <?php phpinfo(); ?> 页面,然后访问看看是否Server API已经变成FPM/FastCGI。
一些其他的东西
之前在安装和配置完成php5-fpm之后碰到访问页面直接将php作为文本内容输出,什么数据库用户名密码什么的都直接显示在浏览器上,差点吓死。后来分析是由于安装完成之后没有在apache配置文件中添加对php文件的处理方式,导致apache将php文件当作html静态页面直接输出了。
之后,在apache中添加fastcgi配置后,访问出现500内部错误,查看日志,发现如下条目
1 2 |
(2)No such file or directory: FastCGI: failed to connect to server "/var/www/fastcgi/php5.fastcgi": connect() failed FastCGI: incomplete headers (0 bytes) received from server "/var/www/fastcgi/php5.fastcgi" |
为了解决这个问题还去/var/www目录下手动建了fastcgi/php5.fastcgi这两个文件夹,还傻傻的去改了用户权限。后来才发现其实根本不需要的,读懂上面的配置文件就会发现,其实这个监听地址根本就是不需要实际存在的,是一个虚拟的地址,目的只不过是给linux的socket监听一个地址而已。只要跟php5-fpm配置文件中的监听端口一致就可以了,上面的错误信息说明apache已经识别出了php文件,并转发给php5-fpm,但是php5-fpm没有踩它,没有给响应,说明要不就是php5-fpm的配置有问题,要不就是apache发送过去的方式有问题php5-fpm不能识别。最后修改了apache的配置文件并reload后好了。
之后又发现网站可以访问了,但是只能访问主页,其它页面都显示为空白,查看日志,发现如下错误信息
1 2 |
(104)Connection reset by peer: FastCGI: comm with server "/usr/lib/cgi-bin/php5-fcgi" aborted: read failed, referer: http://blog.minirplus.com/3585 FastCGI: incomplete headers (0 bytes) received from server "/usr/lib/cgi-bin/php5-fcgi", referer: http://blog.minirplus.com/3585 |
觉得可能是伪静态的问题,网上找了下,发现不是伪静态的问题,很可能跟缓存插件有关,因为网站已经不能访问,遂只能登陆ftp把插件文件夹删除,删除之后网站就可以正常访问了。
然后有一个虚拟主机在主机配置文件中写入了全局伪静态,将所有访问请求发送到index.php,在切换到php5-fpm之后就无法访问,并且显示500内部错误。解决方法是将apache虚拟主机配置文件中的伪静态删除,在网站更目录下新建.htaccess文件,并且将伪静态规则写入。分析可能是之前规则写的有问题。
最后,切记一定要在service apache2 stop下进行设置,不然一旦设置不好,数据库用户名密码就很容易从浏览器直接访问到。
参考
https://www.digitalocean.com/community/questions/apache-2-4-with-php5-fpm
配置status和ping页面
按照上面的配置完成之后,php-fpm还有两个额外的观察页面,可以查看php-fpm的运行状态
打开 /etc/php5/fpm/pool.d/www.conf 配置文件,找到下面两行,将前面的注释取消
1 2 3 |
; pm.status_path = /status ... ; ping.path = /ping |
然后打开 /etc/apache2/sites-available 下需要访问这两个页面的虚拟主机的配置文件,加上下面高亮的语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<VirtualHost *:80> DocumentRoot ... ServerName yourdomain.com LogLevel warn ErrorLog ... CustomLog ... ServerSignature Off <Directory /var/www/... > Options -Indexes </Directory> <Directory /var/www/... > Order allow,deny Deny from all </Directory> <LocationMatch "/(ping|status)"> SetHandler php5-fcgi Action php5-fcgi /php5-fcgi virtual </LocationMatch> </VirtualHost> |
接着就可以通过 yourdomain.com/status 来访问php-mps的状态页面了。
There are no comments yet