精品国产一级在线观看,国产成人综合久久精品亚洲,免费一级欧美大片在线观看

模擬百萬級(jí)TCP并發(fā)

責(zé)任編輯:editor007

作者:邢森

2017-01-09 20:11:02

摘自:51CTO

TCP并發(fā)是指一個(gè)服務(wù)器同時(shí)“hold住”的連接數(shù)量,確切的說就是指服務(wù)器端看到的“ESTABLISHED”狀態(tài)的TCP連接數(shù)量。通過libpcap我們可以獲取所有的數(shù)據(jù)包(即便操作系統(tǒng)不處理)然后構(gòu)造自己的數(shù)據(jù)包通過raw socket直接把寫入到數(shù)據(jù)鏈路層。

什么是TCP并發(fā)

TCP并發(fā)是指一個(gè)服務(wù)器同時(shí)“hold住”的連接數(shù)量,確切的說就是指服務(wù)器端看到的“ESTABLISHED”狀態(tài)的TCP連接數(shù)量。通過netstat -n|grep ^tcp|awk '{print $NF}'|sort -nr|uniq -c可以查看當(dāng)前服務(wù)器TCP狀態(tài)統(tǒng)計(jì)報(bào)告,下圖是我的執(zhí)行結(jié)果(我正在通過SSH連接這臺(tái)機(jī)器所以有一個(gè)“ESTABLISHED”狀態(tài)的TCP連接)

  測(cè)試TCP并發(fā)就是指讓這個(gè)值達(dá)到的頂峰,要實(shí)現(xiàn)這個(gè)必須滿足兩點(diǎn):

短時(shí)間內(nèi)構(gòu)造百萬級(jí)連接服務(wù)器端同時(shí)hold住百萬級(jí)連接

需要注意的是上面的“測(cè)試”不包括“連接之后的交互”僅僅是指“hold住連接”。

傳統(tǒng)工具為什么無法滿足

很多服務(wù)器都是TCP結(jié)構(gòu)的比如Mysql、Tomcat、Nginx,這些工具也有相應(yīng)的壓力測(cè)試工具,比較著名的包括:Jmeter、Tsung。這些工具的實(shí)現(xiàn)基本上是一致的

同時(shí)啟動(dòng)多個(gè)任務(wù)每個(gè)任務(wù)打開一個(gè)socket連接到服務(wù)器

這種測(cè)試方法受限于三個(gè)資源

可以啟動(dòng)的任務(wù)數(shù)量(線程數(shù)或者進(jìn)程數(shù))可以打開的socket數(shù)量(文件描述符)受限于本機(jī)可用端口最大值——65535

第一個(gè)限制我們可以通過“協(xié)程”之類的技術(shù)手段解決;第二個(gè)限制在內(nèi)存滿足的情況下可以通過調(diào)整系統(tǒng)參數(shù)解決(參考我的《你真知道“Too many open files”?》);第三個(gè)限制幾乎是致命的——傳統(tǒng)上只能通過多臺(tái)服務(wù)器一塊協(xié)同。

即便解決了上述三個(gè)問題也很難在“短時(shí)間”內(nèi)造成巨大的壓力,大量的socket會(huì)吃光內(nèi)存,多臺(tái)服務(wù)器協(xié)同必然是一個(gè)分布式問題(想想就掉頭發(fā))。

新的思路

TCP連接給人的感覺是一個(gè)“通道”,這其實(shí)這是一個(gè)“錯(cuò)覺”。所有的網(wǎng)絡(luò)基本上都是基于“存儲(chǔ)轉(zhuǎn)發(fā)”的經(jīng)過。三次握手之后的TCP連接到達(dá)“ESTABLISHED”狀態(tài),服務(wù)器會(huì)為它保留資源——即使客戶端已經(jīng)不再理睬這個(gè)連接。那么我們是不是可以不經(jīng)過TCP/IP協(xié)議棧直接通過raw socket構(gòu)造三次握手呢?只要我們大批量的構(gòu)造三次握手就可以對(duì)服務(wù)器構(gòu)成巨大的壓力了。

我們重點(diǎn)關(guān)注Client->Server的兩個(gè)箭頭。第一個(gè)數(shù)據(jù)包是SYN數(shù)據(jù)包,seq=隨機(jī)數(shù);第二個(gè)數(shù)據(jù)包是ACK數(shù)據(jù)包,ACK=收到數(shù)據(jù)包的seq+1,seq=收到數(shù)據(jù)包的ack。其實(shí)TCP數(shù)據(jù)包之間是沒有直接關(guān)系的,我們收到一個(gè)數(shù)據(jù)包就可以直接算出回復(fù)數(shù)據(jù)包的ack、seq

上面的思路基本上可以證明我們的方法在理論上是可行的,在實(shí)踐上我們還需要克服一些問題

怎么獲取Server到Client的SYN+ACK(三次握手中的第二個(gè)箭頭);畢竟我們不是直接使用Socket打開TCP連接(這樣做就不需要自己構(gòu)造TCP三次握手了)Server在收到Client請(qǐng)求后會(huì)嘗試對(duì)Client進(jìn)行ARP地址,如果發(fā)現(xiàn)無法解析就認(rèn)為是一個(gè)非法的數(shù)據(jù)包直接發(fā)送RST數(shù)據(jù)包關(guān)閉TCP連接

第一個(gè)問題我們通過libpcap“旁路”kernel,直接獲取原始數(shù)據(jù)包。下圖是libpcap的原理

libpcap底層使用的是BPF(Berkeley Packet Filter)驅(qū)動(dòng),這是kernel中專門用來“調(diào)試”的驅(qū)動(dòng)程序最早是為Unix開發(fā)現(xiàn)在已經(jīng)成為各種操作系統(tǒng)的標(biāo)配(只要支持tcpdump那么底層一定是有實(shí)現(xiàn)這個(gè)驅(qū)動(dòng)模型的)。它獨(dú)立于kernel中的其他協(xié)議棧直接和讀取數(shù)據(jù)鏈路層的數(shù)據(jù)包。

通過libpcap我們可以獲取所有的數(shù)據(jù)包(即便操作系統(tǒng)不處理)然后構(gòu)造自己的數(shù)據(jù)包通過raw socket直接把寫入到數(shù)據(jù)鏈路層。整個(gè)“收包”->“處理”->“回包”完全不需要kernel參與。

第二個(gè)問題其實(shí)在前面的文章中我已經(jīng)給出了答案——構(gòu)造并且回復(fù)ARP數(shù)據(jù)包(《深入理解ARP攻擊 》)。簡(jiǎn)單來說就是通過libpcap獲取arp request,通過raw socket回復(fù)arp response。

動(dòng)手

我努力去掉所有不相關(guān)的東西只保留了最精簡(jiǎn)的部分,不到300行的代碼。代碼分為兩大部分“發(fā)起TCP SYN數(shù)據(jù)包”和“回復(fù)SYN+ACK數(shù)據(jù)包、ARP request數(shù)據(jù)包”。具體內(nèi)容可以看這里

這次我特意放上了cmake文件,執(zhí)行以下cmake就可以編譯了。

https://github.com/fireflyc/million-tcp-client

模擬多個(gè)IP地址

受限于端口上限,一臺(tái)服務(wù)器只能模擬65535個(gè)TCP連接。但是我提供的演示程序是可以指定IP地址的,這個(gè)IP地址只需要和目標(biāo)IP在同一個(gè)網(wǎng)絡(luò)內(nèi)就可以了。比如我的測(cè)試環(huán)境:

測(cè)試機(jī)器有自己的IP地址172.16.46.128,但是這個(gè)IP地址并沒有用途,只是為了方便我SSH連接。服務(wù)器的IP地址是172.16.46.133,我啟動(dòng)三個(gè)tcp-client分別綁定200、201、202。

每個(gè)TCP-Client進(jìn)程都可以模擬65535個(gè)TCP連接。(這個(gè)其實(shí)還有改進(jìn)的余地)

鏈接已復(fù)制,快去分享吧

企業(yè)網(wǎng)版權(quán)所有?2010-2025 京ICP備09108050號(hào)-6京公網(wǎng)安備 11010502049343號(hào)

  • <menuitem id="jw4sk"></menuitem>

    1. <form id="jw4sk"><tbody id="jw4sk"><dfn id="jw4sk"></dfn></tbody></form>
      主站蜘蛛池模板: 句容市| 绥德县| 贵德县| 重庆市| 孝感市| 特克斯县| 从化市| 罗城| 化隆| 琼海市| 四平市| 页游| 望谟县| 漾濞| 泗洪县| 徐闻县| 西盟| 承德市| 铜梁县| 海晏县| 镇沅| 墨玉县| 阿合奇县| 滦南县| 彰化市| 陇南市| 双流县| 辉县市| 清水河县| 马公市| 陆良县| 九台市| 宜良县| 洮南市| 江都市| 绵竹市| 峨眉山市| 阜平县| 新河县| 扶风县| 河池市|