zoukankan      html  css  js  c++  java
  • 记录一次lnmp故障报告

    业务架构图:

    nginx 状态监控图:

    本次故障的表现为:前端php页面无法打开,空白页或者502错误。

    nginx中php配置如下:

    location ~ .php$ {
        root                /xxx/xxx;
        fastcgi_pass        unix:/dev/shm/php-cgi.sock;
        fastcgi_index       index.php;
        include             fastcgi.conf;
        access_log          logs/fastcgi.log ngx_Web_log;
    }

    首先查看 logs/fastcgi.log 如下:

    统计nginx和php交互状态码如下:

       总数    状态码
     233694    499
      55891    200
      34029    302
        100    500

    可以发现日志里大量的出现了499的状态码,百度说明:

    nginx源码:

    /*
    * HTTP does notdefine the code for the case when a client closed
    * the connectionwhile we are processing its request so we introduce
    * own code to logsuch situation when a client has closed the connection
    * before we even tryto send the HTTP header to it
    */
    #define NGX_HTTP_CLIENT_CLOSED_REQUEST 499

    这是nginx定义的一个状态码,用于表示这样的错误:服务器返回http头之前,客户端就提前关闭了http连接

    简单来说,由于后端服务处理时间过长而导致前端nginx等待超时断开。

    查看nginx状态监控图发现active在这个时间段,活动连接一直保持在3000左右,根据经验,日常活动连接数一般在900左右,这次突然上了3000,有可能是攻击所致。

        1. 查看网络连接数:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
        2. 过滤fastcgi.log访问连接ip数量,通过nginx deny禁止掉可疑ip。

    经过上面的处理后,活动连接数的变化不是很明显。于是在程序中添加info.php来测试php响应情况。

    测试结果:
        重启php-fpm 大概10秒后,就无法再次访问info.php ,大致估计是因为php accept queue 被占满所致。查看一下内核参数是否正常:

    # ulimit -n     # 文件最大描述符
    
    # sysctl -a | egrep "tw|backlog|cookies|synack|soconnmax" 
    
    net.core.netdev_max_backlog = 262144         # 程序accept queue队列长度
    net.ipv4.tcp_max_syn_backlog = 262144         # syn queue 队列长度
    net.ipv4.tcp_max_tw_buckets = 6000             # 保持 TIME_WAIT 最大值
    net.ipv4.tcp_synack_retries = 1             # 服务端发送syn + ack 包次数限制
    net.ipv4.tcp_syncookies = 1                 # 启用syn cookies,当syn等待队列出现溢出时,启用cookies来处理,可以防范少量的syn攻击
    net.ipv4.tcp_tw_recycle = 1                 # TIME_WAIT 状态快速回收
    net.ipv4.tcp_tw_reuse = 1                     # TIME_WAIT 状态快速重用

    一些常用的内核参数都是没有问题的。

    问题总汇下:
        1. nginx fastcgi.log 大量返回499
        2. nginx 活动连接数远远高于正常业务并发
        3. php 重启很快就失去响应。

    这时候发现问题排查起来有点困难了,于是和开发、数据库沟通下。

    沟通下来的结果就是:
        早上数据库被DBA调整过。出现过停止服务的状态,而开发人员通过java开发的api是要去连接数据库的。
        请求从nginx进来,通过php去调用java接口,而java接口无法连接上数据库无法将数据返回给php,所以nginx等待超时返回499

    沟通后思路清晰了,早上DBA动MySQL没有通知到大家,造成了这一系列连锁反应。可见,通知和沟通是很重要的。

    重启java程序,php正常返回结果,业务恢复正常。

    最后,做技术不能只是关注技术本身,熟悉业务流程和沟通也是作为运维人员必备的技能。

  • 相关阅读:
    关于i 标签盛放背景图像
    关于首行缩进
    复选框样式自定义
    创建对象的两种方法
    SpringBoot项目中常见的注解
    微服务 第一章:Idea快速创建SpringBoot项目
    Exception in thread "Thread-1" java.util.ConcurrentModificationException 异常原因和解决方法
    《改善java代码》第四章:改善关于字符串的代码
    IDEA忽略不必要提交的文件
    Git分支管理
  • 原文地址:https://www.cnblogs.com/hukey/p/6739053.html
Copyright © 2011-2022 走看看