一个 PHP 服务,收到请求之后,直接 HTTP 请求第三方,拿到结果返回,整个过程是同步阻塞的;
最近第三方延迟升高导致服务在高峰的时候 load 也升高了,类似这种瓶颈在网络 io 的服务,反映在 CPU 状态的什么地方呢?
wa 和 iowait 只反映磁盘 io 对 load 的影响,网络 io 对 load 的影响反映在哪里(延迟升高导致 fpm 进程阻塞,是反映在 us 升高吗)?是否第三方接口的延迟变高会使这个服务机器的 us,si 变高?
楼主基础知识不扎实,特来求教
top - 12:57:45 up 201 days, 20:59, 1 user, load average: 2.61, 2.70, 2.79
Tasks: 451 total, 3 running, 448 sleeping, 0 stopped, 0 zombie
%Cpu0 : 23.8 us, 5.8 sy, 0.0 ni, 67.3 id, 0.0 wa, 0.0 hi, 3.1 si, 0.0 st
%Cpu1 : 22.0 us, 7.1 sy, 0.0 ni, 67.6 id, 0.0 wa, 0.0 hi, 3.4 si, 0.0 st
%Cpu2 : 23.0 us, 6.8 sy, 0.0 ni, 67.2 id, 0.0 wa, 0.0 hi, 3.0 si, 0.0 st
%Cpu3 : 16.0 us, 7.8 sy, 0.0 ni, 72.7 id, 0.0 wa, 0.0 hi, 3.4 si, 0.0 st
%Cpu4 : 12.8 us, 5.2 sy, 0.0 ni, 79.9 id, 0.0 wa, 0.0 hi, 2.1 si, 0.0 st
%Cpu5 : 12.8 us, 5.9 sy, 0.0 ni, 79.6 id, 0.0 wa, 0.0 hi, 1.7 si, 0.0 st
%Cpu6 : 12.9 us, 5.8 sy, 0.0 ni, 78.6 id, 0.0 wa, 0.0 hi, 2.7 si, 0.0 st
%Cpu7 : 14.2 us, 5.2 sy, 0.0 ni, 78.9 id, 0.0 wa, 0.0 hi, 1.7 si, 0.0 st
KiB Mem : 32747872 total, 306700 free, 2588520 used, 29852652 buff/cache
KiB Swap: 16516092 total, 16516092 free, 0 used. 27871856 avail Mem
mpstat -P ALL 2
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 16.35 0.00 5.94 0.00 0.00 2.39 0.00 0.00 0.00 75.32
Average: 0 22.90 0.00 6.06 0.00 0.00 2.77 0.00 0.00 0.00 68.28
Average: 1 20.58 0.00 6.62 0.00 0.00 2.69 0.00 0.00 0.00 70.11
Average: 2 19.65 0.00 6.17 0.00 0.00 2.98 0.00 0.00 0.00 71.19
Average: 3 15.49 0.00 8.00 0.00 0.00 3.08 0.00 0.00 0.00 73.44
Average: 4 12.87 0.00 5.56 0.00 0.00 1.85 0.00 0.00 0.00 79.71
Average: 5 13.59 0.00 4.94 0.00 0.00 1.85 0.00 0.00 0.00 79.61
Average: 6 12.38 0.00 4.75 0.00 0.00 1.96 0.00 0.00 0.00 80.91
Average: 7 13.30 0.00 5.36 0.00 0.00 1.96 0.00 0.00 0.00 79.38
1
owenliang 2017-11-14 14:57:49 +08:00
可以看一下 SDK 的实现,是否采用了不合理的非阻塞网络操作,比如 nonblock 的 loop read,或者 nonblock 的 select wait ?
|
2
torbrowserbridge 2017-11-14 15:22:46 +08:00 via Android
@owenliang 哪里有 SDK
|
3
lslqtz 2017-11-14 17:12:52 +08:00 via iPhone
请求变慢,请求数量每秒一样,那应该很正常吧
|
4
owenliang 2017-11-14 17:14:01 +08:00 via Android
@torbrowserbridge 你调用服务用的啥
|
5
picone 2017-11-14 17:42:00 +08:00
刚试了下,循环的 curl_exec 请求网络,等待数据返回不占用 CPU 时间。
|
6
dawncold 2017-11-14 21:34:48 +08:00
netstat 的 sendq 和 recvq
|
7
gouchaoer 2017-11-14 23:57:16 +08:00 via Android 1
尽量不要在 php-fpm 中 http 阻塞访问第三方服务,因为如果这个 http 服务 3 秒返回,你单机开了 300 个 php-fpm 吧,那你 qps 还是 100。。。但是 php-fpm 的阻塞又非常简单,所以解决办法很简单,你多开 php-fpm 就 ok 了,单机开个几千个 cpu 还是可以调度过来,只要你内存够。。。。你想优化?上 workerman 的异步,或者 swoole 的半协程,或者 swoole 的协程,或者换 go 吧
|
8
shiny 2017-11-15 00:16:06 +08:00
是用 file_get_contents 还是 cURL 请求的?几年前试过,同样的 http 地址,file_get_contents 会有较高的 CPU 使用率。
|
9
Zephyros 2017-11-29 02:56:36 +08:00
给你帖一个 top 命令的一些解释,希望有用:
us - user cpu time (or) % CPU time spent in user space sy - system cpu time (or) % CPU time spent in kernel space ni - user nice cpu time (or) % CPU time spent on low priority processes id - idle cpu time (or) % CPU time spent idle wa - io wait cpu time (or) % CPU time spent in wait (on disk) hi - hardware irq (or) % CPU time spent servicing/handling hardware interrupts si - software irq (or) % CPU time spent servicing/handling software interrupts st - steal time % CPU time in involuntary wait by virtual cpu while hypervisor is servicing another processor (or) % CPU time stolen from a virtual machine |
10
Zephyros 2017-11-29 03:10:00 +08:00
php 即可以单独一个进程运行,也可以作为 Apache 等其他进程的子线程,具体取决于你的服务器是怎么装的 php。
直接这么用 top 命令的话,你可能还需要看运行 php 进程的用户是谁,究竟是 root 用户还是其他用户,再者,又因同一个用户的所有进程都合在一起了,似乎不太好看。 若要看到每进程的 CPU 使用情况,建议你用 ps aux 命令试试,(或者用 ps -ef )。 |
11
Zephyros 2017-11-29 03:13:54 +08:00 1
给你一个测试的建议:php 自带一个 sleep 函数,你可以在虚拟机上单独搞一个服务器,故意让它休眠个 10 秒再返回,就当是模拟第三方延迟了 10 秒。然后用另一台机器(物理机可能较好)测试,看 CPU 等资源是否有变。
|
12
Zephyros 2017-11-29 04:01:53 +08:00
另一个测试建议:故意制造一些特别吃 CPU 的程序,观察效果。比如 password_hash 就是一个特别吃 CPU 的函数。
http://php.net/manual/en/function.password-hash.php 其他比较吃 CPU 的算法有 MD5,SHA1 等。一般的算法,只要是纯计算,不涉及磁盘网络等的,多循环个若干次也能起到吃 CPU 的效果。 |