问:
目前负责维护一个访问量较大的电商平台,核心业务逻辑主要基于 PHP 实现。随着用户量的持续增长,日常峰值并发量不断提升,系统偶尔会出现响应变慢、甚至接口超时的情况。目前已经尝试过增加服务器资源、优化数据库查询、引入 Redis 缓存等常规手段,但效果不尽理想。团队正在思考更深层次的优化方案,比如 PHP-FPM 参数调优、引入 OPcache、Swoole 协程化改造、甚至考虑部分核心服务微服务化。但在这些方案中,如何评估投入产出比,并选择最适合当前业务阶段和团队技术栈的策略,成为了一个难题。希望有实际大规模 PHP 应用优化经验的同行能分享一些实战经验和最佳实践。
答:
opcache可以直接开,对于有大量php文件的项目来说,性能提升很明显。对于普通的tp框架来说,200-400毫秒的加载可以缩短到40毫秒左右。此举主要解决php初始化问题,并且基本没有升级负担。
启用缓存,但缓存是redis还是文件缓存不是核心,而是数据查询逻辑。核心问题是哪些数据需要缓存,哪些数据走全局变量。尤其排查循环中的数据查询,如果出现重复的查询,但缓存结果存放到redis,仍然不好,静态属性和全局变量才是最快的。我曾经有个统计方法,要在循环中查询对应模板配置,一开始放到缓存中,但还不够快,压力只是从mysql转移到redis,直接存放到静态属性让接口从8秒减到1秒左右。(属于代码逻辑优化)
文件和数据分离,文件的上传和下载不要和服务器走同一个流量,尽量实现客户端直传三方。有个隐蔽的情况是类似头像获取的必须走服务器的话,看看注册和登录机制是否需要优化。我之前营销活动遇到过这个情况,最终发现是登录机制不好导致一直在每次都要重新获取头像,而这个过程很慢。
如果不是特定接口慢而是整体变慢,排查是宽带瓶颈还是cpu内存瓶颈。PHP的高并发模型的缺陷在于每个请求都是一套完整的程序,假如一个接口的运行要占用20M(一般基础tp的占用量),那么同时100个请求就要2G内存了。不改架构的情况下,就是优化程序加载(开启opcache)和让接口快速完成,不要有cpu空转的情况,比如阻塞io,等待锁。对于java和swoole这种架构,高并发模型是不会每个请求都初始化程序的,而是运行时就初始化好,当请求来了就异步处理请求就好了,因此不存在优化程序加载这一步,但阻塞io仍然在,需要优化,甚至更容易阻塞。(不是所有阻塞操作都值得优化)。
确定是mysql瓶颈还是php瓶颈。如果是php瓶颈的话,动态扩容最省事,简单写个脚本实现自动启动按量付费机器,再定时关掉。
注意微服务化的要求不比动态扩容低。如果不能动态扩容,那么微服务话对php毫无意义,(java的微服务化,即便不作动态扩容,也能解决重启时间长的问题,避免整个系统重启导致不可用,但php天生不存在这个问题。)
目前不清楚具体情况,到底瓶颈在哪里,感觉还没尝试过opcache,这导致每次请求php程序都会加载大量文件,高并发时容易成为瓶颈,可能开启了之后能直接解决问题。再次推荐。
尝试php8.0,如果程序支持php7,那么大概率8.0是兼容的,开启opcache后能获得更极致的加载,比如我第一段的例子中,使用8.0的话,比40毫秒还要快,在25-40毫秒之间。
一个情况可以注意一下,开启opcache之后,压力测试下反而会产生一点失败的请求(不开启的时候没有失败请求),但我认为这是因为开启后遇到cpu和内存瓶颈导致,在开启前加载过程根本不会对cpu产生压力,所以没有失败。
原文标题: 大规模 PHP 应用在高并发下如何进行性能优化?
原文地址: https://phpreturn.com/index/a68e2128a5ebfe.html
原文平台: PHP武器库
版权声明: 本文由phpreturn.com(PHP武器库官网)原创和首发,所有权利归phpreturn(PHP武器库)所有,本站允许任何形式的转载/引用文章,但必须同时注明出处。