zoukankan      html  css  js  c++  java
  • 论坛---挂掉的思考

    某天,某dz论坛整站垮掉,事后分析:遭遇cc攻击,非常多的肉机(不同IP)对该论坛某个特定的url进行访问,造成整站瘫痪。

    排查思路

    如果遇到整站瘫痪,我们应该怎么办?

    1,测试静态页面,检测web-server是否正常,通常是正常的

    2,测试php页面,检测php是否正常,两种状态都有可能,大部分是正常的,少数情况异常

    3,手工连接数据,测试连通性,执行show processlist,查慢sql

    4,查access-log,慢请求肯定会在access-log中体现,大部分情况查慢请求能迅速定位问题

    因为请求慢才会造成后续请求阻塞进而出现问题,请求足够快就不会有问题。

    请求慢的原因

    可能1:php跑满了,请求被饿死(深层原因还是请求慢,这是表象);

    可能2:应用程序内部逻辑问题,有互锁,死循环,函数处理慢要优化(注意,内存溢出不属于此类);

    可能3:io阻塞(写文件慢,目前未碰到过),sql慢(因为sql必须等待执行结束才会返回,未结束会一直等待,即使客户端主动断开,mysql有可能还会一直执行,sql慢是碰到最多的)

    另,内存溢出一定会报php错误,会被记录在php错误日志中,会返回500的错误,只会影响单次执行,不会影响后续请求。

    access-log已经多次为排查事故原因做出了贡献。

    CC攻击案例分析

    我们根据access-log来还原下这次cc攻击下webserver和系统的表现。

    攻击从10:45:48开始一直持续到10:52:05,10:55:22恢复正常,持续10分钟。

    第一阶段:10:45:48到10:46:50,整站沦陷

    [30/Oct/2014:10:45:48 +0800] "GET /status.php HTTP/1.0" 499 0 "-" "KeepAliveClient" 82 4.999 -

    [30/Oct/2014:10:45:48 +0800] "GET /search.php?searchsubmit=yes HTTP/1.1" 499 0 "-" "Mozilla/4.0" 142 30.000 -

    攻击一开始,大量的攻击请求打过来,整站瞬间塌陷,响应全部超过30秒,返回499状态码

    单台机器的攻击请求数是50个/秒,从第一秒开始所有php请求均响应失败返回499(30秒为客户端连接nginx超时,客户端主动断开连接),图片请求正常,status.php也返回499(估计检测脚本设置nginx连接超时是5秒)。这段时间内lvs已经知道nginx无法连接(间接说明了nginx处理php特别慢),但是没做下线处理

    第二阶段:10:46:50-10:51:13,LVS下线前端机,重启php-fpm

    lvs认为前端机确实有问题,执行下线操作。在此期间,一直有status心跳探测。我们看到了这样的日志:

    [30/Oct/2014:10:46:56 +0800] "GET /status.php HTTP/1.1" 504 182 "-" "-" 50 60.002 -

    [30/Oct/2014:10:46:56 +0800] "GET /thread-3029964-1-1.html HTTP/1.1" 504 ... 60

    [30/Oct/2014:10:46:56 +0800] "GET /status.php HTTP/1.0" 499 0 "-" "KeepAliveClient" 82 5.000 -

    分析:第三条日志,5秒+499,是正常的status脚本检测,执行时间为5秒,连接nginx超时;

    第一条日志为什么会是60秒超时呢?

    合理的解释:client到nginx已建立连接,但nginx到php连接失败,socket_timeout设置为60s,连接超时退出,nginx返回给客户端504。(同时能知道,access-log是在执行结束后记录的,实际请求时间=日志时间减去执行时间)

    那么这样就容易解释第二条日志了,和第一条日志一样的原理。可以看到,超时时间是60秒,请求时间是10:45:56,请求是在cc攻击之后发生的,cc攻击之后请求处理有两类,一类返回499(连接nginx超时,被客户端断开),另一类返回504(nginx连接php超时)

    部分结论:status.php连接nginx超时返回499,连接nginx成功但nginx连php失败会返回504。

    第三阶段:10:51:13-10:52:05,前端机上线,攻击继续,多次重启php-fpm,10:55:22恢复正常

    [30/Oct/2014:10:51:12 +0800] "GET /status.php HTTP/1.1" 200 13 "-" "-" 50 13.673 -

    怀疑,lvs判断status是正常的,所以上线前端机。

    攻击日志如下:

    [30/Oct/2014:10:51:26 +0800] "GET /search.php?searchsubmit=yes HTTP/1.1" 499 0 "-" "Mozilla/4.0" 143 29.993 -

    恢复后的第一条200日志:

    [30/Oct/2014:10:55:22 +0800] "GET /forum-77-489.html HTTP/1.1" 200 

    上线处理了些正常请求后又遭攻击,攻击在10:52:05停止后,打出了些504连接超时的语句,在10:55:22恢复正常。

    我认为,主因是客户端瞬间连接太多,导致nginx连接数打满,php连接数打满,和mysql关系不大。 

    那么针对cc攻击,需要做什么事情呢?

    php版本升级?可以查slowlog,但不是防cc的解决方案,瞬间打满php,处理多快都没用。

    增加前端机?能够增加nginx和php连接数,可以缓解CC攻击带来的冲击。

    优化mysql?和mysql没直接关系,不是防cc的解决方案。

    接扛攻击集群?让集群来扛量和过滤非法IP,是个不错的解决方案。

    环境变量

    nginx.conf,php连接超时是300s

    etc/php-fpm.conf,请求执行超时是31s

    lib/php.ini, default_socket_timeout = 60

    额外了解到的

    502:Bad gateway。如果脚本运行时间很长,比如循环80次,每次等待1秒,nginx会返回502。这意味着,client-nginx连接成功,nginx-php连接成功,但php耗时太长

    499:NGX_HTTP_CLIENT_CLOSED_REQUEST。客户端关闭请求。这意味着,client-nginx连接失败

    504:Gateway Time-out。用户连接该服务器,该服务器作为网关请求上游服务器,上游服务器响应超时。这意味着,client-nginx连接成功,(nginx-php连接失败,或者连接成功,但是一直没处理该php)

    Reference

    nginx状态码解释:http://www.daniel-journey.com/archives/1699

    504相关:http://wenku.it168.com/d_000790933.shtml

  • 相关阅读:
    PHP之旅3 php数组以及遍历数组 以及each() list() foreach()
    NSSetUncaughtExceptionHandler
    runtime
    Objective-C中的instancetype和id区别
    tableView 局部刷新
    CGAffineTransform
    iOS中文本属性Attributes
    ios 相机 自定义 相片的截取
    php程序的生命周期
    PHP代码执行流程
  • 原文地址:https://www.cnblogs.com/helww/p/4078256.html
Copyright © 2011-2022 走看看