关于对php-fpm的压力测试

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
性能测试 PTS,5000VUM额度
简介: 以前公司网站架构一直都是nginx+apache,因为apache市场占有率还是很大,稳定性也很好,加上版本已经升级到2.4,因为公司业务访问量不是很大,所以一直没考虑更换,但最近因为测试人员用jmeter连续测压测3轮200并发反馈很多报错,而且响应时间也比较久,最终想试试php-fpm替代apache看看效果如何。

以前公司网站架构一直都是nginx+apache,因为apache市场占有率还是很大的,稳定性也一直很好,加上如今版本已经升级到2.4,安全和性能方面都有提升,因为公司业务访问量不是太大,所以一直也没计划更换,但最近因为测试人员用jmeter连续测压测3轮200并发(压测都是动态请求)反馈很多报错,查了一个apache的错误日子,报内存不够,8G的内存应该不会这么差吧!而且响应时间在我看来也比较久,其中当然也有一些代码的原因,这里我只想从运维的角度去试试php-fpm替代apache看看效果如何?其实说白了最后主要就是看响应时间和错误率。
1、首先保存单台apache(kvm运行,apache还是优化了的)的压测数据(总共29个接口)
image
image
再看看apache优化之后的参数
image
2、因为这次在测试swarm mode,所以正好通过swarm部署php-fpm环境,单台docker容器运行,代码一样,php.ini版本和参数基本都一样,下面看一组www.conf基本没有做任何优化的压测结果
image
分析nginx日志和压测结果看到很多500错误,当时我就纳闷了,php-fpm不至于这么弱吧?不是高并发的网站都是使用php-fpm嘛!当时查了一下php-fpm日志报错如下:
Failed to connect to redis: Cannot assign requested address
经排查是php-fpm服务端连接redis有问题,php-fpm频繁的连redis服务器,由于每次连接都在很短的时间内结束,导致产生太多的TIME_WAIT不释放,以至于用完了可用的默认端口号,所以新的连接没办法绑定端口,说明是php-fpm服务端的问题,而不是redis服务器端的问题。通过netstat的确也看到很多TIME_WAIT状态的连接,所以我们需要简单的做一些内核参数优化。
解决办法:
在docker容器所在的宿主机上执行命令
sysctl -w net.ipv4.tcp_timestamps=1 开启对于TCP时间戳的支持,若该项设置为0,则下面一项设置不起作用
sysctl -w net.ipv4.tcp_tw_recycle=1 表示开启TCP连接中TIME-WAIT sockets的快速回收
再次压测已经看到没有500错误,也就是错误率为0,响应时间和apache不分上下,有的接口高,有的接口低,虽然相差不是很大,但这只是php-fpm参数没有优化压测的结果,已经让我感到一丝丝的欣慰啦!
下面是响应时间的截图对比
image
关于php-fpm优化压测的细节和结论
对于www.conf优化并不是设置的进程数量越高越好,如果设置不合适就会导致系统负载很高,也需要根据压测结果和php-fpm报的错误日志需要不断的调试和压测,提一句还是看结果最重要。下面是我压测过程中日志警告的截图
image
image
下面是我调优的参数,系统负载最高都能到30左右。其实还是建议大家根据实际的硬件配置优化,这里我限制了CPU能使用宿主机的400%,内存8G。一般一个php-fpm占用20M内存左右。
www.conf主要优化参数:
php-fpm工作模式选为默认,如果内存很大可以设置为static,但是设置static后只有pm.max_children一个参数有效(切记切记),设置dynamic是所有参数都有效,另外还有一种ondemand管理方式,这里不多议。
www.conf文件优化如下:
pm = dynamic
子进程最大数
pm.max_children = 50
优化后为100,因为并发是200,持续3轮,理论上一般并发多少这个值就设置多少,然后相对于的增加一点点即可!这样php-fpm日志就不会报最大子进程数不够的警告。比如这里我压测的时候也设置了300,观察了php-fpm最多250个左右子进程,但是设置为300的响应时间还没有100好看。
初始子进程数
pm.start_servers = 5
优化后为50
最小空闲子进程数
pm.min_spare_servers = 5
优化后为50
最大空闲子进程数
pm.max_spare_servers = 35
优化后为70
每个子进程重生之前服务的请求数
pm.max_requests = 500
优化后为4000
单个请求的超时中止时间
request_terminate_timeout = 0
优化后为10,如果后端处理时间大于10秒就会报出502,这也是为了很好释放资源的优化,设置的时候一定要注意。
文件打开描述符的rlimit限制
rlimit_files = 1024
优化后为8192
再次压测结果响应时间php-fpm还不如apache好看,甚至比apache弱,这一点确实让我很惊讶,关于www.conf配置文件我优化了N次,但是压测结果在处理时间都没让我很满意,虽然在错误率这方面优势很明显,难道只是我一厢情愿的认为php-fpm比apache强很多吗?难道对于我这种压测标准默认的配置就是最优的吗?这里结果是单台php-fpm只是在错误率上面有明显的优势,处理时间上如果优化不好会比apache弱或者不分上下?以后准备抛除所有压测php测试页面进行对比看看!
个人疑问:
1、最大子进程数设置很大,系统负载偶尔会飙升很高,甚至有时候能到一百多,这里让我很不解。
2、当top看到系统负载不高,而vmstat查看r列会造成cpu严重不足,也能到一百多,又让我真心有点不理解了。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
原生php实现列表接口+分页接口+排序接口组合使用+包括测试数据(不加任何封装)
原生php实现列表接口+分页接口+排序接口组合使用+包括测试数据(不加任何封装)
原生php实现列表接口+分页接口+排序接口组合使用+包括测试数据(不加任何封装)
|
28天前
|
测试技术 PHP 开发工具
php性能监测模块XHProf安装与测试
【10月更文挑战第13天】php性能监测模块XHProf安装与测试
28 0
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
44 2
|
2月前
|
设计模式 人工智能 算法
PHP中的设计模式:策略模式的深入解析与实践软件测试中的人工智能革命:提升效率与准确性的新篇章
在PHP开发中,理解并运用设计模式是提升代码质量和可维护性的重要途径。本文聚焦于策略模式(Strategy Pattern),一种行为型设计模式,它允许在运行时选择算法或业务规则。通过本文,我们将深入探讨策略模式的定义、结构、使用场景以及如何在PHP项目中有效地实现和利用策略模式。不同于性能优化等技术性摘要,本文着重于提供对策略模式全面而实用的理解,助力开发者编写出更加灵活和可扩展的应用程序。 本文深入探讨了人工智能在软件测试领域的应用,揭示了其如何显著提高测试过程的效率和准确性。通过实际案例分析,展示了AI技术在自动化测试、缺陷检测及结果分析中的关键作用,并讨论了实施AI测试策略时面临的挑
22 3
|
4月前
|
测试技术 PHP 开发者
原生php单元测试示例
通过上面的示例,我们可以看到,即使在缺乏专门测试框架的情况下,使用原生PHP代码进行基本的单元测试也是完全可行的。当然,对于更复杂的项目,利用像PHPUnit这样的专业工具将带来更多的便利和高级功能。不过,理解单元测试的基本概念和能够手工编写测试是每个PHP开发者的宝贵技能。
36 4
|
4月前
|
测试技术 PHP 开发者
原生php单元测试示例
通过上面的示例,我们可以看到,即使在缺乏专门测试框架的情况下,使用原生PHP代码进行基本的单元测试也是完全可行的。当然,对于更复杂的项目,利用像PHPUnit这样的专业工具将带来更多的便利和高级功能。不过,理解单元测试的基本概念和能够手工编写测试是每个PHP开发者的宝贵技能。
21 1
|
4月前
|
数据库
基于PHP+MYSQL开发制作的趣味测试网站源码
基于PHP+MYSQL开发制作的趣味测试网站源码。可在后台提前设置好缘分, 自己手动在数据库里修改数据,数据库里有就会优先查询数据库的信息, 没设置的话第一次查询缘分都是非常好的 95-99,第二次查就比较差 , 所以如果要你女朋友查询你的名字觉得很好 那就得是她第一反应是查和你的缘分, 如果查的是别人,那不好意思,第二个可能是你。
67 3
|
4月前
|
测试技术 PHP 开发者
原生php单元测试示例
通过上面的示例,我们可以看到,即使在缺乏专门测试框架的情况下,使用原生PHP代码进行基本的单元测试也是完全可行的。当然,对于更复杂的项目,利用像PHPUnit这样的专业工具将带来更多的便利和高级功能。不过,理解单元测试的基本概念和能够手工编写测试是每个PHP开发者的宝贵技能。
25 0
|
PHP 数据库
对PHP源码的测试
对PHP源码的测试