跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • PHP 项目架构性能瓶颈问题请教
未分類
2 1 月 2021

PHP 项目架构性能瓶颈问题请教

PHP 项目架构性能瓶颈问题请教

資深大佬 : yuandj 0

环境:

  • 语言:php7.4
  • 框架:hyperf 2.0

服务器

  • nginx 1 台
  • php api 4 台
  • redis 1 台
  • mysql 1 台

问题描述

  1. 目前项目在 qps 较高时遇到了响应时间延长的问题,新增了一台 api 服务器,并没有多大改善(原本是 3 台)
  2. 大概看了一下高并发时服务器的负载,并没有达到上限
  3. 平时 qps 可以支撑 1000 左右(3 台服务器),响应延迟保持在 450ms 左右。这两天请求增多 qps 达到 1300 左右,每个小时有十几分钟响应延迟会增加(多的时候响应会达到 3 、4 秒)(下面会附图),前 2 条大概排除了服务器的问题,现在考虑代码问题。下面附图把代码流程加了 time debug,并附带上比较耗时的代码段,麻烦各位大佬帮忙看看代码有没有性能瓶颈问题。

ps: 之前有段时间也遇到响应延迟问题,当时 time debug 定位到 redis get 操作耗时比较多(当时是 2 秒左右),但并没有在这方面做修复,后面通过减少了 swoole 的进程数解决了。

请求延迟监控图

每个小时的开始,请求会比较集中

PHP 项目架构性能瓶颈问题请教

请求流程时间拆分图

发现 qps 相关的代码段执行时间比较长,下面附上相关代码段

PHP 项目架构性能瓶颈问题请教

QPS 相关代码段

PHP 项目架构性能瓶颈问题请教

PHP 项目架构性能瓶颈问题请教

PHP 项目架构性能瓶颈问题请教

大佬有話說 (40)

  • 資深大佬 : mitu9527

    这么多台服务器,一般不能才 1000 多 qps 。

    感觉你这问题不是很难的样子,看看硬件资源消耗,再多看看各种日志,应该就能找到问题所在。

  • 資深大佬 : Jeyfang

    尝试下排除法咯,注释下各耗时严重的地方,然后单独去排查。期待这问题解决的后续

  • 資深大佬 : imhui

    有项目用了 hyperf,关注一波

  • 資深大佬 : imgbed

    mysql 数据量大吗?

  • 主 資深大佬 : yuandj

    @imgbed mysql 数据量不大,是有缓存层的,缓存是永久有效,之前排查到 Redis get 操作耗时 2 秒,会不会是和缓存相关的问题呢,但当时在排查了 redis 慢日志,并没有耗时较久的命令

  • 資深大佬 : wangbenjun5

    你们 QPS 居然用代码去统计,难道不能用 nginx 访问日志去统计么

  • 主 資深大佬 : yuandj

    @wangbenjun5 不是做统计,是用来做请求限制

  • 資深大佬 : awanganddong

    这个是 adx 平台,还是 dsp 平台。

    是不是 redis 缓存击穿了

  • 資深大佬 : liuxu

    性能分析靠猜测三言两语说不清,最起码一个系统资源消耗和 xhprof 日志得给出来

  • 資深大佬 : lbp0200

    QPS1000 多,也是大站了

  • 資深大佬 : z5864703

    redis 的 qps 多少,有时并不是 redis 执行慢,而是 qps 高,本身单线程排队执行下来就延迟高了。
    针对这种情况批量操作 redis 可以用管道和 lua 脚本,减少网络交互延迟

  • 資深大佬 : nowgoo

    可能 redis 的网卡打满了?缓存的数据不宜太大

  • 資深大佬 : wangritian

    你能做的事情还有很多,确认业务机器、redis 、mysql 的负载和带宽,单独编写接口做压力测试,尽可能多收集信息,再做思考

  • 資深大佬 : keller

    QPS 统计改成异步吧
    不要实时计算,异步计算好结果,下次请求的时候直接从缓存拿上次结算好的数据做限制

  • 主 資深大佬 : yuandj

    @z5864703 @wangritian 由于没运维,机器负载和带宽大概排查了一下,没大波动,初步怀疑就是 redis 这里有问题(上面更新了 redis 慢日志),后面试试减少 redis io,提高 redis 配置尝试一下

  • 資深大佬 : GGGG430

    直接线上短时间 strace -T -tt -p 123 -o log 看看某个 swoole 的 worker 在干啥, 然后找找里面耗时高的系统调用在干啥, 精准定位问题

  • 資深大佬 : HanMeiM

    mysql 和 redis 这种还是直接上云吧。。。如果真有问题,你们没运维也搞不定啊

  • 資深大佬 : opengps

    1000 的 qps,一台数据库,关注下数据库这台机器的硬盘 io 是不是瓶颈

  • 資深大佬 : ahsjs

    @yuandj 缓存 qps 数据?每隔多少时间更新一次,超也就超一点点

  • 資深大佬 : chengfeng

    既然觉得是 redis 的问题,直接租个高配版 redis 切换过去看看效果呗

  • 資深大佬 : ebingtel

    redis 用池化连接了么?

  • 資深大佬 : liuhan907

    我建议你可以考虑接入 prometheus,细致的分析每个操作的耗时。能更加精确的定位瓶颈。

  • 資深大佬 : zhuzhibin

    我就想问协程框架好不好用 上手如何?

  • 資深大佬 : AlanLeung2018

    先排查是不是 mysql 慢查询造成的慢请求,然后再检查一下是不是某个时间段 fpm 进程数太多了

  • 資深大佬 : iConnect

    这个情况大概率是 redis 的故障,先把 redis 服务器扩容或提高配置,或者干脆切到云服务商的专业 redis 云跑一段时间,对比一下,基本上就能诊断出来了。

  • 資深大佬 : honkki

    redis 的配置是否有问题

  • 資深大佬 : sagaxu

    1. 先确认 php 的 redis 用了连接池,池的大小,空闲多少
    2. for 循环里每次两个 incr,10 个 config 的时候就是 20 个 incr,考虑做成批量更新

  • 資深大佬 : dusu

    显然是 redis pool 到了最高并发量 导致 hyperf worker 协程都卡在了 redis 这头 而 redis 又查不出慢查询的原因

    建议把 qps 部分或者高频又低重要性的 redis 操作都换成 asyncQueue 或者其他异步单线程任务试试看看协程能不能缓解。

  • 資深大佬 : chenqh

    感觉是不是 redis get 的一些值字节太大?

  • 資深大佬 : sadfQED2

    先确认一下硬件资源占用,每台机器的硬盘 io,网络 io,cpu,内存

    先确定不是内存以后再定位是哪台机器。

    另外,项目里面建议引入 opentarcing

  • 資深大佬 : sadfQED2

    @sadfQED2 不是内存等硬件
    少打几个字了

  • 資深大佬 : surfire91

    @yuandj
    “确实有一些 incr set get 时间比较长,超过了 10000 微秒,但是图中 qps_incr_time 代码段执行时间是 170 毫秒,那么这么大的差距是哪里来的呢?”

    qps_incr_time 代码段 里遍历了一个数组 configs,每个元素要执行两次 redis incr, 如果 configs 元素的数量多几个,执行 170ms 也正常。

    另外 redis incr 需要 10ms 的话,肯定是不正常的。

  • 資深大佬 : dedemao

    请教下“请求延迟监控图”和“请求流程时间拆分图”是如何获取的呢

  • 資深大佬 : fuxkcsdn

    skipConfig 里的 $cUsedQps, $pUsedQps 这 2 个可以用 mget 来获取

    incrQps 方法
    可以通过 pipe 或者事务来执行,速度会提高很多
    如果 incrQps 里那个循环量很大的话,那直接改这里性能就能有很大提升了

  • 資深大佬 : jeristiano

    建议你去 hyperf 官方群去问问,他们经常为用户提供建议和反馈
    qq 862099724

  • 主 資深大佬 : yuandj

    @dedemao 监控是用的 hyperf 手册里推荐的,你可以在手册里搜索关键字“ Grafana”;请求流程拆分图,是自己打的日志

  • 資深大佬 : mpanda

    第一直觉,反正不是 php 的锅

  • 資深大佬 : sagaxu

    咱们好像是同行,这个行业 qps 做到单机 1 万才算及格,rtb 响应时间(含网络)一般不宜超过 200ms 。不含 dmp 的纯 dsp,单机普遍能做到 10 万 qps 。

  • 主 資深大佬 : yuandj

    @fuxkcsdn incr 用 pipe 来操作,执行时间有所改善;但是 skipConfig 用 mget(),却比之前消耗了更多时间,请问是什么原因呢?

  • 資深大佬 : fuxkcsdn

    @yuandj mget 消耗更多时间,是多次对比结果吗?
    从源码上看 mget 只是 get 的循环并组装 reply,理论上能抵消网络消耗才对
    一种可能就是当前 redis 服务器已经超过负荷,组装 reply 的损耗超过 1 次网络请求的损耗了

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具