首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

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

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


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

    楼主表述不正确,还是其他?
        29
    haiyan   95 天前
    @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 %
        30
    dongya   95 天前   ♥ 1
    @AngryPanda 哈哈, 你说对了
        31
    kiwier   95 天前   ♥ 1
    哥哥 tp3 该换了,漏洞太多,并且性能不行
        32
    yc8332   95 天前   ♥ 1
    就是你的 php 程序速度太慢了。。。并发大了就只能排队了。。。加更多 php 进程没用,数据库连接数是一个问题,还有就是 cpu 也忙不过来。。。还是要优化你的 php 程序。。
        33
    Mazexal   95 天前   ♥ 1
    .net core 天下第一
        34
    sggggy   95 天前   ♥ 1
    初学 linux 的话建议安装 htop,用 htop 去看,不会因为不理解 top 的命令而心惊肉跳的。之前我也遇到老是有程序员问运维,为啥内存消耗这么高,要不要重启一下啥的…… windows 带来的理念。
        35
    vincenttone   95 天前   ♥ 1
    看当时的连接时长和数量,关键部分添加日志(比如请求和响应时长、数据库连接时长、timewait 的情况),添加内存和 cpu 负载的监控。这样你才知道具体问题出在哪里,猜测没用。
        36
    haiyan   95 天前
    @dongya
    @Mazexal 给 php 招黑了 🙈

    @kiwier 接手的项目,不是我开发的,换就是重新搞,搞不起啊
        37
    HiCode   95 天前   ♥ 1
    @haiyan

    这个内存使用率也偏高了,日活 2000,不是每分钟 2000,我建议是从内存占用入手。
        38
    goodspb   95 天前   ♥ 1
    和内存无关系。主要是 fpm 被耗尽了,先查一下 fpm 慢日志,看看是哪里导致的慢。临时的解决方案应该是调整一下 PM 的配置
        39
    avenger   95 天前 via iPhone   ♥ 1
    phpfpm 配置贴一下
        40
    azh7138m   95 天前   ♥ 1
    你可以考虑换 fpm 走 http 和 nginx 交互,代价是虽然能用户侧不会出现 50x,但是响应速度会变慢,实际 qps 可能会降低。
    还是要做好 profiling,看下是慢在哪里了。
    不过,2 分钟 单机 1k UV 其实很高了,一个 UV 毕竟对应了不少业务。
        41
    Snail233   95 天前   ♥ 1
    @Woood 哈哈哈哈,用的 laravel 吧,哈哈哈哈哈哈哈
        42
    Snail233   95 天前
    @tanszhe 哈哈哈哈,用的 laravel 吧,哈哈哈哈哈哈哈
        43
    opengps   95 天前   ♥ 1
    2 分钟 1000,这是很高的并发了,居然还用单机承载,而且是云服务器的硬盘
        44
    haiyan   95 天前
    @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
        45
    ragnaroks   95 天前   ♥ 1
    那就别用 php 了啊...你都用上.net 了,直接升级成.net core 呗,2c4g 抗 1w 并发不是轻轻松松?
        46
    haiyan   95 天前
    @ragnaroks 系统在用着
        47
    haiyan   95 天前
    @jsjscool 装了半天了还是没有装成功
        48
    jswh   94 天前   ♥ 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 策略不一样
        49
    jswh   94 天前
    @jswh 补充一下,如果还在用 php5.*建议尽快升级到 7.*
        50
    caryqy   94 天前   ♥ 1
    暂时解决不了的话就加硬件配置
        51
    avenger   94 天前   ♥ 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 看一下具体的情况,这是一个成长的机会。
        52
    avenger   94 天前
    @haiyan 又去看了下,我们的服务器是 2 核 8g 内存,ssd 硬盘
        53
    jsjscool   94 天前   ♥ 1
    @haiyan 报啥错?走到哪一步了?
        54
    qsbaq   94 天前   ♥ 1
    @haiyan 配置成 static,然后上个 opcache。
        55
    lifeintools   94 天前   ♥ 1
    @jsjscool 他的 PHP 水平 你让他安装个插件 太难为他了。不然 就 nginx 和 fpm 参数调优。
        56
    haiyan   94 天前
    @jsjscool git clone https://github.com/laynefyc/xhgui-branch.git
    cd xhgui-branch
    php install.php 这一步中途提示:github 连接超时
        57
    qinxi   94 天前   ♥ 1
    建议用 Java ,同时招聘 https://www.v2ex.com/t/583148 这个同学
        58
    wangzz223   94 天前   ♥ 1
    搞点缓存挡挡...都打到 mysql 上,服务并发不会很好..
    能异步化处理的异步化处理.
        59
    yufeng0681   94 天前   ♥ 1
    打日志,分段跟踪:
    1、压力测试,数据库是否有问题
    2、压力测试,web 响应是否有问题
    3、压力中,将某一段逻辑拿掉测试性能( 1、拿掉数据库代码直接返回; 2、拿掉业务处理代码直接回 html )

    小说业务有热门数据概念,最好上缓存,提高响应速度,减少数据库压力。虽然不知道你的小说是图片还是文字类的
        60
    codespots   94 天前   ♥ 1
    @ragnaroks 你是在黑 PHP 还是在黑 .net core
        61
    yumenoks   94 天前   ♥ 1
    上服务器吧,一个月 300 左右的,
    然后把数据库分离出来,丢到阿里云啥的,
    服务器可以弄 2 台,或者 1 台多 IP,然后开 1 台 linux 跑 web,一台 window 跑关关采集.
    看你自己的预算了.
        62
    1981   94 天前   ♥ 1
    个人建议把数据库分开来,我 10m 的数据库都卡卡卡卡卡卡卡
        63
    encro   94 天前   ♥ 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
        64
    encro   94 天前   ♥ 1
    request_terminate_timeout = 120
    request_slowlog_timeout = 0

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

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

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

    另外拿别的语言比较的多半没用意义。换语言本身就是一个重构过程,你换的过程中又不会一句一句去翻译,肯定会解决原来的一些不合理之处。
        69
    akira   94 天前   ♥ 1
    方案 1. 每个月多花几百块 升级下服务器
    方案 2. 付费找人帮忙优化服务器
    方案 3. 自学服务器优化相关技能并完成优化工作
        70
    ragnaroks   94 天前   ♥ 1
        71
    haiyan   94 天前
    一早来这么多回复,很感谢大家,指了很多方向,够我去了解的了。
    这个网站不着急马上解决,只要不发促销就行了😺。
    我看了代码,基本上压力在这几个:
    1,推送,每 5 分钟查询前 5 分钟未付款的订单,订单表 3 万多数据,查出来后循环发送;
    2,十几个推广在用着后台,生成二维码推广海报,时不时刷下各种统计;
    3,前台小说章节目录,是个大变量,两千多章节全部都是显示;
    4,登录和状态检查,通过子域名区分是谁的客户,用户表 40 多万,这个操作繁琐。
    我准备先去加缓存,推送换成队列,后续把优化结果发出来。
        72
    flashrick   94 天前
    @haiyan 这 4 条都可以用 redis 解决 手动狗头
        73
    haiyan   89 天前
    回来更新下,上周改完之后,终于可以顶住了。
    基本就是把上面的,1,4 两点改成用 redis 缓存实现,网站首页很少变化的也放缓存,微信获取 access_token 也放缓存,查询数据库量大大减少了,看来是 mysql 堵塞了。
    再次感谢各位帮助,学到了很多。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2298 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 28ms · UTC 07:16 · PVG 15:16 · LAX 00:16 · JFK 03:16
    ♥ Do have faith in what you're doing.