Web经验菜鸟运维

原创经验:解决1G小内存主机由于php-fpm爆满导致的服务不可用问题

AndyX:首先咱买的是华为云小主机,最便宜的那种,所以默认内存只有1GB。其次,由于最近AndyX.Net博客访问量日趋增大(也有部分是来自于搜索引擎的爬虫),网站系统虽然做了缓存优化,但也可能遇到了某些扫描器在使用xmlrpc.php漏洞探测账号。结果就导致了华为云监控疯狂提示网站短暂不可用的状况出现。

andyx0-service_unavailability_caused_by_php-fpm_burst_in_1g_memory.jpg插图

本教程来源于实际情况,本次php-fpm参数优化适用于1GB内存的入门型主机。

若遇到了针对xmlrpc.php的暴力破解,可能也会引发此问题,解决方法请参见本站文章《记一次WordPress优化xmlrpc.php防止暴力破解登陆过程

若遇到数据库Mysql/Mariadb占用内存过大状况,可能也会引发此问题,解决方法请参见文章《浅谈Mariadb/Mysql内存占用的优化方案

 

思路与排查:

已知华为云监控提示了网站短暂不可用是由于内存不足引起的,那么我们就先从内存入手

很艰难的登陆了服务器的Console控制台之后,使用free命令简单查看一下内存:

free   -h

反馈如图,阿西吧,在开启swap情况下剩余可用只有可怜的5.9M了,内存使用99%这必然会导致系统卡死

andyx2-service_unavailability_caused_by_php-fpm_burst_in_1g_memory.png插图(1)

那么接下来另开启一个Console控制台,然后使用top命令查询,打开top之后按键Shift+M进行内存使用排序,此时我们看到有大量的php-fpm进程被启用,并且每个进程平均占用接近30M+(Mysql进程目前看来比较正常先不用管它)

andyx1-service_unavailability_caused_by_php-fpm_burst_in_1g_memory.jpg插图(2)

PS:关于top命令的详细使用方法,可以参见本站文章《top命令详解以及VIRT,RES,SHR,DATA的含义

好吧,那么用ps命令+wc命令数一下php-fpm有21个之多,扣除一个php-fpm主进程之后还有20个子进程

andyx4-service_unavailability_caused_by_php-fpm_burst_in_1g_memory.jpg插图(3)

我们来算一下,大约需要占用600M内存,最对于只有可怜的1GB内存主机确实占的有些多了,所以接下来我们需要修改php-fpm配置文件对其最大子进程数做一个限制。

 

解决方案:

关于php-fpm参数调整的更多信息可以参考《php-fpm参数调优方案

一般php-fpm进程占用20~30m左右的内存就按30m算。如果单独跑php-fpm,动态方式起始值可设置物理内存Mem/30M,由于大家一般Nginx、MySQL都在一台机器上,于是预留一半给它们,即php-fpm最大进程数为$Mem/2/30

由于我是通过remi源安装的php7所以配置文件路径位置不太一样,仅供参考

(请按实际情况调整,若依然有php-pfm内存爆满情况,可适当调低pm.max_数值)

使用vim命令打开php-fpm的配置文件:

vim  /etc/opt/remi/php*/php-fpm.d/www.conf
#本文中CentOS的Remi源安装的php-fpm配置文件位置


vim  /etc/php-fpm.d/www.conf
#CentOS的默认yum源安装的php-fpm配置文件位置


vim  /etc/php/7.*/fpm/pool.d/www.conf
#树莓派标准apt源安装的php-fpm配置文件位置

andyx7-service_unavailability_caused_by_php-fpm_burst_in_1g_memory_7.jpg插图(4)

由于我使用的是动态模式,所以将参数修改为

pm = dynamic
#模式为动态模式
#pm参数指定了进程管理方式,有两种可供选择:static或dynamic,从字面意思不难理解,为静态或动态方式。如果是静态方式,那么在php-fpm启动的时候就创建了指定数目的进程,
在运行过程中不会再有变化(并不是真的就永远不变);而动态的则在运行过程中动态调整,当然并不是无限制的创建新进程,受pm.max_spare_servers参数影响;动态适合小内存机器,
灵活分配进程,省内存。静态适用于大内存机器,动态创建回收进程对服务器资源也是一种消耗

pm.max_children = 16
#static模式下创建的子进程数或dynamic模式下同一时刻允许最大的php-fpm子进程数量

pm.start_servers = 5
#动态方式下的起始php-fpm进程数量

pm.min_spare_servers = 5
#动态方式下服务器空闲时最小php-fpm进程数量

pm.max_spare_servers = 16
#动态方式下服务器空闲时最大php-fpm进程数量

pm.max=requests = 500
#默认500,发送多少个请求后会重启线程,我们需要适当降低这个值,用以让php-fpm自动的释放内存\
#样实际上的内存消耗是max_children*max_requests*每个请求使用内存,根据这个我们可以预估一下内存的使用情况

#----------------------------------------------------
#请按实际情况调整,若依然有php-pfm内存爆满情况,可适当调低pm.max_数值
#----------------------------------------------------

 

:wq保存后实行systemctl命令重载配置文件让其生效(通过remi源安装的php所以服务名不太一样,仅供参考)

systemctl  reload   php7*-php-fpm
#remi源安装的php-fpm服务名称为php7*-php-fpm


systemctl  reload   php-fpm
#普通yum/apt安装的php-fpm服务名为php-fpm

 

 

OK,我们使用free、top命令再看下当前内存以及进程数状态:

andyx5-service_unavailability_caused_by_php-fpm_burst_in_1g_memory.jpg插图(5) andyx6-service_unavailability_caused_by_php-fpm_burst_in_1g_memory.jpg插图(6)

至此问题基本解决。

(END)

若需转载本文,请标注来源与链接:原创内容AndyX.Net版权所有  https://andyx.net/service_unavailability_caused_by_php-fpm_burst_in_1g_memory