瞬发大量并发连接 造成MySQL连接不响应的分析
http://www.actionsky.com/docs/archives/252
?2016年12月7日目錄
- 1?現象
- 2?猜想
- 3?檢查環境
- 4?猜想2
- 5?分析
- 5.1?TCP握手的第三步ACK包為什么丟失
- 6?恢復故障與日志的正關聯
- 7?解決方案
現象
Sysbench對MySQL進行壓測, 并發數過大(>5k)時, Sysbench建立連接的步驟會超時.
猜想
猜想: 直覺上這很簡單, Sysbench每建立一個連接, 都要消耗一個線程, 資源消耗過大導致超時.
驗證: 修改Sysbench源碼, 調大超時時間, 仍然會發生超時.
檢查環境
猜想失敗, 回到常規的環境檢查:
猜想2
懷疑 MySQL 在應用層因為某種原因, 沒有發送握手包, 比如卡在某一個流程上:
懷疑是OS的原因, Google之, 得到參考文檔:?A TCP “stuck” connection mystery
分析
參考文檔中的現象跟目前的狀況很類似, 簡述如下:
正常的TCP連接流程:
當發生類似SYN-flood的現象時, TCP連接的流程會使用SYN-cookie, 變為:
當啟用SYN-cookie時, 第3步的ACK包因為?某種原因?丟失, 那么:
發生這種情況時:
TCP握手的第三步ACK包為什么丟失
參考文檔中, 對于TCP握手的第三步ACK包的丟失原因, 描述為:
Some of these packets get lost because some buffer somewhere overflows.我們可以通過Systemtap進一步探究原因. 通過一個簡單的腳本:
probe kernel.function("cookie_v4_check").return {source_port = @cast($skb->head + $skb->transport_header, "struct tcphdr")->sourceprintf("source=%d, return=%d\n", readable_port(source_port), $return) }function readable_port(port) {return (port & ((1<<9)-1)) << 8 | (port >> 8) }觀察結果, 可以確認cookie_v4_check?(syn cookie機制進行包簽名檢查的函數)會返回 NULL(0). 即驗證是由于syn cookie驗證不通過, 導致TCP握手的第三步ACK包不被接受.
之后就是對其中不同條件進行觀察, 看看是哪個條件不通過. 最終原因是accept隊列滿 (sk_acceptq_is_full):
796 static inline bool sk_acceptq_is_full(const struct sock *sk) 797 { 798 return sk->sk_ack_backlog > sk->sk_max_ack_backlog; 799 }恢復故障與日志的正關聯
在故障處理的一開始, 我們就檢查了syslog, 結論是未見異常.
當整個故障分析完成, 得知了故障與syn cookie有關, 回頭看syslog, 里面是有相關的信息, 只是和故障發生的時間不匹配, 沒有正關聯, 因此被忽略.
檢查Linux源碼:
6130 if (!queue->synflood_warned && 6131 sysctl_tcp_syncookies != 2 && 6132 xchg(&queue->synflood_warned, 1) == 0) 6133 pr_info("%s: Possible SYN flooding on port %d. %s. Check SNMP counters.\n", 6134 proto, ntohs(tcp_hdr(skb)->dest), msg);可以看到日志受到了抑制, 因此日志與故障的正關聯被破壞.
粗看源碼, 每個listen socket只會發送一次告警日志, 要獲得日志與故障的正關聯, 必須每次測試重啟MySQL.
解決方案
這種故障一旦形成, 難以檢測; 系統日志中只會出現一次, 在下次重啟MySQL之前就不會再出現了; Client如果沒有合適的超時機制, 萬劫不復.
解決方案:
1. 修改MySQL的協議, 讓Client先發握手包. 顯然不現實.
2. 關閉syn_cookie. 有安全的人又要跳出來了.
3. 或者調高syn_cookie的觸發條件 (syn backlog長度). 降低系統對syn flood的敏感度, 使之可以容忍業務的syn波動.
有多個系統參數混合影響syn backlog長度, 參看http://blog.dubbelboer.com/2012/04/09/syn-cookies.html?
總結
以上是生活随笔為你收集整理的瞬发大量并发连接 造成MySQL连接不响应的分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: css行高line-height的一些深
- 下一篇: redis-redisTemplate模