Laravel 项目深度优化过程
简述
公司的系统是面向商户营销的CRM系统,采用的是saas模式而非独立部署,用户表200W,日活3W,日增长5000+,每天的请求量总量目前是200多W次,其中服务端的请求量主要来自前端API请求+商户ERP数据同歩+微信事件回调。以下均在抛去系统设计的问题不讨论,小公司的产品活下去才是第一要素,只能现有的情况下尽量优化,一步步摸着石头过河。
以下为2019年的方案,后续迭代暂未更新。
服务配置:
单台阿里云ECS服务器 - 12核24G (redis/nginx/php7.1/laravel5.7)
单台阿里云RDS数据库 - 2核4G (mysql)
Supervisor开多个进程跑队列任务
php的woker进程设为100个
跟据laravel优化文档做了优化https://learnku.com/articles/2020/ten-laravel-5-program-optimization-techniques
php-fpm实际并发如下(siege压测-2核4G测试环境 ):
大部分简单逻辑接口并发300QPS
数据库操作多的接口并发70QPS
全查缓存接口接口并发550QPS
存在问题
当三个十万粉丝的商家同时发推文和多个商家线下门店做促销活动时,一秒点击人数过多或线下ERP消费小票、积分回传过多,服务器就会崩溃掉,服务器崩溃的时间如果超过几分钟不能响应接口,就会触发微信事件的3次重推机制和ERP回传5次重推机制,触发重推机制的情况下我们是可以关闭erp的回传,但无法停止80家商户的微信事件重推,这个时侯系统一般就会瘫痪1个多小时,瘫痪结束后又会面临数据找回的问题
一阶段方案
引入Laravel-S,利用swoole的长驻内存的机制, 常驻内存后每个请求减少了一大堆的初始化开销,能一定程度的增加并发数,实测要连接数据库的接口中的并发数提升了35% ~ 50%,不连接数据库的接口中的并发数提升400% ~ 500%,整体的请求失败率大幅度降低,正式环境下每天200多W个请求整体是正常的,没有发现有内存泄漏,在整体修改不大的情况下得到这个提升是很值得满意的。在此感谢Laravel-S作者和swoole社区,以下是Laravel-S作者对数据库连接提升不大的解释
laravel-s文档
github.com/hhxsv5/laravel-s
在此swoole实际并发如下(siege压测-2核4G测试环境):
- 大部分简单逻辑接口600QPS
- 数据库操作多的接口并发96QPS
- 全查缓存接口接口并发2000QPS
引入心得
- 任务队列和定时任务是可以直接用laravel原生的,这部份还是用php-fpm跑,不用过多改动,这样引入的过程中只用去改控制器上的业务代码,当然也可以把定时任务也写到swoole中,这样就可能得到毫秒级的定时任务。项目整体的运行模式为swoole(业务代码)+php-fpm(任务队列和定时任务)
- 控制器的业务逻辑中不要用$this来保存和调用变量,laravel下这一部份会被处理为单例模式的,Swoole Server下,所有单例对象会常驻于内存,这个时候单例对象的生命周期与FPM不同,单例对象依在请求结束后不会被清除,需要开发者自己维护单例的状态
- 认真的看文档的注意事项,文档能解决90%的问题,不能解决的加群或提issue
二阶段方案
在swoole的基础上引入负载均衡做服务器集群和分离项目内的模块(独立ERP模块、微信模块),用堆机器来提高总的并发数
负载均衡存在问题
- 文件如何同步 - 已解决,大部分文件已上云,小部分用nginx转发到特定服务器
- 日志如何收集 - 已解决,ELK日志分析系统
- session、缓存如何同步 - 已解决,全局切换redis
- 多服务器代码同步自动更新 - 已解决,jenkins + gitee(WebHooks)
分离模块存在问题
- 模型、队列、事件监听器高度藕合如何分离 - 半解决,多个服务器代码相同,只是不同业务访问特定服务器
以上的问题附了代码如何自动更新外,其实都可以在项目开始前设计好,希望各位如果开新项目不妨直接考虑上负载均衡会遇到的问题,尽量文件上云,尽量不要用本地文件缓存,尽量在一开始分离模块。
后续
3台机器搭好了负载均衡,同时代码层和业务层也做了很多的优化,能加缓存接口的加缓存,能走异步的不走同步,在全解决二阶段方案现有的问题后,相信在现有的下架构是可以撑半年时间来开发业务的了。
到此,laravel的优化应该是到头了,后面就是数据库的优化、引入mq队列、引入Elasticsearch、用协程的swoole框架如hyperf、easyswoole之类的重构,这类型的框架都相对应的提供了微服务的使用。
在12月在深圳开源中国开发者大会上听了韩天峰对php的分享,也听了下午的架构专场,目前看来在对于中大型的项目上,php的生态是远远比不上java的,像Sharding-JDBC的分布式数据库、Spring Cloud的微服务实现,php在这方面上还是很初级,希望以后在面向中大型项目上的生态能更好吧,在小型项目上php已经十分优秀了。
2020年12月更新
自2019年尾完成第二阶段的改造后,2020年公司的业务量增长200%,因此2020年做了以下优化,但系统还要不断优化。
- 增加更多的服务器
- 全面使用docker
- 引入Elasticsearch搜索
- 引入阿里云polardb集群
- 引入阿里云日志系统
- 引入数据仓库
- 重构数据统计业务
- 负载均衡增加业务隔离
- 代码增加业务隔离
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: