PHP 网站内存占用很高,一做活动就挂了,大佬们帮忙看看 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
haiyan
V2EX    程序员

PHP 网站内存占用很高,一做活动就挂了,大佬们帮忙看看

  •  
  •   haiyan 2019-07-16 09:03:49 +08:00 8348 次点击
    这是一个创建于 2360 天前的主题,其中的信息可能已经有所发展或是发生改变。
    服务器就一个小说网站,服务器阿里云的 2 核 4G 配置,mysql 数据库 1.5G ,日活 2000 这样,平时网站内存就占到了 80%多了,mysql 占了 20%。如果发个促销网址,人同时一上来就挂,实际那两分钟来的人也还不多 1000,必须重启 php-fpm 才行。同配置的.net 版系统就毫无压力,索引设置了,日志也看了,现在不知道是配置低了,还是程序性能太差了。
    请大家帮忙提点见解,谢谢了!
    74 条回复    2019-11-20 12:33:51 +08:00
    abccccabc
        1
    abccccabc  
       2019-07-16 09:09:32 +08:00   1
    你这是在 win 系统跑 PHP 吗??试下加缓存之类的。
    AngryPanda
        2
    AngryPanda  
       2019-07-16 09:11:31 +08:00 via Android   2
    我知道了,你是来黑 PHP 的
    AngryPanda
        3
    AngryPanda  
       2019-07-16 09:12:47 +08:00 via Android
    看一下 phpfpm 的 log
    chuhemiao
        4
    chuhemiao  
       2019-07-16 09:13:42 +08:00   1
    加个 cdn 和 rdb
    Dogergo
        5
    Dogergo  
       2019-07-16 09:14:00 +08:00   1
    代码有问题,大变量释放之类的
    hbolive
        6
    hbolive  
       2019-07-16 09:14:54 +08:00   1
    你这是单台服务器,所以重点检查下数据库,程序。
    所以可以检查下是哪些页面导致数据库负载太高,SHOW full PROCESSLIST,做好表优化工作。。。
    程序的优化只能一点点排查了,也跟写程序的人有关系。。
    加入缓存系统。。
    lmaster
        7
    lmaster  
       2019-07-16 09:16:55 +08:00   1
    有篇博文介绍了 nginx+php ( http://zyan.cc/nginx_php_v4/),你看看是不是 nginx 进程太多导致,试试将 worker_processes 降低,然后你的服务器外网带宽是多少?
    kiwier
        8
    kiwier  
       2019-07-16 09:17:51 +08:00   1
    fpm 再不济,这一两千并发还是可以承受得住的
    tanszhe
        9
    tanszhe  
       2019-07-16 09:19:12 +08:00   1
    用的 laravel 吧
    SpringBlossom
        10
    SpringBlossom  
       2019-07-16 09:20:00 +08:00   1
    试下 swoole
    SpringBlossom
        11
    SpringBlossom  
       2019-07-16 09:21:17 +08:00
    2 分钟 1000,都扛不住,是有的参数没有设置吧,比如 app_debug 之类的
    haiyan
        12
    haiyan  
    OP
       2019-07-16 09:23:11 +08:00
    root 2696 0.0 0.2 39816 7816 ? Ss Jul15 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
    www 2698 0.0 0.8 70536 33328 ? S Jul15 0:25 nginx: worker process
    www 2699 0.0 0.9 91016 35620 ? S Jul15 0:35 nginx: worker process
    mysql 4024 1.6 13.1 2156936 508640 ? Sl Jul15 17:17 /usr/local/mysql/bin/mysqld
    root 5569 0.0 0.3 551672 14788 ? Ss Jul15 0:01 php-fpm: master process
    www 5579 0.0 0.5 633356 21584 ? S Jul15 0:12 php-fpm: pool www
    php-fpm X 32 个
    haiyan
        13
    haiyan  
    OP
       2019-07-16 09:24:51 +08:00
    centos7 跑的,thinkphp 3 的框架,没用什么缓存,感觉没用也没什么影响,系统其实算起来很简单的了
    haiyan
        14
    haiyan  
    OP
       2019-07-16 09:29:45 +08:00
    挂了看 php 日志就是 connect() to unix:/dev/shm/php-cgi.sock failed (2: No such file or directory) while connecting to upstream 这个,max_children 设置到 100 了
    jsjscool
        15
    jsjscool  
       2019-07-16 09:30:41 +08:00   1
    装个 xhgui-branch 看看慢在哪
    yEhwG10ZJa83067x
        16
    yEhwG10ZJa83067x  
       2019-07-16 09:33:47 +08:00   1
    慢日志发上来看看。一般一个 fpm 进程 40M-60M
    haiyan
        17
    haiyan  
    OP
       2019-07-16 09:35:20 +08:00
    @hbolive
    @jsjscool 看了数据库日志,把慢的查询都优化了,还是那样
    haiyan
        18
    haiyan  
    OP
       2019-07-16 09:37:51 +08:00
    这个还不好测试并发,因为都要网站依赖微信登录,没有登录都调到了登录页面了
    components
        19
    components  
       2019-07-16 09:52:51 +08:00   1
    就一小说阅读站,为什么要用 MySQL,sqllite 足以!
    其实,你用 MySQL,就已经吃掉很大一半内存了
    lifeintools
    nbsp;   20
    lifeintools  
       2019-07-16 09:54:34 +08:00   1
    @haiyan 目测是需要参数调优。
    flashrick
        21
    flashrick  
       2019-07-16 10:05:55 +08:00   1
    @components 小说用 nosql 存吧,用 redis 都好,
    haiyan
        22
    haiyan  
    OP
       2019-07-16 10:12:40 +08:00
    @components
    @flashrick 心塞啊,.net 版的还是 win+iis+mssql 应该更占内存啊
    haiyan
        23
    haiyan  
    OP
       2019-07-16 10:12:59 +08:00
    @lifeintools 能否指点一下,哪里的参数
    jsjscool
        24
    jsjscool  
       2019-07-16 10:14:29 +08:00   1
    @haiyan 这明显不是数据库的问题,初步怀疑是哪个资源文件锁了。编程最好不要靠猜,https://github.com/laynefyc/xhgui-branch 装一下,分分钟解决问题。
    dafengchui
        25
    dafengchui  
       2019-07-16 10:14:51 +08:00   1
    其实我觉得估计用了 mysql 的默认配置, 优化下 mysql
    mumbler
        26
    mumbler  
       2019-07-16 10:22:23 +08:00 via Android   1
    遇到过同样问题,最后发现是 nginx 配置问题,并发设置太低
    haiyan
        27
    haiyan  
    OP
       2019-07-16 10:23:22 +08:00
    @jsjscool 学习一下,谢谢你
    Q4h7388nR28s95fa
        28
    Q4h7388nR28s95fa  
       2019-07-16 10:47:55 +08:00   1
    “服务器阿里云的 2 核 4G 配置,mysql 数据库 1.5G ,日活 2000 这样,平时网站内存就占到了 80%多了,mysql 占了 20%”


    我感觉代码问题挺大吧,“平时网站内存就占到了 80%多”,2000 日活,什么情况下会让 php 把内存都占了?

    楼主表述不正确,还是其他?
    haiyan
        29
    haiyan  
    OP
       2019-07-16 11:07:06 +08:00
    @HiCode
    看错了,对 linux 的不了解,实际是这样的
    物理内存:共 3.702 G , 已用 3.082 G , 空闲 0.62 G , 使用率 83.25%

    Cache 化内存为 2.058 G , 使用率 55.59 % | Buffers 缓冲为 0.15 G

    真实内存使用 0.874 G , 真实内存空闲 2.828 G , 使用率 23.6 %
    dongya
        30
    dongya  
       2019-07-16 11:09:00 +08:00   1
    @AngryPanda 哈哈, 你说对了
    kiwier
        31
    kiwier  
       2019-07-16 11:09:39 +08:00   1
    哥哥 tp3 该换了,漏洞太多,并且性能不行
    yc8332
        32
    yc8332  
       2019-07-16 11:10:09 +08:00   1
    就是你的 php 程序速度太慢了。。。并发大了就只能排队了。。。加更多 php 进程没用,数据库连接数是一个问题,还有就是 cpu 也忙不过来。。。还是要优化你的 php 程序。。
    Mazexal
        33
    Mazexal  
       2019-07-16 11:10:52 +08:00   2
    .net core 天下第一
    sggggy
        34
    sggggy  
       2019-07-16 11:11:25 +08:00   1
    初学 linux 的话建议安装 htop,用 htop 去看,不会因为不理解 top 的命令而心惊肉跳的。之前我也遇到老是有程序员问运维,为啥内存消耗这么高,要不要重启一下啥的…… windows 带来的理念。
    vincenttone
        35
    vincenttone  
       2019-07-16 11:14:16 +08:00   1
    看当时的连接时长和数量,关键部分添加日志(比如请求和响应时长、数据库连接时长、timewait 的情况),添加内存和 cpu 负载的监控。这样你才知道具体问题出在哪里,猜测没用。
    haiyan
        36
    haiyan  
    OP
       2019-07-16 11:17:26 +08:00
    @dongya
    @Mazexal 给 php 招黑了

    @kiwier 接手的项目,不是我开发的,换就是重新搞,搞不起啊
    Q4h7388nR28s95fa
        37
    Q4h7388nR28s95fa  
       2019-07-16 11:21:54 +08:00   1
    @haiyan

    这个内存使用率也偏高了,日活 2000,不是每分钟 2000,我建议是从内存占用入手。
    goodspb
        38
    goodspb  
       2019-07-16 12:53:30 +08:00   1
    和内存无关系。主要是 fpm 被耗尽了,先查一下 fpm 慢日志,看看是哪里导致的慢。临时的解决方案应该是调整一下 PM 的配置
    avenger
        39
    avenger  
       2019-07-16 12:56:42 +08:00 via iPhone   1
    phpfpm 配置贴一下
    azh7138m
        40
    azh7138m  
       2019-07-16 12:59:48 +08:00   1
    你可以考虑换 fpm 走 http 和 nginx 交互,代价是虽然能用户侧不会出现 50x,但是响应速度会变慢,实际 qps 可能会降低。
    还是要做好 profiling,看下是慢在哪里了。
    不过,2 分钟 单机 1k UV 其实很高了,一个 UV 毕竟对应了不少业务。
    Snail233
        41
    Snail233  
       2019-07-16 13:11:31 +08:00   1
    @Woood 哈哈哈哈,用的 laravel 吧,哈哈哈哈哈哈哈
    Snail233
        42
    Snail233  
       2019-07-16 13:11:46 +08:00
    @tanszhe 哈哈哈哈,用的 laravel 吧,哈哈哈哈哈哈哈
    opengps
        43
    opengps  
       2019-07-16 13:52:18 +08:00   1
    2 分钟 1000,这是很高的并发了,居然还用单机承载,而且是云服务器的硬盘
    haiyan
        44
    haiyan  
    OP
       2019-07-16 13:57:14 +08:00
    @avenger
    pm = dynamic
    pm.max_children = 100
    pm.start_servers = 30
    pm.min_spare_servers = 20
    pm.max_spare_servers = 70
    pm.max_requests = 2048
    pm.process_idle_timeout = 10s
    request_terminate_timeout = 120
    request_slowlog_timeout = 0
    ragnaroks
        45
    ragnaroks  
       2019-07-16 14:44:13 +08:00   1
    那就别用 php 了啊...你都用上.net 了,直接升级成.net core 呗,2c4g 抗 1w 并发不是轻轻松松?
    haiyan
        46
    haiyan  
    OP
       2019-07-16 15:16:01 +08:00
    @ragnaroks 系统在用着
    haiyan
        47
    haiyan  
    OP
       2019-07-16 15:16:26 +08:00
    @jsjscool 装了半天了还是没有装成功
    jswh
        48
    jswh  
       2019-07-16 15:18:39 +08:00   1
    看错了,对 linux 的不了解,实际是这样的
    物理内存:共 3.702 G , 已用 3.082 G , 空闲 0.62 G , 使用率 83.25%

    Cache 化内存为 2.058 G , 使用率 55.59 % | Buffers 缓冲为 0.15 G

    真实内存使用 0.874 G , 真实内存空闲 2.828 G , 使用率 23.6 %
    ============================
    另外你 2 核心 4G 服务器,这个 php-fpm 设置得有点高了,可以稍微小一点,毕竟 mysql 也是内存大户。


    Linux 要看实际使用内存,不要把 buffer/cache 算上。和 Windows 策略不一样
    jswh
        49
    jswh  
       2019-07-16 15:19:36 +08:00
    @jswh 补充一下,如果还在用 php5.*建议尽快升级到 7.*
    caryqy
        50
    caryqy  
       2019-07-16 15:21:54 +08:00   1
    暂时解决不了的话就加硬件配置
    avenger
        51
    avenger  
       2019-07-16 16:03:18 +08:00   1
    @haiyan 我贴一个我们产品服务器的配置,服务器也是 2 核 4G,高峰的时候,并发 1000,服务器都没啥压力,用的是 Laravel php7.2,开了 opcache,你参考一下,不过我们数据库是分开的,用的单独的阿里云 RDS

    ```
    pm = static
    pm.max_children = 300
    pm.start_servers = 20
    pm.min_spare_servers = 5
    pm.max_spare_servers = 50
    ;pm.process_idle_timeout = 10s
    pm.max_requests = 5000
    ```

    另外,建议服务器有压力的时候开启一下 php-fpm status 看一下具体的情况,这是一个成长的机会。
    avenger
        52
    avenger  
       2019-07-16 16:12:11 +08:00
    @haiyan 又去看了下,我们的服务器是 2 核 8g 内存,ssd 硬盘
    jsjscool
        53
    jsjscool  
       2019-07-16 16:22:59 +08:00   1
    @haiyan 报啥错?走到哪一步了?
    qsbaq
        54
    qsbaq  
       2019-07-16 16:26:51 +08:00   1
    @haiyan 配置成 static,然后上个 opcache。
    lifeintools
        55
    lifeintools  
       2019-07-16 17:11:19 +08:00   1
    @jsjscool 他的 PHP 水平 你让他安装个插件 太难为他了。不然 就 nginx 和 fpm 参数调优。
    haiyan
        56
    haiyan  
    OP
       2019-07-16 17:42:33 +08:00
    @jsjscool git clone https://github.com/laynefyc/xhgui-branch.git
    cd xhgui-branch
    php install.php 这一步中途提示:github 连接超时
    qinxi
        57
    qinxi  
       2019-07-16 18:07:41 +08:00   1
    建议用 Java ,同时招聘 t/583148 这个同学
    wangzz223
        58
    wangzz223  
       2019-07-16 18:17:16 +08:00   1
    搞点缓存挡挡...都打到 mysql 上,服务并发不会很好..
    能异步化处理的异步化处理.
    yufeng0681
        59
    yufeng0681  
       2019-07-16 18:25:05 +08:00   1
    打日志,分段跟踪:
    1、压力测试,数据库是否有问题
    2、压力测试,web 响应是否有问题
    3、压力中,将某一段逻辑拿掉测试性能( 1、拿掉数据库代码直接返回; 2、拿掉业务处理代码直接回 html )

    小说业务有热门数据概念,最好上缓存,提高响应速度,减少数据库压力。虽然不知道你的小说是图片还是文字类的
    codspots
        60
    codespots  
       2019-07-16 18:34:31 +08:00   1
    @ragnaroks 你是在黑 PHP 还是在黑 .net core
    yumenoks
        61
    yumenoks  
       2019-07-16 18:36:51 +08:00   1
    上服务器吧,一个月 300 左右的,
    然后把数据库分离出来,丢到阿里云啥的,
    服务器可以弄 2 台,或者 1 台多 IP,然后开 1 台 linux 跑 web,一台 window 跑关关采集.
    看你自己的预算了.
    1981
        62
    1981  
       2019-07-16 19:00:17 +08:00   1
    个人建议把数据库分开来,我 10m 的数据库都卡卡卡卡卡卡卡
    encro
        63
    encro  
       2019-07-16 20:47:30 +08:00   1
    可以帮你解决,服务费 2000 元。
    也可以自己看我这篇日志吧:
    https://c4ys.com/archives/1609

    PHP 是进程模式的,1000 个并发,那么需要的 cpu 和内存你这配置确实不够。(没有用 swoole 之类的话)
    1000*10M 大约,大约需要 10G 内存。
    通常都没有 1000 个并发,估计数据库先挂了,挂的原因可能是慢 SQL,导致进程卡住一直上涨,连接不释放内存爆掉,或者连接数超过上线,套路云默认 5000。

    提示:
    nginx 开启 request_time;
    php-fpm 慢日志
    mysql 慢日志
    php-fpm 错误日志
    nginx 错误日志
    php 进程数
    mysql 连接数
    nginx 连接数

    以上文字价值 5000
    encro
        64
    encro  
       2019-07-16 20:57:02 +08:00   1
    request_terminate_timeout = 120
    request_slowlog_timeout = 0

    request_terminate_timeout 和 nginx 的 timeout 配置冲突,导致 nginx 主动断开,php 不回收,然后就会 not such file。

    google 下这个错误,就会发现答案的。
    如果百度的话,我可以保证没有一个是对的。
    ginjedoad
        65
    ginjedoad  
       2019-07-16 21:02:35 +08:00   1
    golang 重构一下,4 台一样的配置的机器,百万并发支持。
    encro
        66
    encro  
       2019-07-16 21:11:45 +08:00   1
    通常我用 Yii 框架,一个请求大约是 10-50ms,100 个进程( static 模式),1 分钟理论上支持的请求数是 1000*100/50=2000。
    caoyouming
        67
    caoyouming  
       2019-07-16 21:43:17 +08:00 via Android   1
    我在学校做的那个选课系统,单次选课人数最多可达到 5000 左右,并没有感到有压力呀。我用的也是单服务器,apache+mysql+php,对,服务器也是 winserver,我记得我开始做这个项目时候有一次也遇到类似的问题,改了 apache 的配置文件,包括连接数等等之后就没有这样的问题了。你可以看看你的服务器配置文件,找个懂配置文件的看看就行了。
    jhdxr
        68
    jhdxr  
       2019-07-16 21:48:21 +08:00   2
    @Snail233 laravel 也没那么不堪。。。

    小说网站能卡成这样多半是程序没写好。说不定在循环里写个 sql 查询之类的。。。

    另外拿别的语言比较的多半没用意义。换语言本身就是一个重构过程,你换的过程中又不会一句一句去翻译,肯定会解决原来的一些不合理之处。
    akira
        69
    akira  
       2019-07-17 00:59:10 +08:00   1
    方案 1. 每个月多花几百块 升级下服务器
    方案 2. 付费找人帮忙优化服务器
    方案 3. 自学服务器优化相关技能并完成优化工作
    ragnaroks
        70
    ragnaroks  
       2019-07-17 08:38:46 +08:00   1
    haiyan
        71
    haiyan  
    OP
       2019-07-17 09:01:03 +08:00
    一早来这么多回复,很感谢大家,指了很多方向,够我去了解的了。
    这个网站不着急马上解决,只要不发促销就行了。
    我看了代码,基本上压力在这几个:
    1,推送,每 5 分钟查询前 5 分钟未付款的订单,订单表 3 万多数据,查出来后循环发送;
    2,十几个推广在用着后台,生成二维码推广海报,时不时刷下各种统计;
    3,前台小说章节目录,是个大变量,两千多章节全部都是显示;
    4,登录和状态检查,通过子域名区分是谁的客户,用户表 40 多万,这个操作繁琐。
    我准备先去加缓存,推送换成队列,后续把优化结果发出来。
    flashrick
        72
    flashrick  
       2019-07-17 10:16:28 +08:00
    @haiyan 这 4 条都可以用 redis 解决 手动狗头
    haiyan
        73
    haiyan  
    OP
       2019-07-22 09:32:53 +08:00
    回来更新下,上周改完之后,终于可以顶住了。
    基本就是把上面的,1,4 两点改成用 redis 缓存实现,网站首页很少变化的也放缓存,微信获取 access_token 也放缓存,查询数据库量大大减少了,看来是 mysql 堵塞了。
    再次感谢各位帮助,学到了很多。
    CODEWEA
        74
    CODEWEA  
       2019-11-20 12:33:51 +08:00
    for 循环 mysql ?,果然是来黑 php 的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2391 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 13:03 PVG 21:03 LAX 05:03 JFK 08:03
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86