瞬发大量并发连接 造成MySQL连接不响应的分析
http://www.actionsky.com/docs/archives/252
?2016年12月7日目錄
- 1?現(xiàn)象
- 2?猜想
- 3?檢查環(huán)境
- 4?猜想2
- 5?分析
- 5.1?TCP握手的第三步ACK包為什么丟失
- 6?恢復故障與日志的正關聯(lián)
- 7?解決方案
現(xiàn)象
Sysbench對MySQL進行壓測, 并發(fā)數(shù)過大(>5k)時, Sysbench建立連接的步驟會超時.
猜想
猜想: 直覺上這很簡單, Sysbench每建立一個連接, 都要消耗一個線程, 資源消耗過大導致超時.
驗證: 修改Sysbench源碼, 調大超時時間, 仍然會發(fā)生超時.
檢查環(huán)境
猜想失敗, 回到常規(guī)的環(huán)境檢查:
猜想2
懷疑 MySQL 在應用層因為某種原因, 沒有發(fā)送握手包, 比如卡在某一個流程上:
懷疑是OS的原因, Google之, 得到參考文檔:?A TCP “stuck” connection mystery
分析
參考文檔中的現(xiàn)象跟目前的狀況很類似, 簡述如下:
正常的TCP連接流程:
當發(fā)生類似SYN-flood的現(xiàn)象時, TCP連接的流程會使用SYN-cookie, 變?yōu)?
當啟用SYN-cookie時, 第3步的ACK包因為?某種原因?丟失, 那么:
發(fā)生這種情況時:
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機制進行包簽名檢查的函數(shù))會返回 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 }恢復故障與日志的正關聯(lián)
在故障處理的一開始, 我們就檢查了syslog, 結論是未見異常.
當整個故障分析完成, 得知了故障與syn cookie有關, 回頭看syslog, 里面是有相關的信息, 只是和故障發(fā)生的時間不匹配, 沒有正關聯(lián), 因此被忽略.
檢查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);可以看到日志受到了抑制, 因此日志與故障的正關聯(lián)被破壞.
粗看源碼, 每個listen socket只會發(fā)送一次告警日志, 要獲得日志與故障的正關聯(lián), 必須每次測試重啟MySQL.
解決方案
這種故障一旦形成, 難以檢測; 系統(tǒng)日志中只會出現(xiàn)一次, 在下次重啟MySQL之前就不會再出現(xiàn)了; Client如果沒有合適的超時機制, 萬劫不復.
解決方案:
1. 修改MySQL的協(xié)議, 讓Client先發(fā)握手包. 顯然不現(xiàn)實.
2. 關閉syn_cookie. 有安全的人又要跳出來了.
3. 或者調高syn_cookie的觸發(fā)條件 (syn backlog長度). 降低系統(tǒng)對syn flood的敏感度, 使之可以容忍業(yè)務的syn波動.
有多個系統(tǒng)參數(shù)混合影響syn backlog長度, 參看http://blog.dubbelboer.com/2012/04/09/syn-cookies.html?
總結
以上是生活随笔為你收集整理的瞬发大量并发连接 造成MySQL连接不响应的分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: css行高line-height的一些深
- 下一篇: linux cmake编译源码,linu