zoukankan      html  css  js  c++  java
  • php项目,cpu暴增问题查找

    背景:

    前几天通过WordPress上线一个应用(前后台部署分离,后台走内网内部使用,前台做了全站缓存对外使用)。

    今天访问后台应用发现开始报504,一段时间后全部504.

    解决方案:

    登录容器发现容器内nginx日志全部499。

    通过top指令发现php-fpm占用cpu暴增。

    netstat -anp|grep 'php-fpm端口号'  发现所有php-fpm状态都为syn_recv(服务端被动打开后,接收到了客户端的SYN并且发送了ACK时的状态)

    所有php-fpm状态都为syn_recv,导致控制SYNqueue的队列数量满,所有新的请求直接拒绝。

    立马通过strace命令进行追踪pid,发现一直在循环执行gettimeofday等一些函数

    网上查找资料说如果开启xdebug扩展会引发这样的状况,通过php -m发现果然使用了xdebug,关闭此扩展,重启php-fpm。

    进行观察发现,cpu使用率平稳,php-fpm状态正常,一切正常。

    总结:

    线上不要开启xdebug扩展,为什么xdebug会引起此种问题,暂时未深入了解,但是xdebug性能低不适合线上使用,建议使用php_trace扩展代替

    通过php_trace来检测php代码执行流程,关于怎样使用php_trace,可查看之前所写的文章。(php_trace为360开源的工具,性能强大,经他们测试在线上只会损耗百分之几左右的性能)

    开启php-fpm状态监控,最好能增加报警机制,已及时发现与获取问题原因。

    解释:

    这里有必要解释下, TCP连接为什么会积压在队列里, 要理解这个问题, 需要先理解linux 对TCP 三次握手的一些具体实现。

    我们知道, 在server端,监听一个端口, 调用socket,bind 最后调用listen:

    int listen(intsockfd, int backlog);
    

    listen的第二个参数叫做backlog, 用来设置连接队列的大小。实际Linux 维护两个队列, 一个是在接收到SYN后,此时没有完成三次握手, 处于半连接状态,存放到SYNqueue(我们的问题就是发生在此处),

    另一个是三次握手完成后, 成功建立连接,存放到acceptqueue,等待应用调用accept 来消费队列。这里的backlog就是用来设置accept queue(旧版内核用来设置SYN queue,详细请man listen)的大小。

    TCP 传输跟系统调用实际是一个异步的过程, 系统通过队列来保存最新的TCP状态或数据。也就是说,TCP三次握手由内核来完成, 跟应用层是否调用accept无关, 内核将完成三次握手的socket 放到acceptqueue中,应用调用accept 时,从accept queue中获取连接。那么,如果backlog 非常大,而我又不及时调用accept 来消费队列,则连接就被积压到accept queue中了。

    同样, 在三次握手完成后, 客户端就可以发送数据了, 数据由内核接收, 并保存在TCP 的buffer中, 而此时应用(PHP)可能还没有调用accept。

    最后感谢一下曾经的面试官,因为之前有问到如何查找线上cpu暴增问题,后来查找了下基本资料,没想到这次用到了。。

  • 相关阅读:
    Weex系列-入门2
    Weex系列-入门1
    Android ClassLoader笔记(二)
    Android ClassLoader笔记(一)
    Android-DataBinding入门系列(一)基本介绍
    Fiddler简单介绍
    colorWithPatternImage导致的图片错位问题
    自定义view-滑动开关
    ios设置行间距和部分文本颜色
    办公利器-一行代码搞定http服务
  • 原文地址:https://www.cnblogs.com/tangchuanyang/p/6601167.html
Copyright © 2011-2022 走看看