网站首页 文章专栏

记录网站频现502,大量php-fpm子进程,CPU占用高:xmlrpc.php被刷

Mr.hao
Mr.hao HSBLOG 2020-09-22 16:08:20

出现问题:

1.WordPress博客站点,频现502,再次刷新浏览正常
2.访问页面巨卡,响应时间很慢

运行环境:

centos7.0+php5.5.38+wordpress4.7.4

排查:

1、 top 查看进程情况,发现大量php-fpm进程数量,占用资源太多

第三行,cpu状态信息:
 us — 用户空间占用CPU的百分比;
 sy — 内核空间占用CPU的百分比;
 ni — 改变过优先级的进程占用CPU的百分比;
 id — 空闲CPU百分比;
 wa — IO等待占用CPU的百分比;
 hi — 硬中断(Hardware IRQ)占用CPU的百分比;
 si — 软中断(Software Interrupts)占用CPU的百分比。
第四行,内存状态:
 total — 物理内存总量;
 used — 使用中的内存总量;
 free — 空闲内存总量;
 buffers — 缓存的内存量 。

2、查看 nginx 网站日志 tail -f access.log 和 tail -f access.log,发现有短时大量post访问,导致nginx返回 499 或者 502

499:表示客户端主动关闭了连接[服务器返回http头之前,客户端就提前关闭了http连接]or[服务器端处理的时间过长,客户端“不耐烦”了]
502:资源不够,服务端php处理有问题,未正常响应请求,在nginx+php中一般找,进程管理器fastcgi,即php-fpm可能出现的问题

错误日志中发现:
connect() to unix:/tmp/php-fpm.sock failed (11: Resource temporarily unavailable) while connecting to upstream

3、查看一下当前 fastcgi 进程个数

netstat -napo |grep "php-fpm" | wc -l

4、查看已经有多少个php-cgi进程用来处理tcp请求

netstat -anp|grep "php-fpm"|grep "tcp"|grep "pool"|wc -l

尝试方案 A:【调整 php 和 nginx 配置参数】

1. 调整进程管理器 php-fpm 配置参数,控制进程数量

max_children 该参数指明了每个children最多处理多少个请求后便会被关闭。
在大量处理请求下,如果该值设置过小会导致children频繁的自杀和建立而浪费大量时间,
若所有的children差不多都在这个时候自杀,则重建前将没有children响应请求,
于是出现502,可以将该值设置大一些或者是0[无限]。
1)php.ini 中 memory_limit 内存限制调大一些
2)php-fpm 参数调整
pm 表示进程数的控制方式,分别为 static (静态)和 dynamic (动态)。
pm = dynamic 如何控制子进程,选项有static和dynamic
pm.max_children:静态方式下开启的php-fpm进程数量
pm.max_requests:php-fpm子进程能处理的最大请求数
pm.start_servers:动态方式下的起始php-fpm进程数量
pm.min_spare_servers:动态方式下的最小php-fpm进程数
pm.max_spare_servers:动态方式下的最大php-fpm进程数量
request_terminate_timeout :超时时间设置
3)php.ini 中 max_execution_time :fast-cgi的执行脚本时间

2. 调整nginx配置文件

worker_processes auto # woker进程数,一般设置为CPU核数*线程数
fastcgi_connect_timeout 300
fastcgi_send_timeout 300
fastcgi_read_timeout  300

重启 nginx 和 php-fpm ,发现并无卵用!


尝试方案 B:【修改 nginx 和 php-fpm 通信方式】

unix socket 不走网络,可以提高Nginx和php-fpm通信性能,但在高并发时会不稳定
Nginx会频繁报错:
connect() to unix:/dev/shm/php-fcgi.sock failed (Resource temporarily unavailable) while connecting to upstream

sock方式:fastcgi_pass unix:/tmp/php-cgi.sock;
http方式:fastcgi_pass 127.0.0.1:9000;

1. 修改 php-fpm.conf : 

将 listen = /tmp/php-cgi.sock 修改为 listen = 127.0.0.1:9000


2. 修改 nginx.conf :

将 fastcgi_pass = unix:/tmp/php-cgi.sock 修改为 fastcgi_pass = 127.0.0.1:9000

重启 nginx 和 php-fpm 后,top查看 php-fpm进程数量正常,502 和 499 未出现


尝试方案 C:【针对DDOS攻击】

1. 查看nginx日志,分析ip,屏蔽ip

1)在 nginx.conf 同级目录新建 blockips.conf
2)编辑blockips.conf 加入屏蔽规则
deny 1.2.3.4;    //屏蔽单个ip
deny 123.0.0.0/8;  // 封 123.0.0.1~123.255.255.254 这个段的ip
deny 123.1.0.0/16;  // 封 123.1.0.1~123.1.255.254 这个段的ip
deny 123.1.1.0/24;  // 封 123.1.1.1~123.1.1.254 这个段的ip
3) 在nginx.conf 中引入blockips.conf
  include blockips.conf;

也可直接在 centos 启用防火墙,增加 iptables,屏蔽规则ip,具体配置 => https://hsblogs.com/docs.html

2.修改nginx虚拟主机配置文件:直接屏蔽掉文件路径

3. Wordpress的xmlrpc漏洞,直接修改wp主题文件中【/wp-content/主题名/functions.php】 放到文件最下方

//禁用XML-RPC接口
add_filter('xmlrpc_enabled', '__return_false');
//or
//禁用XML-RPC的pingback接口
add_filter( 'xmlrpc_methods', 'remove_xmlrpc_pingback_ping' );
function remove_xmlrpc_pingback_ping( $methods ){
    unset( $methods['pingback.ping'] );
    return $methods;
}

重启 nginx 和 php-fpm,再次查看top进程,发现进程数量 、cpu、内存占用 都恢复正常


关于【http slow post慢速攻击】:




注:参考文章

1. 浅谈TCP协议与DDOS
2. 无连接和面向连接协议的区别 
3. Nginx和PHP-FPM使用tcp socket还是unix socket?   
4. https://static.kancloud.cn/wangking/linux/1209652
5. LNMP的工作原理
6. 常见的DDOS攻击及原理-应用层

沟通交流
  • 消灭零回复