K8S与Laravel压测经历过程

背景K8S与Laravel5.6压测:
  1. 运维准备压测环境,ECS上安装的Redis(从生产环境克隆过来的镜像),4核8G阿里云MySQL5.6 RDS,代码部署在Docker挂载的NAS固态盘上,两个pod,每个pod都是nainx与php-fpm两个容器。准备完成后测试:

    访问登录接口,xxxxxxxx/login,发现每次都是5.x秒,都不用压测了,光是一个登录接口,还没有带参数,只是经过路由到方法,验证参数,返回结果这个流程都这么慢,其它接口更不用说了。

    开始找原因:

* 因为是负载均衡,后面既有ECS,也有k8s,先只把请求打在ECS上执行,发现没有问题;负载打到k8s上,很慢。所以确认是k8s问题,然后pod各种调配置,重构等等无济于事,目前打的docker镜像,都是把配置文件从外面COPY进容器里,修改php或nginx的配置很麻烦,在阿里云的docker镜像里不能重启,遂决定容器里要动态加载外面的配置文件,同时还不用重新打镜像,
最终通过载入nas盘里的shell脚本,然后在容器里执行这个脚本启动对应容器的主进程和其它操作,比如创建目录,覆盖配置文件等。

  • 通过上一步操作,已到晚上12点多,查看各种日志,还是没有找到原因,在laravel的入口文件index.php里打断点,发现返回很快,进入路由后返回就很慢,在网上看到相关资料说是因为laravel每次启动都会加载大量文件,怀疑是每次请求打到容器里,容器里挂载的是nas盘,在容器里加载大量文件,可能导致磁盘IO高或者网络消耗引起的速度慢,所以又重新修改Dockerfile,启动时把挂载的代码目录直接拷到docker容器里面,这样就不是执行挂载目录的代码了,最后发现还是慢......

  • 死马当活马医,决定修改.env配置,把MySQLRedis配置注释,让项目报错,看看错误日志记录的位置,神奇的是,这个时候接口变快了,接着调试发现是Redis的问题,ECS上安装的Redis不允许外界连接,由于ECS是直接从线上克隆的,所以以为代码和配置肯定没有问题,结果是Redis服务的问题,:|,由于redis只能本地连接,所以负载打到ECS上没有问题,打到k8s就慢,又因为我们没有输入账号密码进行登录后面的操作,也没有用上Redis缓存,导致问题没有发现,只是在laravel初始化的时候因为连接不上Reids而耗时多导致网页反馈慢

    结论:这次错误排查耗时长,2个运维(由于开发不熟悉k8s相关操作),2个开发,一起排查,结果开发也跟着把k8s好好的熟悉了一遍,最后找到问题已是凌晨1点多。由于我们许多简单的动作没做,偏离了排查方向,导致花费了太多时间。往往看起来复杂的问题,最后都是简单的错误引起的。

  1. 初次压测:第二天上午,直接100并发压测,崩溃!!,XD,最后发现只能支持差不多10个并发几分钟而已;

    分析接口代码,业务逻辑实现有问题,导致查询条件不合理,扫描MySQL的行数过多,查询慢,更改查询与增加相关索引,并发到100没有任务问题。但是到500就出现很多问题。

  2. 第二次压测:到500并发的时候,出现很多504与502,修改了php-fpm的max_children与nginx等各种配置后,500并发也勉强可以达到,接口响应时间随着压测时间变长也跟着变长,然后接着升级pod配置之后,发现并发怎么都上不去,MySQL RDS没有瓶颈,pod监控也是没有问题,都没有自动扩容,压测到了1分钟的时候就开始出现504与502。查看nginx日志也是随着压测的时间的增加,反应越来越慢。这中间又是各种修改php与nginx的配置,各种捣鼓,还是运维的亮哥说,得看php的slow log.

  • 插曲:想查看php slow log, 但这个配置在docker容器开启后,没有起作用,在容器里没有生成相关文件。这个调整花费了很多时间,最后如愿以偿看到了slow
    log。

  • 查看slow.log,果然还是laravel框架的问题,每次请求接口,框架会生成一个session会话,默认配置是存储在storage/framework/sessions/目录,进入目录后发现这个目录下的文件已经到达2万多,每次请求都会更改对应文件的内容,这回真的是磁盘IO引起的问题了,我把session的drive修改成redis,速度马上上来了,并发压测1000也毫无压力。

    至此,一次小的压力测试完成!!!!

发布者

发表评论

电子邮件地址不会被公开。 必填项已用*标注