色五月色开心色婷婷色丁香,五月婷婷丁香花综合网,婷婷丁香五月激情综合在线,五月婷婷六月丁香动漫,婷婷丁香五月激情综合在线,丁香花中文字幕在线观看,播五月色五月开心五月网,开心激情综合网,狠狠色丁香婷婷综合最新地址,丁香视频在线观看,狠狠做六月爱婷婷综合av,久久激情五月丁香伊人

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運營的一線實戰(zhàn)洞察。

網(wǎng)絡(luò)IO模型詳解:阻塞IO、IO多路復(fù)用、epoll與異步IO選型

網(wǎng)絡(luò)IO模型詳解:阻塞IO、IO多路復(fù)用、epoll與異步IO選型 1. 把一次網(wǎng)絡(luò)讀寫拆到內(nèi)核里看線上有個服務(wù)QPS 壓到三千左右就上不去了機器 CPU 看著不高但top里sy系統(tǒng)態(tài)占比一直壓在 40% 以上load也不高連接數(shù)上不去也不掉。一開始懷疑是數(shù)據(jù)庫換了幾輪慢查詢優(yōu)化沒效果后來又懷疑帶寬不對抓包一看每個請求的往返都很正常。最后把線程棧 dump 下來發(fā)現(xiàn)幾百個工作線程全卡在同一個recv調(diào)用上一半在等數(shù)據(jù)、一半在等鎖。問題不在業(yè)務(wù)代碼在于整個服務(wù)的網(wǎng)絡(luò) IO 模型選錯了——線程池 阻塞 IO 硬扛長連接連接一多線程全變擺設(shè)。這就是我想聊的話題。網(wǎng)絡(luò) IO 模型說白了就一件事當程序要讀網(wǎng)絡(luò)上的數(shù)據(jù)而數(shù)據(jù)還沒到的時候你的程序該干什么。是原地卡住等還是先回去干別的、過會兒再來問一遍還是干脆交給一個“哨兵”統(tǒng)一盯著誰的數(shù)據(jù)到了再通知誰。這五種做法就是常說的阻塞 IO、非阻塞 IO、IO 多路復(fù)用、信號驅(qū)動 IO、異步 IO。它們不是教科書里的名詞游戲每一種背后都對應(yīng)著一筆真實的成本賬線程數(shù)、內(nèi)存占用、上下文切換次數(shù)、以及你愿不愿意接受一定的編程復(fù)雜度。這篇文章寫給三類人。第一類是寫業(yè)務(wù)代碼的平時用框架用得很順但遇到連接數(shù)暴漲、超時莫名其妙、CPU 空轉(zhuǎn)這些問題時不知道該往哪個方向查第二類是準備自己寫網(wǎng)絡(luò)服務(wù)的選型的時候需要知道每種模型的天花板在哪第三類是要應(yīng)對面試和架構(gòu)評審的光背“五種模型”的定義沒用得能說清楚為什么主流選擇是 epoll 那一套、為什么異步 IO 喊了這么多年落地卻不算多。下面的內(nèi)容我會從內(nèi)核里的一次讀操作開始拆一路講到代碼怎么寫、線上怎么排查。所有參數(shù)和步驟我都會給出為什么這么定而不是直接甩結(jié)論。1.1 從網(wǎng)卡到用戶緩沖區(qū)一次讀事件的完整路徑很多人對網(wǎng)絡(luò) IO 的理解停在“read 一個 socket 拿到數(shù)據(jù)”中間發(fā)生了什么是一片模糊。這片模糊恰恰是后面所有模型差異的來源所以必須先講清楚。假設(shè)客戶端發(fā)來一個數(shù)據(jù)包。網(wǎng)卡收到電信號通過 DMA 把數(shù)據(jù)寫進內(nèi)核里預(yù)先分配好的環(huán)形緩沖區(qū)ring buffer硬件隨即發(fā)一個中斷。內(nèi)核的中斷處理程序不會當場把數(shù)據(jù)一路解析上去那樣太慢它只做最輕量的事把數(shù)據(jù)包掛到軟中斷待處理隊列然后盡快返回。真正的協(xié)議棧處理在軟中斷里完成逐層剝掉以太網(wǎng)頭、IP 頭、TCP 頭根據(jù)四元組找到對應(yīng)的 socket把載荷數(shù)據(jù)追加到該 socket 的接收緩沖區(qū)里。如果這個 socket 上掛著一個正在睡眠等待的進程內(nèi)核喚醒它把它從等待隊列里挪回可運行隊列。到這一步為止數(shù)據(jù)已經(jīng)在內(nèi)核緩沖區(qū)里躺著了但你的程序還沒看見它。程序要真正拿到這段字節(jié)還需要一次數(shù)據(jù)拷貝從內(nèi)核空間的 socket 接收緩沖區(qū)復(fù)制到用戶空間你聲明的那塊內(nèi)存里。這次拷貝是 CPU 參與的繞不開除非用零拷貝那一套但那是另一個話題普通 socket 讀寫還是要拷。所以一次完整的網(wǎng)絡(luò)讀可以切成兩個階段階段一等待數(shù)據(jù)就緒數(shù)據(jù)從網(wǎng)卡到內(nèi)核緩沖區(qū)期間你的程序可能什么都做不了。階段二數(shù)據(jù)拷貝從內(nèi)核緩沖區(qū)到用戶緩沖區(qū)期間 CPU 在干活但你的程序依然處于系統(tǒng)調(diào)用之中。記住這兩個階段后面五種模型的區(qū)別全都在于“這兩個階段里進程到底在不在等、等在哪”。我在實際調(diào)試中經(jīng)常用一個很土的辦法驗證這個路徑在服務(wù)端recv之前加日志然后用ss -m看對應(yīng)連接的接收隊列。如果 Recv-Q 有值而你的程序還沒讀到說明數(shù)據(jù)已經(jīng)在內(nèi)核里了程序卡在階段二的入口如果 Recv-Q 是 0 而程序還在阻塞那就是階段一沒等到東西。這個判斷方法很粗糙但定位方向極其有效比盲目加日志快得多。順帶說一個容易忽略的點TCP 的接收窗口和內(nèi)核接收緩沖區(qū)是綁定的。如果你的程序讀得慢內(nèi)核緩沖區(qū)堆滿接收窗口就會縮小到零發(fā)送方被流控卡住。這時候表現(xiàn)出的“網(wǎng)絡(luò)慢”其實是應(yīng)用層讀得太慢不是帶寬問題。我在一個數(shù)據(jù)同步的場景里就遇到過對方一直抱怨傳輸慢最后發(fā)現(xiàn)是消費端每次只讀 1KB內(nèi)核緩沖區(qū)堆了 200KB 讀不出去。1.2 兩個階段的劃分決定了所有模型的差異把兩個階段攤開五種模型的差別就一目了然了我先用一段話把它們串起來后面再逐個拆。阻塞 IO兩個階段都在等。發(fā)起調(diào)用后進程被掛起數(shù)據(jù)到了、拷貝完了才返回。等待期間這個線程什么都干不了。非阻塞 IO第一個階段不等。調(diào)用立刻返回沒數(shù)據(jù)就告訴你沒數(shù)據(jù)errno 為 EAGAIN程序自己決定過多久再來問一次。第二個階段還是同步的數(shù)據(jù)拷貝時進程仍然在系統(tǒng)調(diào)用里。IO 多路復(fù)用第一個階段交給一個專門的系統(tǒng)調(diào)用去等。你一次性把一批 fd 注冊進去這個調(diào)用會阻塞在那里直到其中任意一個可讀可寫。也就是說一個線程能盯住成千上萬個連接。但注意它只是幫你“等到”拷貝還是你自己調(diào)recv來做所以本質(zhì)上仍然是同步 IO。信號驅(qū)動 IO第一個階段連等都不用等。注冊一個信號處理函數(shù)數(shù)據(jù)就緒時內(nèi)核發(fā) SIGIO 給你你在信號處理里再調(diào)recv。理論上很優(yōu)雅實際用得極少后面會說原因。異步 IO兩個階段都不需要你管。你發(fā)起一個讀請求附帶一塊緩沖區(qū)和回調(diào)或者一個完成事件然后立刻返回。內(nèi)核把數(shù)據(jù)等到、并且拷貝進你給的緩沖區(qū)之后才通知你“完事了”。這是真正的異步和前面四種有本質(zhì)區(qū)別。這里有個特別常見的誤解就是把 IO 多路復(fù)用當成異步 IO。很多文章寫著“NIO 就是非阻塞異步”這個說法很不嚴謹。Java 的 NIO 名字叫 Non-blocking I/O但它用的是多路復(fù)用底層是 epollSelector.select()返回可讀之后你還是得自己調(diào)channel.read()把數(shù)據(jù)從內(nèi)核拷到 ByteBuffer 里這一步是同步的。真正對標異步 IO 的是 JDK 7 引入的 NIO.2AIO或者 Linux 上的 io_uring。判斷一個 IO 是同步還是異步標準只有一條數(shù)據(jù)從內(nèi)核緩沖區(qū)到用戶緩沖區(qū)這一步是誰在做進程有沒有被阻塞。只要這一步是進程自己調(diào)用的那就是同步不管前面等得多花哨。這條標準我在評審方案時反復(fù)用能擋掉一大堆名詞包裝。理解了這層再看一個具體的現(xiàn)象為什么有些服務(wù)線程數(shù)不多但能扛上萬連接因為它把階段一交給了 epoll一個線程盯幾千個 fd只有真正有數(shù)據(jù)的連接才會被分配線程去處理階段二。這就是事件驅(qū)動的基本盤。反過來如果服務(wù)是一連接一線程的阻塞模型一萬連接就是一萬個線程光線程棧默認 8MB實際虛擬內(nèi)存物理頁按需分配和內(nèi)核調(diào)度開銷就能把機器拖垮。2. 五種網(wǎng)絡(luò) IO 模型的逐個拆解與適用邊界這一段是全文的主體我盡量把每種模型“為什么是這樣設(shè)計的”“在什么情況下會翻車”講透。不講空話每個結(jié)論都配一個能驗證它的現(xiàn)象。2.1 阻塞 IO最簡單也最容易被誤用的模型阻塞 IO 的調(diào)用鏈非常直白accept沒有新連接就卡住recv沒有數(shù)據(jù)就卡住send發(fā)送緩沖區(qū)滿了也卡住。進程被放進 socket 的等待隊列狀態(tài)變成可中斷睡眠CPU 完全不占用。數(shù)據(jù)到了內(nèi)核喚醒它它繼續(xù)往下走。它的優(yōu)點就一個字簡單。代碼是線性的讀完了就處理處理完了就寫回去心智負擔為零。所以它在兩類場景里活得很好。一類是連接數(shù)很少的內(nèi)部服務(wù)比如一個管理后臺幾十個并發(fā)用阻塞 IO 加線程池完全夠用沒必要上事件驅(qū)動。另一類是配合“一連接一線程”的模型做短連接服務(wù)請求處理很快連接生命周期很短線程復(fù)用池子能兜住。但它有兩個硬傷第一個是線程和連接綁定。假設(shè)每個連接平均每秒只有 10 個請求單次處理耗時 5ms那么這個連接 99.5% 的時間是空閑的可它依然占著一個線程。線程本身的開銷分幾塊內(nèi)核里的 task_struct、用戶態(tài)的棧、調(diào)度器維護的運行隊列節(jié)點還有上下文切換的成本。線程數(shù)上千之后調(diào)度器的紅黑樹操作和緩存失效會明顯拖慢整體sy占比會明顯上升。第二個硬傷是阻塞調(diào)用會傳染。你在一個請求里串行調(diào)了三個下游服務(wù)每個都可能卡住最壞情況下這個線程被占用的時間等于三個超時之和。如果下游抖動線程池很快被耗干新請求進來排隊超時擴散最終整個服務(wù)雪崩。我做壓測時見過一個典型現(xiàn)象并發(fā)從 500 加到 800TP99 從 80ms 跳到 3 秒但 CPU 使用率反而下降——這就是線程池打滿、大量線程在等下游的典型特征。要緩解就得給每個阻塞調(diào)用設(shè)超時并且用SO_RCVTIMEO或應(yīng)用層超時把等待時間卡住。但超時只是止血不解決根本問題你依然為每個連接付出了線程成本。一個經(jīng)驗判斷如果你的服務(wù)連接數(shù)長期在幾百以內(nèi)、單次處理耗時可控、沒有大量長連接比如推送、IM、訂閱阻塞 IO 加線程池是最省心的選擇。別為了“先進”去上事件驅(qū)動事件驅(qū)動的代碼復(fù)雜度和調(diào)試難度是另一個量級。還有一個坑要說清楚阻塞 IO 在accept上也有講究。監(jiān)聽 socket 默認是阻塞的如果accept返回后你處理連接花了很久期間新連接會堆在 backlog 隊列里。backlog 大小由listen(fd, backlog)指定實際生效值還受net.core.somaxconn限制。這兩個值不一致的時候以小的為準。很多服務(wù)連接建立慢、握手超時就是 backlog 給太小了。生產(chǎn)環(huán)境我會把somaxconn調(diào)到 4096 以上listen傳 1024 起步具體看連接建立速率。2.2 非阻塞 IO輪詢的代價與適用場景非阻塞 IO 就是把 fd 設(shè)成O_NONBLOCK然后調(diào)用立刻返回。沒數(shù)據(jù)時返回 -1 并置 errno 為 EAGAIN 或 EWOULDBLOCK在 Linux 上這兩個值相同。程序可以立刻去干別的事過會兒再來問。聽起來很美好但如果你真的寫一個while(true) { n recv(fd, buf, len, 0); if (n 0) break; }的循環(huán)你會發(fā)現(xiàn) CPU 直接 100%而且大部分時間在做無意義的系統(tǒng)調(diào)用。這就是忙輪詢是最糟糕的用法。系統(tǒng)調(diào)用本身有成本要從用戶態(tài)切到內(nèi)核態(tài)保存寄存器檢查權(quán)限處理完再切回來。一次可能幾百納秒但一秒做幾十萬次就是實打?qū)嵉拈_銷且這些開銷全部記賬在sy上。所以非阻塞 IO 單獨用幾乎沒有意義它必須和別的東西配合。最常見的配合方式有三種第一種是和多路復(fù)用配合這也是絕大多數(shù)場景的做法。先用 epoll 等到某個 fd 就緒再對這個 fd 用非阻塞方式讀寫。為什么就緒了還要非阻塞因為 epoll 的通知是“曾經(jīng)可讀”等你真正去讀的時候可能已經(jīng)被別的線程讀走了或者數(shù)據(jù)只到了一部分。非阻塞在這里是兜底保證你永遠不會因為一次讀寫把線程卡死。第二種是帶退避的輪詢。每次 EAGAIN 之后 sleep 一小段時間再來。這種方式在極低延遲要求的場景下偶爾用比如某些交易系統(tǒng)的行情拉取但絕大多數(shù)業(yè)務(wù)沒必要。退避時間的選擇很講究太短沒意義太長丟延遲。第三種是非阻塞加自旋加協(xié)程調(diào)度。協(xié)程庫在遇到 EAGAIN 時會把當前協(xié)程掛起把 CPU 讓給別的協(xié)程等 fd 就緒了再喚醒。對上層來說代碼是同步寫法實際執(zhí)行是事件驅(qū)動的。這也是現(xiàn)在很多語言 runtime 的做法。這里必須點出一個常見誤區(qū)把 socket 設(shè)成非阻塞并不等于性能變好。非阻塞只是改變了“等待”的方式并沒有減少數(shù)據(jù)拷貝也沒有減少系統(tǒng)調(diào)用次數(shù)。如果你的程序邏輯還是“讀一次處理一次”非阻塞帶來的只是更復(fù)雜的錯誤處理代碼。真正帶來吞吐提升的是多路復(fù)用帶來的“一個線程管多連接”。我在實際項目里給 fd 設(shè)非阻塞的時機很固定accept返回的新連接立刻設(shè)connect發(fā)起前設(shè)非阻塞 connect 可以避免三次握手期間卡住然后用 epoll 監(jiān)聽可寫事件判斷連接是否建立成功監(jiān)聽 fd 本身視模型而定。這個順序不能亂尤其是connect如果先連再設(shè)非阻塞那在連接超時的情況下你還是會被卡住。2.3 IO 多路復(fù)用select、poll、epoll 的三代演進這一節(jié)是重點因為它是目前幾乎所有高性能網(wǎng)絡(luò)服務(wù)的底座。select是最早的方案。它用一個位圖fd_set表示要監(jiān)聽哪些 fd調(diào)用時把這個位圖從用戶態(tài)拷到內(nèi)核態(tài)內(nèi)核遍歷一遍看哪些 fd 有事件把有事件的 fd 在位圖里標記出來再拷回用戶態(tài)。程序拿到返回值后還得自己再遍歷一遍位圖找出哪些位被置位了。它有三個致命問題。第一fd 數(shù)量上限是FD_SETSIZE通常是 1024改這個值要重新編譯內(nèi)核不現(xiàn)實。第二每次調(diào)用都要把整個位圖拷進拷出fd 越多拷貝越大這是 O(n) 的內(nèi)存拷貝。第三內(nèi)核要線性掃描所有 fd用戶態(tài)也要線性掃描兩次 O(n)。所以 select 在 fd 上千之后性能急劇下滑而且每次調(diào)用完都得重置 fd_set很容易寫錯。poll換了個數(shù)據(jù)結(jié)構(gòu)用pollfd數(shù)組每個元素包含 fd、關(guān)心的事件、返回的事件。它解決了 1024 上限的問題上限變成內(nèi)存和ulimit -n決定的也解決了每次要重置的問題events 和 revents 分離。但本質(zhì)沒變還是每次全量拷貝還是內(nèi)核線性掃描還是用戶態(tài)線性掃描。fd 到一萬這個量級poll 的拷貝和掃描開銷就很可觀了。epoll是 Linux 2.6 引入的思路完全不一樣把“注冊”和“等待”拆成兩個操作。epoll_create在內(nèi)核里創(chuàng)建一個 eventpoll 對象里面維護兩塊核心結(jié)構(gòu)一棵紅黑樹用來存所有注冊進來的 fd 及其關(guān)注的事件一個就緒鏈表用來存已經(jīng)有事件發(fā)生的 fd。紅黑樹保證增刪改是 O(log n)就緒鏈表保證取事件是 O(1)。epoll_ctl負責往紅黑樹里加、刪、改。關(guān)鍵是注冊的時候內(nèi)核會給這個 fd 掛一個回調(diào)當該 fd 對應(yīng)的數(shù)據(jù)到達、觸發(fā)軟中斷處理時內(nèi)核直接通過這個回調(diào)把 fd 塞進就緒鏈表。也就是說事件是被主動推送過來的不需要掃描。epoll_wait只做一件事看就緒鏈表空不空。空就睡非空就把鏈表里的節(jié)點拷到一個用戶傳入的數(shù)組里返回同時把這個節(jié)點從鏈表摘掉水平觸發(fā)模式下會重新掛回去后面細說。返回值是就緒的 fd 個數(shù)用戶只需要處理這 n 個不需要遍歷全部。這三個改進疊加起來效果是注冊一次長期有效事件驅(qū)動無需掃描只返回就緒的處理量與總連接數(shù)無關(guān)。這就是所謂的 O(1) 事件通知嚴格說是 O(就緒數(shù))不是 O(總連接數(shù))。但 epoll 不是沒有成本有幾個點必須知道第一epoll_ctl的調(diào)用是有開銷的比 select 的一次性注冊攤薄下來要貴。所以如果你的場景是“一批 fd 用一次就扔”比如處理一批短連接select 或 poll 反而可能更劃算。epoll 的優(yōu)勢在長連接、高頻復(fù)用。第二epoll 的紅黑樹節(jié)點和就緒鏈表節(jié)點都是內(nèi)核內(nèi)存連接數(shù)巨大時這部分內(nèi)存不可忽視。粗略估算每個被監(jiān)聽的 fd 在內(nèi)核里額外占幾百字節(jié)不同內(nèi)核版本有差異量級在數(shù)百字節(jié)十萬連接就是幾十 MB 的額外開銷。做容量規(guī)劃時要把這塊算進去。第三epoll_wait返回的數(shù)組大小要合理。傳 1 意味著每次只能取一個就緒事件雖然不會丟但會多調(diào)用很多次傳太大又浪費?;蚨芽臻g。我一般按min(預(yù)期并發(fā)就緒數(shù), 1024)來定實測下來 512 到 1024 是個舒適區(qū)。第四跨進程或者多線程同時epoll_wait同一個 epoll 實例會涉及喚醒競爭也就是常說的驚群。Linux 4.5 引入的EPOLLEXCLUSIVE標志可以緩解同一時刻只喚醒一個等待者另一個思路是用SO_REUSEPORT讓每個線程各自持有獨立的監(jiān)聽 fd 和獨立的 epoll 實例。這兩套方案我在不同項目里都用過后者在多核下擴展性更好但連接分配的均衡性依賴內(nèi)核哈希不能保證完全均勻。2.4 信號驅(qū)動與異步IO一條容易被混淆的邊界信號驅(qū)動 IO的流程是給 socket 設(shè)置屬主并注冊 SIGIO 處理函數(shù)開啟信號驅(qū)動然后進程就可以去干別的。數(shù)據(jù)到達時內(nèi)核發(fā) SIGIO進程在信號處理函數(shù)里調(diào)recv讀數(shù)據(jù)。它的問題很實際。首先信號處理函數(shù)里能做的事情非常受限很多庫函數(shù)不是異步信號安全的一不小心就死鎖。其次信號是進程級的多個 fd 共用一個信號處理函數(shù)里很難判斷到底是哪個 fd 就緒還得額外維護映射。第三信號可能丟失或合并高頻事件下不可靠。所以這套東西除了少數(shù)嵌入式場景和歷史遺留代碼基本沒人用了。你在網(wǎng)上看到它的介紹知道原理就夠了不用花時間實踐。異步 IO才是真正意義上的“不等”。你提交一個讀請求附帶緩沖區(qū)和完成通知方式立刻返回。內(nèi)核負責等數(shù)據(jù)、負責拷貝全干完了再告訴你。整個過程中你的進程一次都沒有被阻塞在 IO 上。Linux 上的實現(xiàn)經(jīng)歷了兩個階段。早期是 POSIX AIOglibc 的用戶態(tài)模擬和內(nèi)核 AIOio_submit/io_getevents前者本質(zhì)是用線程池模擬后者限制很多只支持 O_DIRECT、對普通文件的支持不好、網(wǎng)絡(luò) IO 支持有限一直沒能普及。近些年 io_uring 出來了用一對共享內(nèi)存的環(huán)形隊列提交隊列和完成隊列來做用戶態(tài)和內(nèi)核態(tài)的通信既支持文件 IO 也支持網(wǎng)絡(luò) IO還能批量提交通過IORING_SETUP_SQPOLL讓內(nèi)核線程輪詢提交隊列進一步減少系統(tǒng)調(diào)用。它的性能數(shù)據(jù)很漂亮但生態(tài)還在成熟過程中各種語言的綁定質(zhì)量參差不齊線上大規(guī)模用的案例還不算多。至于 Java 的 AIONIO.2在 Linux 上底層用的是 epoll 模擬JDK 內(nèi)部有專門的實現(xiàn)并不是真正的內(nèi)核異步 IO所以它的“異步”更多是 API 層面的封裝。這也是為什么很多 Java 服務(wù)依然選 Netty 而不是 AIO 的原因之一。選型上的建議除非你有非常明確的理由比如已經(jīng)在用 io_uring 做存儲棧、或者對系統(tǒng)調(diào)用次數(shù)極度敏感網(wǎng)絡(luò)服務(wù)的默認答案就是 epoll 這一套多路復(fù)用加事件循環(huán)。異步 IO 的收益在當前階段還不足以抵消它的復(fù)雜度和生態(tài)風險。下面這張表是我自己在做方案對比時用的把關(guān)鍵維度擺在一起看比讀十篇介紹文章都直觀。模型階段一等數(shù)據(jù)階段二拷貝單線程可管理連接數(shù)編程復(fù)雜度典型適用場景阻塞 IO進程阻塞進程阻塞1與線程綁定低連接少、內(nèi)部服務(wù)、短連接非阻塞 IO輪詢不阻塞進程阻塞取決于輪詢策略中一般需配合其他模型使用IO 多路復(fù)用由內(nèi)核代為等待進程阻塞數(shù)千至數(shù)十萬中高長連接網(wǎng)關(guān)、推送、代理信號驅(qū)動 IO信號通知不阻塞進程阻塞理論上多實際受限高極少使用異步 IO內(nèi)核完成內(nèi)核完成高高高吞吐存儲、特定場景3. 把 epoll 真正跑起來從調(diào)用到事件循環(huán)理論講完落到代碼。這一段我會把 epoll 的關(guān)鍵調(diào)用拆開說明每個參數(shù)為什么這么填然后給出一個能直接編譯運行的最小事件循環(huán)再對照 Java NIO 的寫法方便不同技術(shù)棧的讀者對照理解。3.1 epoll 三個調(diào)用背后的數(shù)據(jù)結(jié)構(gòu)與參數(shù)含義epoll_create1(EPOLL_CLOEXEC)創(chuàng)建一個 epoll 實例返回一個 fd。參數(shù)用EPOLL_CLOEXEC而不是老的epoll_create(size)原因是前者會在exec新程序時自動關(guān)閉這個 fd避免子進程繼承一堆用不上的句柄。老接口的size參數(shù)在內(nèi)核 2.6.8 之后已經(jīng)沒意義了只是兼容保留不要以為它真的能限制什么。epoll_ctl(epfd, op, fd, event)是增刪改。op有 ADD、DEL、MOD 三種。event里兩個字段最要緊events是關(guān)注的事件掩碼data是一個聯(lián)合體可以存 fd 也可以存指針。我強烈建議存指針而不是 fd因為在高并發(fā)場景下你需要通過這個字段快速定位到連接對象包含緩沖區(qū)、狀態(tài)機、超時時間等存 fd 的話還要再查一次哈希表白白多一次間接尋址。存指針的做法是把連接對象的地址塞進data.ptr事件回來時直接強轉(zhuǎn)。events里常填的EPOLLIN可讀、EPOLLOUT可寫、EPOLLERR錯誤、EPOLLHUP掛斷、EPOLLRDHUP對端關(guān)閉寫端這個很有用能提前感知半關(guān)閉。注意EPOLLERR和EPOLLHUP是永遠會被上報的不需要你顯式注冊但你應(yīng)該在事件處理里優(yōu)先檢查它們。epoll_wait(epfd, events, maxevents, timeout)是等待。timeout單位毫秒-1 表示永久阻塞0 表示立即返回純輪詢正數(shù)表示最多等這么久。這里有個實操細節(jié)很多事件循環(huán)會把 timeout 設(shè)成一個較小的值比如 100ms 或者按最近的定時器到期時間算目的是定期醒來處理定時任務(wù)連接超時、心跳檢測。如果設(shè) -1那定時任務(wù)就永遠沒機會執(zhí)行。我一般的做法是算出“距離下一個定時器還有多少毫秒”作為 timeout 傳進去這樣既不空轉(zhuǎn)也不誤事。調(diào)用返回值 n 表示就緒的事件數(shù)接下來遍歷events[0..n-1]逐個處理。處理時有個原則單個事件的處理時間要盡可能短。如果某個連接的業(yè)務(wù)處理很重不要在這個循環(huán)里做完應(yīng)該丟給業(yè)務(wù)線程池。否則一個慢請求會拖住整個事件循環(huán)所有連接都受影響。這是事件驅(qū)動模型最容易被違反的原則也是很多自研框架的性能瓶頸所在。3.2 水平觸發(fā)與邊緣觸發(fā)丟數(shù)據(jù)的坑都在這兒這是 epoll 里最容易出問題的地方我必須單獨講。水平觸發(fā)LT默認的語義是只要 fd 的接收緩沖區(qū)里還有數(shù)據(jù)沒讀完每次epoll_wait都會告訴你這個 fd 可讀。也就是說你讀了一半就走了下次還會被通知不會丟。這個模式寫起來安全因為你哪怕只讀了一個字節(jié)剩下的下次還能拿到。代價是如果一直不讀完就會一直被通知形成忙循環(huán)所以還是要讀完。邊緣觸發(fā)ET的語義是只在狀態(tài)發(fā)生變化時通知一次。從“無數(shù)據(jù)”變成“有數(shù)據(jù)”時通知之后無論緩沖區(qū)里還剩多少都不再通知直到下一次新的數(shù)據(jù)到達。這就要求你收到通知后必須循環(huán)讀取直到返回 EAGAIN把緩沖區(qū)徹底讀空。同時 fd 必須是非阻塞的否則最后一次讀會因為沒數(shù)據(jù)而阻塞住把整個事件循環(huán)卡死。我在一個項目里就踩過這個坑代碼改成了 ET 模式但讀取邏輯還是只讀一次。壓測時表現(xiàn)為極低概率的數(shù)據(jù)丟失大概萬分之一的請求少字段。排查了兩天才定位到原因是某個請求的數(shù)據(jù)包被拆成了兩段第一段到達觸發(fā)了一次通知程序讀完第一段就去處理了第二段到達時因為緩沖區(qū)非空狀態(tài)沒變化不再觸發(fā)通知于是第二段永遠留在內(nèi)核緩沖區(qū)里直到下一個包到達才被順帶讀出來——所以表現(xiàn)為“偶發(fā)丟數(shù)據(jù)”而不是“必丟”。這種 bug 極難復(fù)現(xiàn)因為依賴網(wǎng)絡(luò)分包。所以 ET 模式的正確寫法固定是三段式for (;;) { n read(fd, buf, len); if (n 0) { 處理 } else if (n 0) { 對端關(guān)閉清理 } else { if (errno EAGAIN || errno EWOULDBLOCK) break; else 出錯處理 } }。這個循環(huán)不能省。選用建議沒有明確性能訴求就用 LT。ET 的優(yōu)勢在于減少epoll_wait的返回次數(shù)在高并發(fā)下能省一些系統(tǒng)調(diào)用但差距沒有想象中大通常 10% 以內(nèi)而它帶來的正確性風險是實打?qū)嵉?。只有在連接數(shù)極高、且你對自己的讀取邏輯非常有信心時才上 ET。另外要注意監(jiān)聽 fdlisten返回的那個在 ET 模式下也要循環(huán)accept直到 EAGAIN否則并發(fā)連接建立時會漏掉一部分連接。3.3 一份可復(fù)用的最小事件循環(huán)先看 C 版本這段代碼我用了很多次去掉業(yè)務(wù)邏輯就是一個干凈的骨架。#include sys/epoll.h #include sys/socket.h #include fcntl.h #include unistd.h #include errno.h #include stdio.h #define MAX_EVENTS 1024 static int set_nonblocking(int fd) { int flags fcntl(fd, F_GETFL, 0); if (flags -1) return -1; return fcntl(fd, F_SETFL, flags | O_NONBLOCK); } int main(void) { int listenfd socket(AF_INET, SOCK_STREAM, 0); int opt 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, opt, sizeof(opt)); /* bind listen 略backlog 建議 1024 起 */ set_nonblocking(listenfd); int epfd epoll_create1(EPOLL_CLOEXEC); struct epoll_event ev, events[MAX_EVENTS]; ev.events EPOLLIN; /* 監(jiān)聽 fd 用水平觸發(fā)穩(wěn) */ ev.data.fd listenfd; epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, ev); for (;;) { /* timeout 按最近定時器到期時間算這里固定 100ms 演示 */ int n epoll_wait(epfd, events, MAX_EVENTS, 100); if (n 0) { if (errno EINTR) continue; /* 被信號打斷重來 */ perror(epoll_wait); break; } for (int i 0; i n; i) { int fd events[i].data.fd; if (events[i].events (EPOLLERR | EPOLLHUP)) { close(fd); epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); continue; } if (fd listenfd) { for (;;) { /* 循環(huán) accept 直到 EAGAIN */ int conn accept(listenfd, NULL, NULL); if (conn 0) { if (errno EAGAIN || errno EWOULDBLOCK) break; if (errno EINTR) continue; break; } set_nonblocking(conn); ev.events EPOLLIN | EPOLLRDHUP; ev.data.fd conn; epoll_ctl(epfd, EPOLL_CTL_ADD, conn, ev); } } else { /* 業(yè)務(wù)讀取這里若用 ET 必須循環(huán)讀到 EAGAIN */ char buf[4096]; ssize_t r read(fd, buf, sizeof(buf)); if (r 0) { /* 處理數(shù)據(jù) */ } else if (r 0) { close(fd); epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); } else { if (errno ! EAGAIN errno ! EWOULDBLOCK) { close(fd); epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); } } } } } return 0; }這段代碼里有幾個地方值得單獨說。EINTR的處理不能省因為進程可能被信號打斷epoll_wait會返回 -1如果不判斷就直接退出服務(wù)會因為一個無關(guān)信號掛掉。EPOLLRDHUP加進去是為了盡早感知對端關(guān)閉否則你可能要等一次寫失敗才知道對面走了。epoll_ctl DEL在 close 之前還是之后其實都可以因為 close 會自動把 fd 從 epoll 里移除但顯式 DEL 更清晰也避免 fd 被復(fù)用后出現(xiàn)意外。再看 Java NIO 的等價寫法思路完全一樣只是把系統(tǒng)調(diào)用包裝成了對象。Selector selector Selector.open(); ServerSocketChannel server ServerSocketChannel.open(); server.bind(new InetSocketAddress(8080), 1024); server.configureBlocking(false); server.register(selector, SelectionKey.OP_ACCEPT); while (true) { // 1000ms 是為了兜底定時任務(wù) int n selector.select(1000); if (n 0) continue; IteratorSelectionKey it selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key it.next(); it.remove(); // 必須移除否則下次重復(fù)處理 if (!key.isValid()) continue; if (key.isAcceptable()) { SocketChannel ch server.accept(); ch.configureBlocking(false); ch.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { SocketChannel ch (SocketChannel) key.channel(); ByteBuffer buf ByteBuffer.allocate(4096); int r ch.read(buf); if (r -1) { key.cancel(); ch.close(); } else if (r 0) { buf.flip(); /* 處理 */ } } } }it.remove()這一行是新手最容易漏的。selectedKeys()返回的集合是復(fù)用的你不移除下一輪還會處理同一個 key業(yè)務(wù)邏輯會重復(fù)執(zhí)行。這個 bug 的表現(xiàn)是“請求被處理了兩次”在冪等接口上不明顯在扣款類操作上就是事故。Java 側(cè)還有兩個細節(jié)configureBlocking(false)必須在register之前調(diào)用否則會拋異常allocate每個連接都新建一個 ByteBuffer 會造成大量小對象生產(chǎn)環(huán)境要用池化或者直接緩沖區(qū)。這些在 Netty 里都被封裝好了但知道底層在干什么出問題時才能定位。4. 從模型到架構(gòu)Reactor 與線程模型的取舍搞清楚了單個連接怎么處理下一個問題是怎么把成千上萬個連接和有限的 CPU 核數(shù)組織起來。這就是 Reactor 模式要回答的事。4.1 三種 Reactor 結(jié)構(gòu)與它們的成本賬單 Reactor 單線程是最樸素的形態(tài)一個線程跑事件循環(huán)accept、讀、業(yè)務(wù)處理、寫全在里面。它的好處是無鎖、無競爭、邏輯簡單壞處是任何一步慢都會拖住全部。適合業(yè)務(wù)極輕的場景比如某些協(xié)議轉(zhuǎn)換、簡單的回顯服務(wù)。用它跑有數(shù)據(jù)庫訪問的業(yè)務(wù)基本上是自找麻煩。單 Reactor 多線程把業(yè)務(wù)處理挪出去事件循環(huán)只負責 IO 讀寫和編解碼讀完的完整報文丟給業(yè)務(wù)線程池。這樣 IO 和計算解耦一個慢查詢不會阻塞其他連接的數(shù)據(jù)接收。代價是線程間傳遞數(shù)據(jù)要做隊列隊列滿了要有背壓策略而且寫操作要從業(yè)務(wù)線程回到 IO 線程涉及跨線程提交任務(wù)。這里的坑是寫并發(fā)多個業(yè)務(wù)線程同時想往同一個連接寫數(shù)據(jù)直接寫會導致字節(jié)流交錯必須加鎖或者串行化到 IO 線程。主從 Reactor更進一步把 accept 也分離出來主 Reactor 只負責監(jiān)聽和建立連接建立后把新連接分給某個從 Reactor從 Reactor 各自跑自己的事件循環(huán)處理讀寫。這樣 accept 的壓力不會影響已有連接而且從 Reactor 的數(shù)量可以按 CPU 核數(shù)擴展通常設(shè)成核數(shù)或核數(shù)的 1 到 2 倍。這是目前主流框架的默認模型。分連接的方式通常有兩種輪詢和按連接 id 取模。輪詢實現(xiàn)簡單但需要原子計數(shù)高并發(fā)下有競爭取模無競爭但依賴連接 id 分布均勻。我在實際項目里更傾向輪詢因為連接 id 不一定連續(xù)取模可能傾斜。這里有個成本賬要算清楚從 Reactor 線程數(shù)不是越多越好。每個線程有自己的 epoll 實例、自己的事件循環(huán)、自己的隊列。線程多了鎖競爭雖然少了但上下文切換和緩存局部性會變差。我實測下來從 Reactor 線程數(shù)設(shè)成 CPU 核數(shù)時吞吐最好超過 1.5 倍核數(shù)基本沒有收益反而 P99 會抖動。這個結(jié)論在不同業(yè)務(wù)下會有差異但量級上差不多。4.2 連接數(shù)、線程數(shù)與內(nèi)存容量估算的實際算法做架構(gòu)評審時經(jīng)常被問“這套模型能扛多少連接”很多人答不上來。其實可以算我心里有個固定的算法。先算文件描述符。每個連接占一個 fd服務(wù)端自己還要占一些監(jiān)聽、日志、管道、epoll 實例、定時器留 200 個余量比較穩(wěn)。所以ulimit -n至少要等于目標連接數(shù)加上 200。這里要注意ulimit -n是每進程的限制還有fs.file-max是系統(tǒng)級限制兩個都要調(diào)。改ulimit可以在啟動腳本里ulimit -n 1048576也可以通過 systemd 的LimitNOFILE配。改完記得驗證用cat /proc/pid/limits看實際生效值。再算內(nèi)核內(nèi)存。每個 TCP 連接在內(nèi)核里有 socket 結(jié)構(gòu)、發(fā)送緩沖區(qū)、接收緩沖區(qū)。緩沖區(qū)大小受net.ipv4.tcp_rmem和tcp_wmem控制是三元組最小、默認、最大。默認值通常接收 128KB 左右、發(fā)送 16KB 左右但這是上限實際按需增長。保守估算每連接 200KB 內(nèi)核內(nèi)存十萬連接就是 20GB。這個數(shù)字經(jīng)常被忽略結(jié)果連接一多就 OOM。生產(chǎn)上我會把默認值調(diào)小一點比如接收 64KB讓緩沖區(qū)按需增長避免空閑連接占著大塊內(nèi)存。再算應(yīng)用層內(nèi)存。每個連接對象、讀緩沖區(qū)、寫緩沖區(qū)、狀態(tài)機、定時器節(jié)點加起來通常幾 KB 到幾十 KB。這里的關(guān)鍵是讀寫緩沖區(qū)別開太大。有的框架默認給每個連接分配 64KB 讀緩沖十萬連接就是 6.4GB。實際做法是用可變緩沖區(qū)初始 1KB 到 4KB不夠再擴并且設(shè)上限。最后算線程棧。Java 默認每線程 1MB可用-Xss調(diào)小到 256KBC 的 pthread 默認 8MB虛擬內(nèi)存實際按需分配。線程數(shù)按 Reactor 核數(shù)加業(yè)務(wù)線程池來估通常幾十到幾百這塊開銷不大。真正占內(nèi)存的是連接對象不是線程。把這些加起來就是一臺機器的內(nèi)存需求。我給個參考十萬長連接4KB 應(yīng)用層緩沖加 64KB 內(nèi)核緩沖加對象開銷大約 8 到 12GB需要配 16GB 內(nèi)存的機器并且把 fd 限制調(diào)到 12 萬以上。這個估算在幾個項目里驗證過誤差在 20% 以內(nèi)。4.3 背壓與應(yīng)用層協(xié)議的配合模型選對了還有一個隱形的坑上游讀得飛快下游寫得慢。事件循環(huán)不停地把數(shù)據(jù)讀進來放進隊列業(yè)務(wù)線程處理不過來隊列無限增長最后內(nèi)存爆掉。這就是沒有背壓。背壓的手段分幾層。最直接的是停止讀當某個連接的待處理隊列超過閾值就從 epoll 里把這個 fd 的 EPOLLIN 事件摘掉用epoll_ctl MOD改成只監(jiān)聽 EPOLLOUT或者干脆 DEL 掉這樣內(nèi)核緩沖區(qū)堆滿后TCP 接收窗口縮小發(fā)送方自然減速。這一招最干凈因為它把壓力傳導回了源頭符合 TCP 的設(shè)計初衷。第二層是限制并發(fā)處理數(shù)。業(yè)務(wù)線程池用有界隊列隊列滿了就拒絕或者阻塞提交。這里的取舍是阻塞提交會讓 IO 線程被卡住不可取拒絕則要有一套降級邏輯比如返回特定錯誤碼讓客戶端重試。我一般用有界隊列加拒絕隊列容量按“能承受的最大積壓時間”來定比如目標 P99 是 100ms處理速度是每秒 1 萬那隊列 1000 左右比較合適。第三層是協(xié)議層限流。比如在報文頭里帶一個序號或者窗口大小讓客戶端自己控制發(fā)送速率。這在自研協(xié)議里很常見用標準協(xié)議的話就得靠 TCP 自身的流控。我見過最典型的背壓缺失案例一個推送服務(wù)客戶端網(wǎng)絡(luò)慢服務(wù)端不停往里寫寫緩沖區(qū)從幾 KB 漲到幾 MB幾千個慢客戶端直接把內(nèi)存吃光。修復(fù)方案是給每個連接設(shè)寫緩沖上限超過就斷開或者丟棄舊消息。斷開這個動作看著粗暴但對推送場景是合理的因為積壓的消息本來就已經(jīng)過期了。另外應(yīng)用層協(xié)議的選擇也會反向影響模型。比如 HTTP/1.1 的 keep-alive 讓連接變長就必須用多路復(fù)用模型HTTP/2 的多路復(fù)用是在一條連接上跑多個流需要應(yīng)用層自己做流控WebSocket 是長連接雙向通信對事件循環(huán)的寫并發(fā)要求更高。這些在選擇協(xié)議的時候就得想清楚別等上線了才發(fā)現(xiàn)模型不匹配。5. 線上排查實錄那些模型理論解釋不了的現(xiàn)象理論和代碼講完最后落到排查。這一節(jié)全是我在實際環(huán)境里遇到過的現(xiàn)象和對應(yīng)的定位路徑很多問題光看模型定義是看不出來的。5.1 高頻問題速查表先給一張表按現(xiàn)象查起?,F(xiàn)象優(yōu)先懷疑快速驗證方法常見處理CPU 的 sy 占比高但吞吐上不去事件循環(huán)空轉(zhuǎn)、系統(tǒng)調(diào)用過多strace -c -p pid看調(diào)用次數(shù)檢查 timeout 是否設(shè)成 0 或過小檢查是否有忙輪詢連接數(shù)上不去accept報錯fd 限制、backlog 太小cat /proc/pid/limits、ss -lnt看 Send-Q調(diào)ulimit -n、調(diào)大somaxconn和 listen backlog大量 CLOSE_WAIT 堆積應(yīng)用層沒正確關(guān)閉連接ss -tan state close-wait | wc -l檢查讀到 EOF 后是否 close檢查異常路徑是否漏關(guān)偶發(fā)丟數(shù)據(jù)低頻難復(fù)現(xiàn)ET 模式?jīng)]循環(huán)讀完抓包對比應(yīng)用層收到的字節(jié)數(shù)改為循環(huán)讀到 EAGAIN或退回 LT某幾個連接延遲極高單個事件處理太慢拖住循環(huán)在事件循環(huán)里埋點統(tǒng)計單次處理耗時把重業(yè)務(wù)移出 IO 線程內(nèi)存持續(xù)增長不釋放寫緩沖無上限、連接對象泄漏看堆內(nèi)連接對象數(shù)量和緩沖大小分布設(shè)緩沖上限加空閑連接回收多線程 accept 時部分連接不處理epoll 驚群觀察是否所有線程都被喚醒用 EPOLLEXCLUSIVE 或 SO_REUSEPORT這張表里的每一條我都在真實環(huán)境驗證過。尤其是 ET 那條抓包對比是最直接的在服務(wù)端用 tcpdump 抓一段數(shù)一下某個請求的 payload 總字節(jié)數(shù)再和應(yīng)用層日志里收到的字節(jié)數(shù)對比。如果抓包比日志多基本可以確定是讀循環(huán)沒讀干凈。5.2 幾個必須提前規(guī)避的細節(jié)第一個epoll_wait返回后別在遍歷中直接 DEL 當前 fd 之外的 fd。這個坑很隱蔽。你手里拿著一個 events 數(shù)組遍歷到第 3 個元素時業(yè)務(wù)邏輯順手關(guān)掉了第 5 個元素對應(yīng)的連接并 DEL 了。等遍歷到第 5 個時那個 fd 可能已經(jīng)被新連接復(fù)用了你去處理它操作的是完全不相干的連接。正確做法是先把所有事件收集起來處理完再統(tǒng)一做增刪或者用引用計數(shù)延遲釋放。我在一個網(wǎng)關(guān)項目里因為這個 bug 排查了整整一周現(xiàn)象是“極低概率的串包”A 用戶收到了 B 用戶的響應(yīng)。第二個信號要處理好。事件循環(huán)里被 SIGPIPE 打斷會導致進程直接退出默認行為。如果客戶端在你寫數(shù)據(jù)時突然斷開你調(diào)用 write 就會收到 SIGPIPE。要么全局忽略它signal(SIGPIPE, SIG_IGN)要么用send的MSG_NOSIGNAL標志。這個必須加不加就是一顆定時炸彈平時不出問題用戶批量斷線重啟時直接崩。第三個定時器精度別依賴epoll_wait的 timeout。那個 timeout 只是“最多等這么久”實際可能提前返回有事件也可能稍微延后調(diào)度延遲。如果你靠它來做精確的超時控制誤差會累積。正確做法是自己維護一個時間輪或者最小堆每次算好最近到期時間作為 timeout同時每次醒來都檢查一遍當前時間把到期的連接處理掉。第四個TIME_WAIT 是正常的別急著調(diào)參數(shù)。服務(wù)端主動關(guān)閉連接會進入 TIME_WAIT占著四元組 60 秒2 倍 MSL。高并發(fā)短連接場景下 TIME_WAIT 數(shù)量會很高很多人第一反應(yīng)是開tcp_tw_reuse或者調(diào)小fin_timeout。但在 NAT 環(huán)境下亂開 reuse 有風險而且 TIME_WAIT 的存在是為了保證最后一個 ACK 能重傳強行消滅會引入數(shù)據(jù)錯亂。我的做法是優(yōu)先用長連接和連接池把短連接降下來實在降不下來再看有沒有足夠的端口范圍最后才考慮內(nèi)核參數(shù)。第五個不要在事件循環(huán)里做 DNS 解析、文件讀寫、日志刷盤這些阻塞操作。任何一個都可能耗時幾十毫秒而這幾十毫秒里所有連接都停擺。DNS 要單獨起解析線程或用異步解析庫日志用異步 appender文件操作丟線程池。這些看起來是常識但我在不止一個服務(wù)里見過事件循環(huán)里直接logger.info同步刷盤的。第六個連接關(guān)閉的順序。正確的關(guān)閉是先shutdown(SHUT_WR)發(fā) FIN 告訴對端我不發(fā)了然后繼續(xù)讀直到讀到 EOF對端也關(guān)了再 close。直接 close 可能會導致發(fā)送緩沖區(qū)里沒發(fā)完的數(shù)據(jù)被丟棄除非設(shè)了 SO_LINGER。在推送類服務(wù)里這個細節(jié)很關(guān)鍵直接 close 會導致最后一條消息丟失。寫到這里我個人的體會其實很簡單網(wǎng)絡(luò) IO 模型的選擇本質(zhì)上是在“線程成本”和“編程復(fù)雜度”之間做交換。阻塞 IO 把復(fù)雜度留給了運行時線程多、切換多事件驅(qū)動把復(fù)雜度留給了開發(fā)者狀態(tài)機、回調(diào)、緩沖管理。沒有哪一種絕對更好只有適不適合你當下的連接規(guī)模、團隊能力和業(yè)務(wù)特征。很多團隊上事件驅(qū)動上早了代碼寫成一團亂麻問題排查成本遠超省下來的那點資源。反過來連接數(shù)已經(jīng)過萬了還在用一連接一線程那就是在跟物理規(guī)律較勁。真要給一個判斷標準我會看兩條連接數(shù)長期穩(wěn)定在 500 以下用阻塞 IO 加線程池超過這個量級或者有大量空閑長連接就老老實實上 epoll 那一套。中間地帶可以先用“阻塞 IO 合理超時 連接池”過渡等壓測數(shù)據(jù)真的支撐不住了再重構(gòu)別一上來就追求終極方案。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
97超碰色色| 日韩黄色一区二区三区| 99精品久久久久久久婷婷蜜桃| 蜜桃无码AV一区二区| 99精品伊人| 蜜臀99久久精品久久久久| 日韩国产不卡在线视频| 极品内射| 精品欧美А∨无码黑人大荫蒂 | 日韩无码服务区| 欧美激情视频在线一区| 99热这里只有精| 四虎精品亚洲| 狠狠干狠狠色| 日韩三级在线观看网站| 动漫区日韩区欧美区| 乱操乱伦AV| 欧美熟爽综合| 亚洲 自拍偷拍 欧美| 精品176精品2| 国产97视频免费观看| 九九九九免费视频| 麻豆啪啪啪视频| 91美女高潮| 亚洲熟女中文字幕在线| 中国特猛少妇色xxx| 极品五月天噜噜| 凹凸视频在线一区二区| 超碰97资源网亚洲| 少妇无码太爽| 国产激情片在线观看| 亚洲高清男人天堂| 一区中文字幕二区日韩| 九九热AV| 久久黄色性爱视频| 五十路熟女人妻一区二区在线观看| 大香蕉九九| 国产精品分类在线观看| 亚洲黄色电影| 亚州国产成人精品女人久久| 一区二区你上我| 大香蕉综合网| 91观看 国产白丝| 亚洲欧美综合色| A片三级无码| 91综合网在线| 欧美啪啪啪91| 中文字幕诱惑制服人妻丝袜美丝袜美| 狼天天狼天天大香蕉| 操逼天美3区| 91久久久久久久久18| 久久亚州大香蕉| 久热色情精品| 亚洲成人碰碰| 黄色污污污污污污网站| 亚洲。日韩。欧美| 欧美视频在线第3页| 精品一区二区亚洲国产| 美女黄频a美女大全免费皮| yw尤物av无码点击进入麻豆| 亚洲高清无毛一区二区| 欲香欲色| 成人a大片在线观看| 视频不卡中文字幕| 美国日韩黄片| 女同女同恋久久级三级| 国产九月婷婷| 欧美性爱精品一区二区| 丰满少妇乱子伦精品无| 日本肉体xxxx裸交| 色婷婷丁香五月| 狼人久草| 九九99久久| 婷婷丁香在线| 麻豆婷婷成人一二三| 天操天操夜操夜月操月年年操| 性站 | 欧美性爱视频免费一区一A | HEYZO高无码国产精品227| 日本日皮视频逼| 伊人久久大香大香线蕉中文| 五月天激情网站| 色妹子A V| 亚洲天堂东京热| 国产精品亚洲日韩骚欢乐谷最新地址发布页huanieguty性屋娱乐妖精视频 | 精品无码一区二区三区| 久久久久99999| 色哟哟 日韩精品| 爱妃国产亚洲视频中文字幕| 综合欧美日本三级| 精品网站9999| 天天看片青娱乐| 伦激情人妻另类人妻| AV综合中文字幕干| 亚洲国产精品久久久男人的天堂| 亚洲色婷婷综合久久一区二区三区| 殴美色网| 牛黄色久午久| 亚洲黄色网址| 9国产超碰| 丁香五月天堂| 久草老司机| 少妇综合| 亚洲精品色| 亚洲熟女综合网| 99久久久| 97操b| 色成人Www精品永久观看| 国产人伦精品一区二区三区 | 亚洲色图美腿丝袜| 日韩成人私密一级精品av| 亞洲久久直播| 欧美亚洲高清晰| 人人操人人插人人摸人人干| 亚洲色性情三级| 国产深夜福利| 亚洲第一页欧美| 亚洲欧洲自拍| 人妻天堂综合网| 久久久久久免费电影| 亚洲一区二区三区中文字幕| 黄久在线| 婷婷激情五月| 四虎精品永久在线播放| 婷婷丁香一区二区三区| 在线综合色| 色在线69堂| 操逼www.| 欧美日韩精品久久久久久久久东北老熟妇| 337p大胆噜噜噜噜噜91Av| 国产精品白丝AV| 色999五月色| 欧美 日韩第一性色| 五月色网| 亚洲男人久久综合天堂| 天久久久噜噜噜久久国产精品爽爽| 2001天天操| 国产探花日韩援交| 九九九精品美女| 操我啊啊啊啊啊| 日韩黄片视频试看| 超碰美国| 亚州欧美综合| 99热免费精品| 吻戏激情性巴克| 国产最新小视频在线播放下载 | 久操网无码在线| 蜜臀av网址| 色九九九九久| www.av在线观看| 精品蜜乳AV免费观看| 91影视亚洲| 青青草在线视频人人想人人上| 一区二区影院| 在线 制服丝袜中出 人妻| 久久久一区二区三区麻豆| 殴美性色a级欧美| 久热在线精品免费观看| 91久久久久久| 校园春色宗合网| 久久久久熟女| 久久精品国产亚洲AV高级北京| 黄网在线播放| 91网站在线播放| www.91色综合| 亚洲AV不卡在线观看| 久久久久九九九| 日韩激情中文字幕有码| 免费网色网站| 亚洲精品国产熟女| 视频在线观看一二三区| 不卡视频一区蜜桃视频| 人妻-91porn| 国产精品丝袜久久亚洲不卡| 亚洲欧美日韩免费观看| 亚洲另类综合欧美| 91麻豆天美传媒在线| 日韩 欧美 另类 人妻| 日本一片一区| 日本操逼视频不卡直接放| 啊啊啊啊啊啊在线看| 色原狠狠天天天| 亚洲一区中文字幕一区| 日本在线伊人啪啪| 97九色人妻| 美女久久久久久久久久久| 色综合网1| 校园春色家庭伦理欧美激情| 97任你吞精| 国产精品久久久久久夜夜夜夜| 久久人人爽爽人人爽人人片αV| 亚洲国产一区二区三区在线 | 亚洲精品国语在线播放| 蜜臀av中字字幕网站| 欧美一级A一级a爱片久久| 青青草在线成人视频| 乱伦熟妇一区二区| 99只有精品| 欧美久久伊人| 69一区二区| 精品国产72| 黄在线| 啊啊啊操死我了| 大香蕉乱伦视频网| 国产精品第一区第一页| 日本中文字幕一区| 东北夫妻性偷拍| 亚洲欧洲综合av在线| 青青久日| 91日产欧美| 狠狠色综合网| 无码av永久免费专区网站| 亚欧操逼片在线观看 | 日本操逼二区| 91综合色| 酒色综合网| 欧美夜色| 久久一区,青青青青草视频在线播放| 少妇一级婬片免费放一级a性色.| 人妻少妇精品视频一区二区三区| 亚洲在高跟鞋自慰久久在色线| 97操操| 91人妻精华帖| 吖在线不卡一区二区国产剧情| 亚洲性综合11| 欧美性高潮在线| 人人澡综合涩| 9精品在线| 91大学精品激情戏| 五月天婷婷小说| 亚洲色悠悠久久88| 五月婷婷色| 超碰久超碰久| 无码不卡亚洲成?人片| 91精品网站| 国产高清自拍| 丝袜天堂| 亚洲少妇诱惑| 高潮内射在线| 日韩成人色图| 欧美超碰9798| 91精品久久久久五月天精品| 色五月AV| 性爱视频免费网址| 欧美老妇女内射网址| 欧美天天插| 欧美色一二三| 东京热91| 国产白丝AV| 花花AV导航| 9Ⅰ超碰| 天天射天天色成人| 超碰78| 日日干天天干夜夜爽| 国产精品久久| 日本操色导航| 综合色色网| 六九九九| 午夜精品久久久久| 大鸡巴久久| 超碰97网站| 日韩美女啪啪一区| 精品久久人妻成人网| 大香蕉亚洲中文| 99精品丰满人妻无| 日韩欧美麻豆 | 在线综合色| 丁香婷婷啪啪| 久久婷婷亚洲欧| 亚洲清纯综合| 九月丁香婷婷色| 五月天激情视频| 亚洲天堂第一页| 欧美极品色| 视频不卡中文字幕| 人人考人人摸人人干| 操穴国产| 久九色| 亚洲免费人妻在| 97亚洲一区| 色九九九九九九| 天天躁日日躁成人字幕aⅴ| 丁香九月激情| 91无码人妻精品一区二区三区蜜桃 | 日本高清熟女久久一区| 伊人丁香五月婷婷| 福利偷拍视频-中文字幕2019国语完整视频大全-S91AV | 五月天精品| 亚洲阿v天堂无码z2018| 国产精品经典一卡久久久| 校园春色美腿丝袜 | 亚洲精品国产无码高清| 800zy一区二区| 人人妻人人澡人人爽久久av| 色综合色| 另类天堂| 欧美另类自拍 | 97在线视频观看免费| av最新免费中文字幕| 久久精品老司| 天天色,天天干,天天干| 国产少妇高潮| www.久久久久| 亚洲欧美97| 欧美性猛交美女自慰91| 丁香六月啪| 欧美久久人体| 97亚洲综合电影| 四虎午夜影院| 久9爱经典视频| 午夜精品视频777| 大香蕉淫人| 丁香五月激情网| 2025年A片视频精品| 求求你操操我| 欧美精品1区2区3区| 久久中文字幕在线观看| 亚洲精品欧美专业| 国产偷拍自拍在线视频| 精品午夜福利| 十八禁电影伊人网| 久久久久久性爱片| 91社区拍啪人妻| 日本 情色 1区| 欧美日韩黄色片一区二区三区四区人与兽做爱| 日小BB小视频| 少妇久久| 国产怡红院在线| 国产精品第一区第一页| 日韩淫色网| 国产精品91一样| 黄色小视频日本txt| 免费在线看黄片av| 97在线播放| 人妻爽爽啪视频| 蜜臀少妇一区二区| 国产免费一区在线观看| 亚洲好看强奸乱伦| www.色吧5.com| 东京热,男人的天堂| 91爱做| 97精彩视频网站| 久碰视频| 日本在线一二 | 久久美女国产| 人妻81p| 久久久久久电影| 18禁看网站一区| 国产路线专区| 色综合91好| 啊啊啊啊啊啊在线| 91宗合网| 99re超碰| 欧美传媒| 最近2019中文字幕国语免费版| 国内精品久久人妻性色av| 一级二级在线观看| 激情 欧美 亚洲 小说| 亚洲乱色熟女一区| 中文字幕交换人妻| 色情综合| 人人澡人人爽人人精品| 日韩午夜国产| 人妻少妇无码| 97色色色| 一牛影视成人片免费| 一区二区三区 日韩欧美| 黄片免费看的| 国产乱码久久| 日本一片一区| 成人区人妻精品一| 九九九久久久| 亚洲日韩美国人妻| 久久久无码国精品无码三区三区| 久久99热这里只频精品6学生| 天天综合日韩网| 白丝少妇一区二区| 久久午夜神马| 福利操逼| 天天射网| 丰满少妇精品一区二区| 青青青国产手线观看视频2| 日韩精品在线观看观看| 男人天堂2019亚洲| www被窝色com| 97视频在线| 美女操逼福利视频| 色999偷自拍拍| 国产精品一级特黄aaa大片在线观看| 中文字幕88av在线| 久久综合乱子伦国产免费| 日韩91网| 中文字幕在线观看视频www| 97精品在线| 操逼片国产| 国产欧美日韩臀| 亚洲精品免费中文字幕| 97精品视频免费| 国产精品国产亚洲区艳妇糸列| 在线观看十八禁| 日韩三级伊人| 天天操天天射青青草| 少妇综合网| 日韩熟女精品无码专区一区二区| 人人搞人人插人人操| 久久精彩视频9| 一级做a爰片性色毛片久久| 亚熟在线| 成人亚欧免费视频| 国产自偷| 日本 欧美 亚中文字幕| 亚洲影院成人| 日本加勒比无码专区一二三| 狠狠狠狠狠狠| 自拍偷拍第26| 男人的天堂久久狠| AV九九| 热热色91| 亚洲av热热色| 91热爆在线| 大香蕉一级黄色片久久| 福利一级版子| 丁香六月啪啪| 欧美少妇性爱网站| 欧美 亚洲| 少妇69中文| 久久精品店| 亚洲欧美人妻| 任你干在线视频| 丁香六月啪啪| 91性高朝久久久久久久久| 99热99re6国产在线播放| 开心五月天激情网| 天天看天天在线精品| 日本亚欧爱爱| 超碰人妻中文在线| 久久久精品久久| 欧美精品99久久久| 91快色色色色色| 久久久无码视频| 超碰综合色| 伊人婷婷五月天| 久久黄片国产一区二区| 久久久无码精品人妻二区| 色综合中文字幕不卡| 亚洲AV噜噜狠狠网址蜜桃动漫| 人妻熟妇一区二区三区| 久久久久9| 国产人妻精品久久久一区二区三区| 17c在线成人免费A片观看| 国产精品农村妇女| 97在线资源| 大香蕉免| 丰满人妻-区二区三区免费| 不卡一区二区日本视频| 日本孕妇一区二区视频操逼免费看| 啊啊啊啊啊啊啊网址在线观看| 美女露胸露屁股| 俺去俺来也在线www| 国产精品麻豆免费视频| 精品国产乱码久久| 一级AAA片一区二区三区| 大肉棒导航| 99re8超碰| 国产11页| 久久色情| 国产99 中文字幕日韩小视频| 强奸乱伦亚洲第一页| 婷婷操视频| 99999精品| 600国产精品视频| 黄页网站成人免费| 欧美图片校园春色| 一本色道久久综合狠狠操| 97超碰在线资源网站| 1234区中文字幕在线观看_青青草国产在线_日韩一区二区 | 欧美一区二区成人一卡| 天天干天天日天天射黄色大片| 国产精选视频| 麻豆视频一区二区| 老熟女网站| 人妻精品一区二区| 国产日韩久久| 免费操逼91| 免费观看日本操逼视频| 肏逼视频日本| 日韩精品一区二区高清| 亚洲图片日本AⅤ欧美在线| 浓厚中出中文字幕在线| 肏逼福利网站| 粉嫩av久久一区二区三区| 夜夜操美女| 亚洲小电影免费涩涩成人在线高清| 欧美日韩*字幕一区| ji熟女.com| 成人三一级一片aaa| 亚洲色图殴美色图激情乱伦| 在线啊v一区| 色色激情五月天| 91黑丝在线播放| 97WW精品| 操淫穴亚洲五月丁香| 日韩欧美天堂| 丰满人妻一区二区三区四区| 国产毛片片精品天天看视频| 奇米四色影视777久久久| 午夜电影在线观看无码专区| 大香蕉婷婷| 少妇毛片久久| 欧美天堂亚洲电影院一区在线播放| 亚州九九九精品视频| 欧美丝袜亚洲| 欧美爱爱97| 中文久久| 久久久精品成人国产| 99久久网站| 久九干| 国产精品色哟哟| 熟妇人妻一区二区三在线| 欧美美逼| 夜草网站| 精品国产丝袜一区二区三区乱码| 亚洲欲色| 男人天堂最新手机版在线青青草| 午夜毛片亚洲精品片国产久久久| 91欧洲国产成人久久精品网站| 国产精品无码久久久久2025| 久久婷婷热| 99re95| 天天综合网亚洲综合网| 日少妇视频| 久久久久久久亚洲Av无码| 人妻精品视频一区二区| 97超碰国产精品| 超碰97欧美日韩| 久草资源在线| 久久黄色视频一区二区三区| 国产亚洲 中文欧美久久| 久草综合视频| 国产又黄又爽| 欧美,日韩,亚洲视频| 99这里有精品视频| 久久成人午夜狠狠| 曰韩人妻中文字幕在线 | 91色碰| 91超碰碰在线| 秋霞Av理论一级在线| 久久精品国产72国产精品福利| 久操黄色视频| 天堂av最新电影网| 天天看天天干| 青青草视频久久| 风月影院男女十八禁| 亚洲色狠| 欧美日韩第一页| 欧洲与亚洲欧美精品中文字幕| 97在线公开视频| 青青久久手机线视频| 91 亚洲 欧洲| 四虎影视国产精品| 爱av免费| 中文幕97| 亚洲欧美日韩免费观看| 日夜伊人网| 黄色高清无码无码破解免费暗网| 国产精品久久久久久久久久久久久久久 | 99自拍B亚洲 | 欧美曰韩国产精品| 日韩性爱一级片| 久久爱97| www99热| 中国黄色特级精品一区二区三区片| 日产欧美电影一区二区三区| 丝袜美腿诱惑亚洲欧美视频在线观看 | 夜夜操天天肏| 男人的天堂1024| 久久鲁干| 四虎免费在线播放| 操逼网站视频漫画国产| 日韩人人精品| 欧美性爱系列| 国产人人干| 国产精品久久久久久久久AV大片| 欧美色色人| 人人看欧美性爱| 日日嗨AV一区二区夜夜| 精品成人亚洲午夜电影| 亚洲色图 图片| 日本黄色大片一级视频免费麻豆| 大香蕉免| 精品国产人成在线| 亚洲性图91| 日韩不卡毛片Av免费高清| 亚洲青色欧美| 岛国毛片手机在线观看| 久草成人影片| 国产超碰| 久久久久久久| 午夜天堂精品久久| 逼操网站| av2014 日韩在线中文字幕| 国产亚洲精品自在线亚洲情侣| 天天日骚逼熟女| 人妻嗯啊啊在线播放| 国产精品视屏| 国产人伦精品一区二区三区| 国产亚洲女v在线观看| 日本精品九九九| 91性高潮久久久久久久久| 中国91AV| 亚洲色堂免费视频| 亚洲欧洲精品视频发布| 欧美综合自拍亚洲综合图| renqi久久久久久久久久久久| 超碰在线一区二区| 欧洲免费一区二| 黄片aaaaa一区| 蜜臀久久99精品久久久久电影| 午夜精品99久久久久传媒| 日韩av无码网站| 欧美色图 人妻| 婷婷色导航| 成人一二| 女人香蕉久久毛毛片精品| 欧美大香蕉卡久久| 95自拍视频在线观看| 性欧美91| 97超级欧美| 五月天激情小说| 在线观看亚洲成人精品| 欧美亚洲美少妇一区二区| 美日韩成人| 岛国1区2区3区在线观看| 四虎影视国产精品| 国产天天骚| 岛国片国产成人亚洲播放| 国产麻豆91欧美一区二区久久婷婷国产精品| 一区二区 韩日AV| 日日操丁香五月天| 97超碰精品| 亚洲综合色图欧美| 婷婷丁香一区二区三区| 色婷婷亚洲婷婷| 波多野结衣先锋影音| 九九九九精| 亚洲91射| 日韩欧美丝袜诱惑| 蜜臀少妇一区二区| 91成人在线免费视频| 中文字幕午夜精品久久久| 116美女午夜| 在线99热| 欧美国产伊人久久久久| 最新亚洲黄色免费电影| 四虎精品一区二区| 天天综合网合集91| 天天综合网~91入口| 亚洲精品819| 婷婷激情五月天小说网| 日本性爱视频一级| 久久久久久97| 蜜臀久久久99久久久久| 国模91| 性交一区二区在线播放| 亚洲国产一级中文综合久久天堂在线免费观看 | 日本精品久久久久久久| 丝袜喷水在线| 内射中出日韩在线观看视频| 日本欧美成人片AAAA| 色播综合| 亚洲各类熟们中文字幕| 超碰人人超在线观看| 日本东京热加勒比久久| 日韩欧美性吧婷婷乱伦大香蕉| 久久国产乱子伦精品免费女,网站| 影音资源男人日韩| 天天干1区2区在线| 国产第11页| 啊啊啊啊啊好舒服视频| 久久久久七视频| 日本一区二区三区精品| 亚洲瓯美色图| 日韩av熟女一区二区三区成人| 蜜桃久久久久久久| 日韩精品.久久精品.AV女优.天美传媒| 婷婷久久综合久| 爱我干综合| 91free福利| 丁香六月综合激情| 国产成人网址| 在线观看综合精品亚洲| 亚洲1区| 五月天综合网| 超碰激情808| 97欧美精品综合| 久久99精品国产| 欧美人妻中出| 大香蕉99re| 91亚洲图片| 凹凸 69堂 在线播放| 三级色影综合网| 久久精品超碰| 日本熟女不卡视频| 国产精品区在线12p| 国产亚洲精品农村妇女| 国产精品久久久久久 百度| 大香蕉综合| 碰碰在线视频| 大香蕉欧美伊| 久久久久幕乱码| 91情色在线| 亚洲97成人在线观看| 色色网91| 九九Av| 69人妻人人揉人人躁人人精品| 午夜福利区| 丰满人妻一区二区中文| 熟妇激情| 亚洲欧美人妻| 性在久久久久久| www.婷婷| 激情终合网| 少妇三p| 日韩免费簧片| 亚洲午夜福利在线影院| 920日本午夜免费| 好看的91视频| 亚欧操逼片在线观看 | 91爱啪| 91精品久久久| 欧美黄页在线| 五月开心久久AV官网| 欧美高清色| 免费一级黄色录像影片| 久久日韩毛| 综合一区二区影视| 九七超碰| 多乙久久久久久| 99re6久热只有精品6在线直播| 青青草狠狠撸| 久久69| 国产激情片在线观看| 不卡九肏| 色悠久| 亚欧性爱ab| 婷婷另类小说| 丰满人妻一区二区三区免费| 天天色综亚洲91污| 亚洲男人天堂网久久| 91精品人妻一品二品三品| 色翁荡息又大又硬又粗又爽| 屁屁影院一区二区三区国产| 91天堂视频| 91色插| 操一区| 中文字幕、久久精品国产2020、久久综合久久自在自线精品自、亚洲 | 97网址97| 亚洲āv网址在线观看| 九九色精品| 伊人网一本| 欧美激情性爱视频网站| yazhousetuoumei| 成人性交午夜免费片| 亚洲色图亚洲无码强奸乱伦| 老熟女熟妇| 永久免费观看的毛片的网站| 婷婷久久大香蕉| 九草九九九| 亚洲成人性爱网站在线播放| 久久综合日韩亚洲欧美| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 久操免费在线| 人妻22p| 天天躁日日躁狠狠狠躁| 韩国三级理论在线| 久久机热| 美女写真| 亚洲色图第四色| 高清一区AV无码| 亚洲揄拍网| 欧美不卡在线一区二区| 97内射偷拍| 久久伊人最新网址视频| 久久一二三级一一一| 亚洲欧美999| 人人手机欧洲亚洲国产人妻| 亚洲日韩美女丝袜美腿人妻视频| 国产精品一区二区三区在线密挑| 暴力av在线| 国产精品交换一区二区| 国产精品久久泡妞网站| 色婷婷成人| 午夜一区| 影音先锋乱| 91国产丝袜白虎| www久久99| 中国少妇啪啪视频| 亚洲操操操| 尤物av网站免费在线播放| 久久久久性熟视频| 国产呦精品系列在线观看| 日本不卡高清免v欧美日韩在线观看| 超碰九7| 欧美 传媒 麻豆 日韩 偷拍| 18禁无码永久免费无限制| 久久日本熟女精品一区| 日韩色| 亚洲色婷婷综合久久久久中文| 国产高潮AA片免费看| 一区二区三区四区理论片| 91xingse| 台湾成人无码AV| 啊啊啊啊啊舒服| 麻豆久久久一区二区| 干少妇视频| 蜜屁Av| 久久综合激情| 日韩一级二级三级免费看完整版| 德国一二三不卡| 国产精品免费美女视频| 久区视频| 日本最新免费韩国1区2区视频播放| 眼镜人妻101.com| 91激情国产| 99少妇精品视频| 精品少妇人妻av久久免费| 啊啊啊好疼| 久久欧美1卡2卡3| 岛国在线免费视频| 欧美激情 亚洲色图| 久久最新免费视频23| 国产第25页在线观看| 97精品一区二区视频在线观看| 婷婷三区| 久久九九国产精品| 色网站导航大全| 亚洲精品黑丝| 一本正道久久熟女| 玖玖爱免费观看视频| 少妇被c 黄 免费观看| 亚洲男人的天堂网| 久久久亚洲精品电影免费看| 日韩无码黄色片| 97超碰碰| 人妻丰满熟妇av无码区蜜桃| WWW.加勒比人妻一区不卡.com| 97任你吞精| 一区不卡在线观看av| 美女黄色91| 中文字幕第23区| 亚洲,欧美,春色,另类| 黄色免费网页无码| 欧美不卡五十路| 亚洲AV色图| 熟女一区二区三区| 800zy一区二区| 久久婷婷亚洲| 欧美午夜一区二区三区| 欧美三级不卡| 国内毛片无码一级毛片| 国产一区二区三区视频在线看| 爱爱动态60秒| 亚洲久草AV色图| 97超碰超欧美。| 婷婷五月天_亚洲小说欧美激情另类_精品久久国产字幕 | 国产原创精品| 婷婷伊人| 日韩欧美俄罗斯A片| 久久久久久一日韩字幕无码| 亚洲精品少妇| 欧美自拍网| 色眯眯av| 九一性生活免费视频| 亚洲人在线| 欧美综合加勒比在线| 强奸乱伦动态污图免费| 欧美日韩国产中文精品字幕自在自线| 78操B| 97操碰| 国产9熟妇视频网站| 俞拍自拍| 欧美激情亚洲情色| 久操在97| 亚洲综合骚逼| 国产盗摄美女如厕大神作品在线观看 | 婷婷婷婷婷婷久久久久| 精品视频一二三中文| 国产乱码久久久| 国产乱码久久久| 免费男人的天堂| 九九九九精品在线| 精人妻无码一区二区三区伊人直播| h色99999| 男人的天堂在线| 成人精品欧洲亚洲| 日韩欧美水蜜桃人妻| 久草精品视频| 伊人aaa| 999九九精品| 丰满少妇精品一区二区| 欧美青青草视频| 欧美色97| 九九九九AV| 91精品老女人| 婷婷超| 久久中文字幕一区不卡| 亚洲精品国产熟女| 国产精品一区二区 尿失禁| 久久精品国产亚洲AV嘿嘿| 国产精品成人蜜臀AV在线| 欧美性爱在线无码| 色婷婷丁香| 国产久久久9999| 欧美狠狠弄| 亚洲大色鬼| 极品出轨视频网站| 日本淫乱女一区二区三区视频| 一中国女人毛片水真多| 久久久久久一日韩字幕无码| 中文字幕国产| 大香蕉五月天| 日韩中文字幕熟妇人妻| 91网18| 日本中文字幕在线视频| 91丨九色丨国产打屁股| 日韩偷拍色图| 男人干美女| 五十路熟女,国产欧美精品区一区二区三区| 97超碰总站| 天天拍夜夜| 日韩有码 一区二区三区| 久草免费福利在线播放| 欧美男人一区| 日韩av熟女一区二区三区成人| 中字一区| 老熟女91视频| 人人妻人射| 国产免费永久精品无码| 夜夜嗨av午夜成人| 狠狠躁日日躁夜夜躁A| AV中亚| 亚洲黄色a级片| 国产剧情一区在线观看| 天天综合网~91综合网| 日逼97| 自拍偷拍 高清无码| 色婷婷亚洲婷婷| 欧美国产有色电影| 夜夜青青无码影院| 国产精品片| 天天日天天干天天整| 91爱综合| 欧美午夜熟妇黑人精品91| 视频国产成人精品日本亚洲18| 欧美成人一级免费电影| 97精品综合久久| 欧美精品三区| 日韩免费中文字幕视频| 成人一二| 日本人人操人人操| ′ !γ}丶。。久久精品欧美一区二区三区| 美女天天干| 91少妇| 狠狠色综合网| 校园春色亚洲欧洲| 999久久久九九九九| 亚乱色| 99久久无色码| 嗯嗯啊啊操死我| 大白逼三四级| 亚洲啪啪视频一区二区| 日韩亚洲美州欧洲综三区一品在线| av婷婷色网| 欧美综合自拍亚洲综合图| 亚洲熟女性高潮久久久| 天色综合网| 色九久| 日韩中文字幕二区| 9999亚洲精品| 老熟女搡BBBB搡BBBB视频| 欧美极品性爱天天射| 久久e6只有精品| 国产精品96| 操91| 久久久无码精品人妻二区| 欧美日本不卡在线| 国产欧美亚洲精品a第2页| 啊啊啊啊啊啊啊国| 久夜操| 亚洲啪啪性视频| 亚洲情色婷婷五月天| 97频视在线| 超碰97日韩| 九九黄色视频在线观看| 大香蕉在线86| 成人AV超碰免费在线| 久视频在线观看| 亚洲国产成人精品女人久久久| 欧美综合娱乐久久| 骚逼高潮久久精品| 国产精品视频在线播放| 亚洲情色 自拍| 黄色片一区二区三区四区五区| 精品久久久亚洲AV成人网站| 成人在线午夜视频一区| 中日韩久久久| 人妻系列无码专区中文有码| 中文一区在线日| 色欲日韩欧美在线一区| 亚拍在线| 风流老熟女一区二区三区l| 麻豆黄色五月天| 搡老女人老91妇女老熟女| 丁香五月激情综合国产| 日韩在线女优天天干| 熟女人妻精品一区二区视频 | 一区二区三区视频| 熟女在线视频| а√天堂资源官网在线资源| 婷婷色色五月天| 亚洲做性| 91九九| 91n处女在线观看| 日本天堂网| 九区国产| 久热在线精品免费观看| 国产AV线| 国产剧情一区在线观看| 影音先锋少妇| 九九热九九| 亚洲国产中文字幕| 一区二区三区 丝袜 高跟 美腿| 久久久草草精品| 日韩不卡网操逼中文字幕日韩| 男女啊啊啊| 丰满人妻一区二区三区四| 国产精品露脸在线观看| 色老牛| 亚洲人妻av| 97干在线视频| 亚洲自拍欧美国产首页网曝| 日韩欧美性爱电影在线观看| 国产67194| 深夜福利黄片| 久久久∴| 免费一级视频特黄色大片| av亚欧| 久久草草欧美精品| 在线欧美亚洲| 第四色色综合91| 人人干人人搞人人摸| 91美女在线观看| 97自拍一区| 九九99久久| 密乳无码| 亚洲高清欧美总合| 超碰天天操| 欧美精品99久久久| 欧美国产欧美在线观看| 超碰九7免费| 媚薬在线视频麻豆| 欧洲无码一区二区| 1769精品一区二区三区| 日日超碰亚洲| 4tube欧美女厕所| 97亚洲欧美日韩| 亚洲激情网一二三四区| 日韩成人精品视频自拍| 国产一区二区三区久久精品太古里| 日韩成人精品视频自拍| 久久成年片色大黄全免费网站| 日本免费不卡二区| 2024人人操人人摸| 99热99re6国产在线播放| 精品网站9999| 噜噜噜在线视频| 久草精品视频| 日韩一区二区熟女| 亚洲国产麻豆一区二区三区| 在线色资源| 欧美 日韩 婷婷 五月| 中文字幕五区| 色999五月色| 亚洲国产午夜真人一级片中文字幕精品黄网站 | 五月丁香激情综合网| 精品毛片av一区二区| 狠狠婷婷亚洲中文综合久久| 亚洲人精品午夜不卡| silk lablo在线观看一区二区| 大香蕉丝袜一级片| 欧美色图 色综合图| 极品美女嘿咻| 欧美在线|亚洲| 久草精品国产蜜臀 | 欧美日韩中文字幕人妻| 国产视频97| 免费成人在线熟妇网| 91九九九小逼| 日韩精品高清资源在线| 久久久久免费少妇| 国产 日韩 欧美高清| 大JI巴好深好爽又大又粗视频| 久久精品人妻一区二区| 欧色综合| 18一区二区三区| 嗯嗯啊啊操死我| 九久9热| 色综合av男人天堂| yellow网站免费观看日韩高清无码| 久久丝袜| 欧美另类天堂| 亚洲精品乱码久久久久久蜜桃麻豆| 天天日日本| 在线观看十八禁| 国产精品经典一卡久久久| 啊a一区在线| 久久久久久性爱片| 欧美日韩222| 二级久久网| 青青草精品| 日韩噜噜69| 久久人体一区二区| 锕锕好爽 死我在线观看| 玖日综合网| 干B网| 人妻丝袜日本| 大香蕉78| 国内毛片国产欧美拍| 亚洲 小说 欧美 激情 另类| 青青在线视频免费| 免费视频一二三区| 大香蕉综合网| 26UUU欧美日本| 涩涩涩综合| 久久毛卡| 操91| 乱日视频| 日韩激情视频| 中文字幕免费看| 久久黄人人爽视频| 少妇久久久久久久久| 国产一区二区三区免费视频在性观看| 伊人骚琪琪亚洲天堂网站| 国产精品熟女一区二区三区| 久久久久熟女| 国产 日韩,欧美 自拍| 天美传媒精品久久视频| 亚州综合在线| 亚洲,日韩,欧美,成人播放| 伊人久久大香线蕉无码| 99精品久久| 嫩草 人人网精品| 91天天c| 亚洲风情在线观看| 国产伊人精品在线| 亚洲男人的天堂va亚洲男人社| 国产99999久久精品| 丁香婷婷激情五月天无毒不卡| 天天操天天射青青草| 自拍视频大全亚洲专媒视频/一区二区三区 |