• 记laravel5.5项目php-fpm迁移到swoole4.2.9


    事起说明

            最近对上线半年多的laravel项目做了一次少大的改动,由php-fpm改为swoole,这里做个记录。

           2019年过年前半个月,上阿里云后台查看前一天的访问请求日志,发现很多接口响应慢。翻了前几天的日志,发现不少响应慢的接口,包括app首页资讯、文章列表、文章详情等所有和cms相关的接口。想着最近没上线过什么新功能,怎么最近变慢好多。阿里云后台查看nginx错误日志,上服务器看php-fpm错误日志。发现和上次php-fpm优化报的同样错误信息。时间点差不多都吻合,大都是push发出后的那几分钟。用户大都在开盘那会打开咱们公司的APP了,虽然公司这款app不做期货交易,黄金交易,但接口响应这么慢,严重影响用户体验!(下图是阿里云后台看到的日志信息)因为临近过年不想有大改动,向公司临时申请加一台服务器,配置好调试上生产负载均衡。

           

           过完年后,刚开工,需求不多。想着要优化系统,自己ab压测一下测试环境的接口,接口tps110多,有点低。参考网上的laravel框架优化资料(https://learnku.com/articles/5088/optimize-laravel-site-to-open-speed),照着改了tps上升到120左右,没起到什么起作用。

           在公司技术群里咨询下,有人建议用swoole+laravel,网上说做得好性能可以十倍以上的提升。又上github搜索swoole+laravel,选用别人已经集成好的,最后选用laravels(https://segmentfault.com/a/1190000013358289?utm_source=tag-newest)。

          开发机安装swoole扩展,composer拉取laravels包(折腾好会,这里就不表述了)。

          原来http请求到达web服务器,服务器nginx将请求转发给php-fpm,让php-fpm管理进程对php程序读取解析并返回。使用 swoole会接管php-fpm要做这部分事情。

         nginx配置更改如下(nginx监听接收88端口的请求并转发本机5200端口,如果是php-fpm,默认本机9000端口接收):

    gzip on;
    gzip_min_length 1024;
    gzip_comp_level 2;#返回结果的压缩比,数值越高压缩的越小但更消耗CPU,但不一定有更高的压缩率╥﹏╥
    gzip_disable "msie6";
    upstream laravels {
      # 通过 IP:Port 连接
    # 通config/laravels.php中listen_ip listen_port保持一致   server
    127.0.0.1:5200 weight=5 max_fails=3 fail_timeout=30s;   keepalive 16; } server {   listen 88;   server_name test-cms.xxxx.com;   root /alidata/www/test-cms.xxx.com/public;   access_log /alidata/logs/nginx/test-cms.xxx.com.log;   error_log /alidata/logs/nginx/test-cms.xxx.com-error.log;   charset utf-8;   location / {     try_files $uri @laravels;   }   location @laravels {     proxy_http_version 1.1;     proxy_set_header Connection "";     proxy_set_header X-Real-IP $remote_addr;     proxy_set_header X-Real-PORT $remote_port;     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;     proxy_set_header Host $http_host;     proxy_set_header Scheme $scheme;     proxy_set_header Server-Protocol $server_protocol;     proxy_set_header Server-Name $server_name;     proxy_set_header Server-Addr $server_addr;     proxy_set_header Server-Port $server_port;     proxy_pass http://laravels;   } }

          在修改config/laravels.php中配置:

        'listen_ip'                => env('LARAVELS_LISTEN_IP', '127.0.0.1'),
        'listen_port'              => env('LARAVELS_LISTEN_PORT', 9527),

    运行和排查

     php bin/laravels {start|stop|restart|reload|info|help} 

    再根据laravels命令:

    命令 说明
    start 启动LaravelS,展示已启动的进程列表 "ps -ef|grep laravels"。支持选项 "-d|--daemonize" 以守护进程的方式运行,此选项将覆盖laravels.phpswoole.daemonize设置;支持选项 "-e|--env" 用来指定运行的环境,如--env=testing将会优先使用配置文件.env.testing,这个特性要求Laravel 5.2+
    stop 停止LaravelS
    restart 重启LaravelS,支持选项 "-d|--daemonize" 和 "-e|--env"
    reload 平滑重启所有Task/Worker进程,这些进程内包含了你的业务代码,不会重启Master/Manger/Timer/Custom进程
    info 显示组件的版本信息
    help 显示帮助信息

         如下:

           再用上压测机用apache jmeter试了下,50的并发压测半分钟,结果显示性能提升很大哦^_^:

           再上100的并发压测:

           没什么提升,再看系统负载不高啊,为啥tps上不去? 

         在排查此问题时,在接口加了时间间隔打印。

         期间一直没找出问题出在哪,截图压测的几个接口都是从redis获取数据,不会读取mysql的。

         网上有人说可能是swoole的redis链接未释放导致的。

         可问题是我这里虽然redis链接句柄用的是class静态变量保存,但是redis是短连接,代码的变量不应该在请求结束就释放了吗?

         如果是用redis长链接可能导致异常,但像我这正常不会有redis链接未释放的问题啊,查看swoole和laravel错误日志也未找到redis的报错信息。

         第二天,忽然想到一位前同事,swoole用的很溜的,请教他后,让我把config/laravels.php的两个参数设置大一些。原来是系统内核数乘2,现在改成系统内核数乘12

         继续压测100的线程数:

         tps上到1200了非常激动

     

         在该同事想看看更高性能意见后,改成200线程数,400线程数,tps越来越大,系统负载也越来越高,接近极限,最后达到2200。

         期间发生一个小插曲,200线程组改成400线程组后,发现tps竟然达到7000多,真是把我两乐坏了,后来看下没有重启swoole服务,接口直接报错。。。

        所以在此提醒下,任何更改php代码的行为,都需要重启swoole服务才能生效!!!

       夜深了,明天要上班就不写了。

       未完待续,下篇接着更!!

  • 相关阅读:
    Java Map遍历方式的选择
    UriMatcher类的addURI()方法
    Java IO流分析整理[转]
    java基础一些注意细节
    java中static变量和方存在内存什么区域
    详细解析Java中抽象类和接口的区别
    mybatis一些记录
    Go语言简介(上)— 语法
    JavaScript相关-深入面向对象
    33个组件5
  • 原文地址:https://www.cnblogs.com/wscsq789/p/10468268.html
Copyright © 2020-2023  润新知