99精品久久精品一区二区-亚洲熟妇无码?v在线播放-日本国产精品无码字幕在线观看-久久久亚洲永夜AV-亚洲一级无码一区二区一-免费国产成高清人在线视频-中文字幕乱码免费观看-国产毛片精品妇女久久久

ARTICLE DETAIL

資訊詳情

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

Linux Socket編程:從底層通信原理到常見錯(cuò)誤排查

Linux Socket編程:從底層通信原理到常見錯(cuò)誤排查 我們直接聊Socket編程但聊的是寫第一行代碼之前你必須先搞明白的那些底層的、通信層面的東西。很多教程一上來就甩給你socket()、bind()、listen()的函數(shù)簽名然后讓你抄一個(gè) echo server跑通了就以為會(huì)了。但一旦遇到高并發(fā)、連接超時(shí)、端口被占這類現(xiàn)實(shí)問題很多人就懵了原因就在于對(duì)“Socket到底是什么”、“建立連接的過程究竟發(fā)生了什么”這些預(yù)備知識(shí)沒有建立起像樣的框架。這篇文章不是函數(shù)手冊(cè)而是幫你把操作系統(tǒng)的網(wǎng)絡(luò)通信模型在心中補(bǔ)全。我會(huì)把Linux下Socket編程從硬件網(wǎng)卡到應(yīng)用層的一整條鏈路拆開講清楚三次握手和accept()返回的關(guān)系、connect()為什么會(huì)被阻塞、bind()沖突是怎么產(chǎn)生的以及那堆熱詞里提到的常見報(bào)錯(cuò)——比如bind: only one usage of each socket address、create socket connection failure——到底是在哪個(gè)環(huán)節(jié)出了什么問題。適合所有剛?cè)腴TLinux網(wǎng)絡(luò)編程的開發(fā)者也適合那些擼過不少代碼但總是被詭異問題卡住的人把這篇文章當(dāng)一張排查地圖用。1. 整體設(shè)計(jì)與核心思路從一次HTTP請(qǐng)求反推通信全程以一次最常見的訪問網(wǎng)頁舉例。你在瀏覽器輸入地址回車頁面出來。這一過程里瀏覽器客戶端和Web服務(wù)器服務(wù)端之間發(fā)生了些什么每一步背后操作系統(tǒng)都做了什么數(shù)據(jù)從你的電腦發(fā)出到被服務(wù)器接收中間要經(jīng)歷應(yīng)用層構(gòu)造請(qǐng)求報(bào)文 - 通過Socket接口送進(jìn)內(nèi)核 - 傳輸層加TCP/UDP頭 - 網(wǎng)絡(luò)層加IP頭并路由 - 鏈路層封裝成幀通過網(wǎng)卡發(fā)出。同樣接收端從網(wǎng)卡收包后要逆序拆掉封裝、找到對(duì)應(yīng)的Socket、最終把數(shù)據(jù)交到應(yīng)用緩沖區(qū)。這個(gè)過程里最容易被人忽略的關(guān)鍵點(diǎn)是應(yīng)用進(jìn)程自己無法直接控制數(shù)據(jù)包該發(fā)到哪張網(wǎng)卡、怎么拆分重傳、如何保證順序——這些全由內(nèi)核的網(wǎng)絡(luò)協(xié)議棧完成。程序員做的只是通過Socket這個(gè)“門衛(wèi)”把數(shù)據(jù)和元信息目標(biāo)IP、目標(biāo)端口交給內(nèi)核然后等待結(jié)果。所以我建議每個(gè)打算深入Socket編程的人先養(yǎng)成一個(gè)習(xí)慣把“連接”不理解為一條物理存在的隧道而是理解為通信雙方在內(nèi)核中建立的一組狀態(tài)。TCP沒有實(shí)體線路所謂連接就是兩端各維護(hù)一個(gè)TCB傳輸控制塊記錄著序號(hào)、確認(rèn)號(hào)、窗口大小、擁塞狀態(tài)。理解了這一點(diǎn)后續(xù)理解超時(shí)重傳、半關(guān)閉、大量TIME_WAIT狀態(tài)都會(huì)輕松很多。1.1 Socket在通信模型中的定位應(yīng)用與內(nèi)核之間的“文件接口”Socket在國內(nèi)教材里常被翻譯為“套接字”這個(gè)翻譯不算錯(cuò)但容易讓人忽略它的本質(zhì)Socket首先是一種文件描述符。在Linux里萬物皆文件網(wǎng)絡(luò)連接也被抽象成了一個(gè)文件。你open()一個(gè)磁盤文件得到一個(gè)fd你socket()創(chuàng)建一個(gè)網(wǎng)絡(luò)端點(diǎn)也得到一個(gè)fd。后續(xù)的read()/write()/close()這些操作對(duì)一個(gè)普通文件和Socket文件幾乎是一模一樣的。這就引出了一個(gè)關(guān)鍵的設(shè)計(jì)思想Socket層是應(yīng)用層與傳輸層之間的一層抽象接口它隱藏了IP地址、端口、協(xié)議棧處理等一系列細(xì)節(jié)。你只需要告訴內(nèi)核三件事協(xié)議族IPv4還是IPv6、類型流式還是數(shù)據(jù)報(bào)、具體協(xié)議TCP還是UDP通常傳0表示默認(rèn)內(nèi)核就給你返回一個(gè)整數(shù)fd。之后你要連接或者監(jiān)聽都通過這個(gè)整數(shù)操作。從內(nèi)核實(shí)現(xiàn)看每個(gè)Socket在內(nèi)核中對(duì)應(yīng)一個(gè)struct socket和更底層的struct sock里面有發(fā)送緩沖區(qū)、接收緩沖區(qū)、等待隊(duì)列等。用文件描述符來指代Socket有一個(gè)絕妙的好處程序員不需要學(xué)習(xí)一套全新的I/O API而是可以復(fù)用select()、poll()、epoll()這些成熟的事件驅(qū)動(dòng)機(jī)制也可以和fork()配合實(shí)現(xiàn)經(jīng)典的多進(jìn)程并發(fā)服務(wù)器。我見過很多人初學(xué)Socket時(shí)總是想問“TCP連接和文件句柄有什么關(guān)系”關(guān)系就是——在Linux內(nèi)核眼里它們都是可讀可寫的I/O對(duì)象沒有本質(zhì)區(qū)別。1.2 定位四元組與端口為什么bind()沖突如此常見給應(yīng)用和連接建模時(shí)必須先搞清楚“一條TCP連接到底由什么唯一確定”。教科書答案是四元組(源IP, 源端口, 目的IP, 目的端口)。這個(gè)定義決定了你服務(wù)器能支持多少并發(fā)連接——它遠(yuǎn)不限于65535因?yàn)檫B接是靠四元組區(qū)分的不是僅僅靠服務(wù)端端口。兩臺(tái)不同客戶端機(jī)器分別連到你服務(wù)器的80端口它們的源IP不同就屬于兩條完全不同的連接。理解了四元組很多疑難雜癥就能解釋。比如熱詞里那條error: listen tcp 127.0.0.1:11434: bind: only one usage of each socket address——這是你程序調(diào)用bind()時(shí)指定的IP和端口組合已經(jīng)被另一個(gè)Socket占用了??赡苁巧洗纬绦蛲顺龊筮B接沒釋放干凈也可能是另一個(gè)進(jìn)程真的在監(jiān)聽。這里要強(qiáng)調(diào)一個(gè)初學(xué)者特別容易犯的錯(cuò)誤監(jiān)聽Socket和已連接Socket是兩種不同的fd。服務(wù)器監(jiān)聽時(shí)創(chuàng)建的fd只負(fù)責(zé)處理新連接請(qǐng)求每accept()一個(gè)客戶端內(nèi)核會(huì)創(chuàng)造出一個(gè)新的fd這個(gè)新fd才是和具體客戶端通信用的。老的監(jiān)聽fd始終守在那里等待下一個(gè)連接。所以千萬別一邊監(jiān)聽一邊拿著監(jiān)聽fd去read()數(shù)據(jù)那是搞錯(cuò)了對(duì)象。端口沖突也常常因?yàn)檫@個(gè)混淆而出現(xiàn)——有的人以為監(jiān)聽Socket關(guān)了但連接Socket還在TIME_WAIT狀態(tài)占著那個(gè)端口。抓包或者ss -ant看連接狀態(tài)是最直接的排查手段而不是靠猜。2. 核心預(yù)備知識(shí)TCP三次握手與Socket API的映射關(guān)系開始寫代碼前最有價(jià)值的事是把TCP狀態(tài)機(jī)和API調(diào)用對(duì)應(yīng)起來。書上說三次握手是SYN、SYN-ACK、ACK三趟看起來很抽象但其實(shí)每一次握手都對(duì)應(yīng)到你代碼里一個(gè)函數(shù)調(diào)用的返回甚至對(duì)應(yīng)到阻塞的解除。搞懂這個(gè)映射你去排查超時(shí)、半開連接、隊(duì)列溢出時(shí)就會(huì)非常有感覺。2.1 connect()、accept() 與握手過程的逐幀對(duì)應(yīng)標(biāo)準(zhǔn)握手的流程是客戶端先發(fā)SYN包服務(wù)端收到后返回SYN-ACK客戶端再回復(fù)ACK然后雙方進(jìn)入ESTABLISHED狀態(tài)。那么這幾步對(duì)應(yīng)到函數(shù)調(diào)用上具體是怎樣的客戶端的connect(fd, addr, len)一旦發(fā)起內(nèi)核立刻把SYN包發(fā)出去然后客戶端進(jìn)入SYN_SENT狀態(tài)。此時(shí)connect()不會(huì)立刻返回——它要等什么等第二個(gè)報(bào)文也就是服務(wù)端的SYN-ACK。收到后客戶端內(nèi)核發(fā)送ACK第三次握手然后connect()才返回成功。也就是說connect()返回成功的那一刻三次握手已經(jīng)完成了你的代碼可以馬上開始發(fā)送數(shù)據(jù)。服務(wù)端這邊有點(diǎn)繞。listen(fd, backlog)調(diào)用后內(nèi)核會(huì)維護(hù)兩個(gè)隊(duì)列半連接隊(duì)列SYN隊(duì)列存還未完成握手的連接和全連接隊(duì)列accept隊(duì)列存已經(jīng)完成握手、等待應(yīng)用取走的連接。第三個(gè)ACK到達(dá)服務(wù)端內(nèi)核時(shí)連接從半連接隊(duì)列移動(dòng)到全連接隊(duì)列。注意此刻accept()可能還沒被調(diào)用accept()只是從全連接隊(duì)列里取一個(gè)已完成的連接如果隊(duì)列為空accept()會(huì)阻塞默認(rèn)阻塞模式下。這個(gè)映射關(guān)系特別重要由此你能推導(dǎo)出很多結(jié)論第一握手成功不代表應(yīng)用層及時(shí)處理了連接中間隔著內(nèi)核隊(duì)列第二如果客戶端認(rèn)為連接已經(jīng)建立并瘋狂發(fā)數(shù)據(jù)但服務(wù)端遲遲不accept()內(nèi)核緩沖區(qū)會(huì)逐漸積壓數(shù)據(jù)最終客戶端可能阻塞在發(fā)送上第三listen()的backlog參數(shù)決定全連接隊(duì)列的長度設(shè)得太小在高并發(fā)下會(huì)出現(xiàn)丟連接的現(xiàn)象但設(shè)得太大也可能掩蓋應(yīng)用層處理能力不足的問題。2.2 狀態(tài)轉(zhuǎn)換與超時(shí)重傳心跳、半開連接與TCP Keep-AliveTCP是可靠傳輸可靠性建立在確認(rèn)與重傳機(jī)制上。數(shù)據(jù)發(fā)出去后如果遲遲收不到ACK發(fā)送方會(huì)超時(shí)重傳。而且這個(gè)超時(shí)不是固定值Linux內(nèi)核會(huì)根據(jù)RTT往返時(shí)間動(dòng)態(tài)調(diào)整——這就是RTO重傳超時(shí)時(shí)間。默認(rèn)初始RTO通常是1秒重傳一次后翻倍呈指數(shù)退避到一定上限后停止。由超時(shí)重傳引出的一個(gè)常見故障是“半開連接”。比如客戶端拔了網(wǎng)線服務(wù)端并不知道因?yàn)門CP沒有持續(xù)的心跳報(bào)文。除非你發(fā)數(shù)據(jù)發(fā)現(xiàn)收不到ACK否則連接會(huì)一直掛在ESTABLISHED狀態(tài)占用著fd和內(nèi)存。生產(chǎn)環(huán)境里很多“連接數(shù)緩慢上漲不下降”的詭異現(xiàn)場(chǎng)都是半開連接干的。解決辦法之一是開啟TCP Keep-Alive。在Socket上設(shè)置SO_KEEPALIVE選項(xiàng)后如果連接在2小時(shí)內(nèi)沒有數(shù)據(jù)交互內(nèi)核會(huì)自動(dòng)發(fā)探測(cè)報(bào)文若連續(xù)多次探測(cè)無響應(yīng)就判定連接失效關(guān)閉這個(gè)fd。2小時(shí)這個(gè)默認(rèn)值對(duì)多數(shù)應(yīng)用太長所以實(shí)踐中常通過TCP_KEEPIDLE、TCP_KEEPINTVL、TCP_KEEPCNT三個(gè)參數(shù)把它縮短到分鐘級(jí)。但Keep-Alive只能發(fā)現(xiàn)連接失效不能保證你的應(yīng)用邏輯是活的。如果你的服務(wù)有業(yè)務(wù)層心跳比如游戲服務(wù)器、長連接推送不要依賴TCP層的Keep-Alive而應(yīng)該自己在應(yīng)用層定時(shí)發(fā)Ping/Pong報(bào)文這樣能同時(shí)檢測(cè)對(duì)端進(jìn)程是否卡死進(jìn)程活著但無法及時(shí)響應(yīng)應(yīng)用邏輯。這兩層心跳的定位完全不同我在實(shí)際項(xiàng)目里見過有人以為開了Keep-Alive就萬事大吉結(jié)果業(yè)務(wù)線程死鎖了連接卻還顯示正常問題拖了很久才暴露。2.3 緩沖區(qū)語義為什么send()返回后數(shù)據(jù)還沒到對(duì)端幾乎所有初學(xué)Socket的人都踩過同一個(gè)坑調(diào)用send()成功了就以為數(shù)據(jù)已經(jīng)“發(fā)出去”了。實(shí)際上send()返回成功只代表數(shù)據(jù)被復(fù)制進(jìn)了內(nèi)核的發(fā)送緩沖區(qū)不代表對(duì)端已經(jīng)收到更不代表對(duì)端應(yīng)用已經(jīng)處理。你想象的鏈路是應(yīng)用 - 網(wǎng)卡 - 對(duì)端網(wǎng)卡 - 對(duì)端應(yīng)用。真實(shí)鏈路是應(yīng)用 - 內(nèi)核發(fā)送緩沖區(qū) - 網(wǎng)卡 - 網(wǎng)絡(luò) - 對(duì)端內(nèi)核接收緩沖區(qū) - 對(duì)端應(yīng)用調(diào)用read()取走。每一層都有緩沖每一層都可能延后。send()返回的字節(jié)數(shù)是本次寫入內(nèi)核緩沖區(qū)的字節(jié)數(shù)如果緩沖區(qū)暫時(shí)滿了send()可能會(huì)部分寫入返回小于你要發(fā)的長度也可能會(huì)阻塞。最令人意外的場(chǎng)景對(duì)端接收窗口為0時(shí)你這邊send()照樣可能成功因?yàn)閿?shù)據(jù)都堆積在本機(jī)內(nèi)核緩沖區(qū)里TCP流控機(jī)制暫時(shí)不發(fā)了而已。所以網(wǎng)絡(luò)編程進(jìn)階第一課就是不要指望一次send()就把整包數(shù)據(jù)發(fā)完、更不要指望對(duì)端立刻收到。通常的做法是循環(huán)發(fā)送直到數(shù)據(jù)全部寫入這叫“寫完整包”接收端則需要循環(huán)讀取直到拿到完整的業(yè)務(wù)報(bào)文這叫“讀完整包”。要完整理解緩沖區(qū)還要知道SO_SNDBUF和SO_RCVBUF這兩個(gè)Socket選項(xiàng)它們各自控制內(nèi)核發(fā)送/接收緩沖區(qū)的上限。在高吞吐場(chǎng)景適當(dāng)調(diào)大接收緩沖區(qū)能提升窗口大小進(jìn)而提升吞吐但也不能無腦調(diào)大內(nèi)存占用會(huì)上升而且TCP的自動(dòng)窗口調(diào)節(jié)可能因手工設(shè)置而被禁用反而適得其反。3. 實(shí)操要點(diǎn)與工具準(zhǔn)備搭建可復(fù)現(xiàn)的實(shí)驗(yàn)環(huán)境光聊理論不行Socket編程必須親手跑。我會(huì)用一臺(tái)Linux機(jī)器虛擬機(jī)上裝Ubuntu Server或者直接用WSL都行來做演示。建議不要一開始就在Windows上折騰Winsock雖然API大體類似但很多排查工具和行為細(xì)節(jié)不一樣。既然你搜的關(guān)鍵詞是Linux那就用Linux的手法來學(xué)。本機(jī)環(huán)境準(zhǔn)備其實(shí)非常輕量一個(gè)Linux內(nèi)核的shell裝好gcc或者python3也行。在開始之前先看看你的系統(tǒng)是否支持需要的工具sssocket statistics用來查連接狀態(tài)tcpdump用來抓包ncnetcat用來快速模擬服務(wù)端或客戶端。如果缺用包管理器裝一下# Ubuntu / Debian sudo apt update sudo apt install -y net-tools tcpdump netcat-openbsd gcc # CentOS / RHEL / Fedora sudo yum install -y net-tools tcpdump nc gcc裝這些工具的目的不是裝飾而是給你一雙“透視眼”。后面排查任何問題第一反應(yīng)都應(yīng)該是用工具觀察現(xiàn)象而不是盯著代碼干瞪眼。3.1 用Python演示一個(gè)最簡(jiǎn)TCP服務(wù)端從能跑到能排查這里我用Python演示而不一開始就用C是因?yàn)樗梢宰屛野炎⒁饬Ψ旁诰W(wǎng)絡(luò)行為上而不是被指針和返回值捆綁。代碼極其短幾行就能起一個(gè)監(jiān)聽服務(wù)import socket server socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((0.0.0.0, 9999)) server.listen(5) print(listening on 9999) while True: conn, addr server.accept() print(new connection from, addr) data conn.recv(1024) print(received:, data) conn.send(bhello from server\n) conn.close()這段代碼知識(shí)點(diǎn)不少我一一解釋。socket.AF_INET是IPv4通信域socket.SOCK_STREAM表示TCP流式Socket。setsockopt(SO_REUSEADDR, 1)的目的是讓服務(wù)器在TIME_WAIT狀態(tài)下也能重新綁定端口否則你CtrlC退出后再重啟常常會(huì)報(bào)“Address already in use”這是新手最常撞到的一堵墻。bind((0.0.0.0, 9999))的0.0.0.0表示監(jiān)聽所有網(wǎng)卡地址如果只想本機(jī)訪問可以寫成127.0.0.1但要注意這兩者對(duì)外表現(xiàn)差異很大。listen(5)設(shè)的backlog就是前面說的全連接隊(duì)列長度。運(yùn)行后在另一個(gè)終端用nc 127.0.0.1 9999連接并發(fā)送任意字符串服務(wù)端就能打印出來。跑通之后你可以在第三個(gè)終端敲ss -ant看連接狀態(tài)。你會(huì)看到有一條ESTAB的連接掛在那里如果客戶端還沒退出這比任何文字都直觀。3.2 tcpdump抓包實(shí)證親眼看三次握手與四次揮手只看到ESTABLISHED狀態(tài)還不夠建議拿tcpdump抓一次握手全過程。需要兩個(gè)終端一個(gè)跑tcpdump監(jiān)聽9999端口上的流量一個(gè)跑客戶端連接。抓包命令sudo tcpdump -i any port 9999 -n -S-i any監(jiān)聽所有網(wǎng)卡-n不做域名反解-S顯示絕對(duì)序號(hào)。然后啟動(dòng)一個(gè)連接你會(huì)看到類似下面這樣的一串報(bào)文1 客戶端 - 服務(wù)器 SYN 2 服務(wù)器 - 客戶端 SYN, ACK 3 客戶端 - 服務(wù)器 ACK 4 客戶端 - 服務(wù)器 PSH, ACK (攜帶數(shù)據(jù)) 5 服務(wù)器 - 客戶端 ACK 6 客戶端 - 服務(wù)器 FIN, ACK 7 服務(wù)器 - 客戶端 ACK 8 服務(wù)器 - 客戶端 FIN, ACK 9 客戶端 - 服務(wù)器 ACK第1到第3就是教科書上的三次握手。第4和第5是數(shù)據(jù)發(fā)送和確認(rèn)。第6到第9是四次揮手。親手抓到這一串報(bào)文之后你對(duì)TCP的“連接建立、數(shù)據(jù)傳輸、連接釋放”三階段會(huì)產(chǎn)生肌肉記憶以后看到任何狀態(tài)機(jī)圖都不會(huì)覺得抽象。有一個(gè)非常值得注意的細(xì)節(jié)如果是主動(dòng)關(guān)閉的一方在發(fā)完最后一個(gè)ACK后會(huì)進(jìn)入TIME_WAIT狀態(tài)并且要停留2MSL最大報(bào)文段生存時(shí)間通常60秒左右。抓包時(shí)你會(huì)發(fā)現(xiàn)第9個(gè)報(bào)文發(fā)完客戶端并沒有立刻消失而是在本地保留一段時(shí)間的連接記錄。這個(gè)狀態(tài)存在的意義是防止最后一個(gè)ACK丟失導(dǎo)致對(duì)端重發(fā)FIN。理解了TIME_WAIT你就能理解為什么高并發(fā)短連接的服務(wù)器上會(huì)出現(xiàn)大量TIME_WAIT連接堆積以及SO_REUSEADDR為什么能幫助服務(wù)端快速重啟或者更好地復(fù)用連接資源。3.3 nc、ss、lsof三連招一行命令快速定位“哪個(gè)進(jìn)程占著端口”遇到“Address already in use”時(shí)光看報(bào)錯(cuò)信息是不夠的你得找出是哪個(gè)進(jìn)程占著端口。排查手法如下組合使用三個(gè)命令基本能解決90%的問題# 1. 查端口監(jiān)聽狀態(tài) ss -tlnp | grep 9999 # 2. 查某個(gè)連接的狀態(tài)詳情 ss -ant | grep 9999 # 3. 查進(jìn)程打開的socket文件 lsof -i :9999ss -tlnp中的-t只看TCP-l只看監(jiān)聽中的Socket-n不做名稱解析-p顯示進(jìn)程信息需要root。輸出里能看到監(jiān)聽地址、端口、隊(duì)列的當(dāng)前值和最大值比如Send-Q和Recv-Q。對(duì)于監(jiān)聽SocketSend-Q顯示的是全連接隊(duì)列的最大長度就是backlogRecv-Q顯示的是當(dāng)前等待被accept()的連接數(shù)。如果Recv-Q持續(xù)不為0說明你的程序accept()速度跟不上新連接到達(dá)的速度這是典型的過載信號(hào)。lsof則是從進(jìn)程視角出發(fā)的工具能列出進(jìn)程打開了哪些Socket文件配合-i過濾端口。它最大的用處是當(dāng)你只知道端口號(hào)、不知道是哪個(gè)進(jìn)程時(shí)直接反查。建議把ss -tlnp和lsof -i刻進(jìn)DNA排查網(wǎng)絡(luò)問題時(shí)它們就是你的聽診器。4. 阻塞與非阻塞、同步與異步四象限里看懂事件驅(qū)動(dòng)幾乎所有Socket教程都會(huì)遇到“阻塞/非阻塞”和“同步/異步”這兩組詞但很多資料把它們混為一談。實(shí)際編碼時(shí)這兩組概念交叉形成四個(gè)象限搞混了代碼寫不順排查問題也無從下手。先下定義。阻塞/非阻塞描述的是I/O系統(tǒng)調(diào)用accept、read、write和當(dāng)前線程的關(guān)系阻塞時(shí)調(diào)用線程會(huì)一直在內(nèi)核里等待事件發(fā)生期間什么都干不了非阻塞時(shí)調(diào)用立即返回內(nèi)核告訴你“還沒好”然后你過會(huì)兒再來問。同步/異步描述的是數(shù)據(jù)拷貝由誰完成、什么時(shí)候完成同步I/O中應(yīng)用自己負(fù)責(zé)從內(nèi)核緩沖區(qū)把數(shù)據(jù)拷到用戶緩沖區(qū)拷貝過程中線程需要等待異步I/O中你告訴內(nèi)核“把數(shù)據(jù)放好了叫我”內(nèi)核完成全部拷貝后通過信號(hào)或回調(diào)通知你。Socket默認(rèn)是阻塞且同步的。accept()阻塞在那里直到有新連接進(jìn)來才返回recv()阻塞在那里直到緩沖區(qū)有數(shù)據(jù)可讀且至少返回一個(gè)字節(jié)。這種方式邏輯清晰但線程在等待時(shí)完全浪費(fèi)了CPU時(shí)間。解決辦法是兩類一類是搞多線程一個(gè)線程管一個(gè)連接阻塞也沒關(guān)系反正每個(gè)連接有專門的人伺候另一類是改成非阻塞配合select()/poll()/epoll()實(shí)現(xiàn)單線程管理成千上萬個(gè)連接也就是常說的Reactor模式。我見過不少新手剛學(xué)會(huì)epoll就把所有Socket一律設(shè)成非阻塞然后發(fā)現(xiàn)代碼突然變得難寫很多每次read()都可能返回EAGAIN每次send()都可能只發(fā)了一部分業(yè)務(wù)邏輯被打散成各種狀態(tài)。實(shí)際上epoll與阻塞Socket并不沖突你完全可以讓監(jiān)聽Socket保持阻塞每次epoll_wait()返回可讀事件時(shí)再調(diào)用accept()——這個(gè)函數(shù)不會(huì)阻塞太久因?yàn)槭录ㄖ呀?jīng)告訴你內(nèi)核里至少有一個(gè)連接在等待取用。同理只要epoll告訴你可讀你recv()一般也不會(huì)長時(shí)間阻塞。所以阻塞/非阻塞不是絕對(duì)的非黑即白關(guān)鍵是搞清楚你的程序在哪里可能被卡住。簡(jiǎn)單總結(jié)我個(gè)人的踩坑心得如果是寫一個(gè)簡(jiǎn)單的工具腳本直接用阻塞模型最省事如果是小規(guī)模的并發(fā)服務(wù)幾十上百連接多線程阻塞模型依然清晰真到了萬級(jí)連接才需要非阻塞加事件驅(qū)動(dòng)。不要一上來就epoll那是把簡(jiǎn)單問題復(fù)雜化。4.1 阻塞模型與多進(jìn)程/多線程經(jīng)典服務(wù)端架構(gòu)的取舍早期Unix網(wǎng)絡(luò)服務(wù)最經(jīng)典的做法是父進(jìn)程阻塞在accept()上每來一個(gè)連接fork()一個(gè)子進(jìn)程去處理。子進(jìn)程繼承了已連接Socket的fd處理完就close()退出父進(jìn)程繼續(xù)監(jiān)聽。這種模型的好處是進(jìn)程隔離性好一個(gè)客戶端搞掛了子進(jìn)程不會(huì)影響其他連接。但進(jìn)程開銷也大頻繁創(chuàng)建銷毀進(jìn)程的成本不容忽視。線程模型更輕量一些pthread_create比fork便宜但線程之間共享地址空間一個(gè)線程崩潰可能影響整個(gè)進(jìn)程?,F(xiàn)在多數(shù)動(dòng)態(tài)語言Python、Ruby還有GIL限制多線程網(wǎng)絡(luò)服務(wù)經(jīng)常被詬病難以利用多核這類場(chǎng)景下常見的選擇反而是多進(jìn)程或者干脆用異步框架。有一種說法“服務(wù)器性能不好是因?yàn)榫€程不夠多”這個(gè)觀點(diǎn)值得商榷。線程切換本身就有開銷連接數(shù)一多大量CPU時(shí)間花在上下文切換上真正處理業(yè)務(wù)的時(shí)間反而變少。一個(gè)更合理的思路是線程池固定大小比如CPU核數(shù)的兩倍使用非阻塞IO加事件通知讓少量線程服務(wù)大量連接。這就是生產(chǎn)級(jí)網(wǎng)絡(luò)庫的通用做法。4.2 非阻塞加IO多路復(fù)用為什么用epoll而不用select非阻塞模型下應(yīng)用怎么知道哪個(gè)fd可讀了select()是最早的多路復(fù)用接口但它有兩個(gè)硬傷一是fd數(shù)量上限很低通常是1024由FD_SETSIZE決定二是每次調(diào)用都要把全部的fd集合從用戶態(tài)拷貝到內(nèi)核態(tài)、再從內(nèi)核態(tài)拷貝回來還要線性掃描所有fd復(fù)雜度是O(n)連接數(shù)一多就很吃力。poll()取消了1024的上限但每次調(diào)用仍然要全量拷貝fd數(shù)組性能瓶頸沒消除。epoll是Linux專屬的高性能方案它解決了兩件事注冊(cè)過的fd留存在內(nèi)核的事件表里不需要每次重復(fù)傳入并且靠回調(diào)機(jī)制內(nèi)核只把“真正有事件發(fā)生”的fd通過就緒鏈表通知你你epoll_wait()的返回次數(shù)基本等于有事可做的fd數(shù)量效率不隨總連接數(shù)線性惡化。如果你寫的是跨平臺(tái)代碼select/poll的兼容性更好但如果確定在Linux上跑高并發(fā)服務(wù)直接用epoll沒有必要轉(zhuǎn)彎子。用epoll時(shí)的常見陷阱是忘記處理邊緣觸發(fā)模式下數(shù)據(jù)沒讀完的問題。水平觸發(fā)只要緩沖區(qū)有數(shù)據(jù)就會(huì)一直通知你沒讀完下次還能繼續(xù)邊緣觸發(fā)只在狀態(tài)變化的瞬間通知一次你如果一次沒讀完可能要等新的數(shù)據(jù)到達(dá)才會(huì)再次收到通知所以邊緣觸發(fā)模式下你必須用循環(huán)把數(shù)據(jù)全部讀干凈直到read()返回EAGAIN為止。我對(duì)初學(xué)者的建議是先用水平觸發(fā)邏輯簡(jiǎn)單不容易出錯(cuò)等真能吃透邊緣觸發(fā)再切換別在最開始就給自己的代碼增加調(diào)試難度。4.3 異步IO的面貌從io_uring看新一代方案?jìng)鹘y(tǒng)的epoll本質(zhì)上還是同步I/O只是它讓線程不用阻塞在某個(gè)fd上而是統(tǒng)一等待事件。真正的異步I/O在Linux上經(jīng)歷過幾輪波折直到io_uring出現(xiàn)才真正成熟起來。io_uring通過內(nèi)核與用戶態(tài)共享一組環(huán)形隊(duì)列應(yīng)用可以批量提交讀寫請(qǐng)求內(nèi)核完成數(shù)據(jù)拷貝后通過完成隊(duì)列通知應(yīng)用整個(gè)過程用戶線程不需要阻塞等待數(shù)據(jù)拷貝結(jié)束。io_uring的好處體現(xiàn)在高IOPS、低延遲和高吞吐場(chǎng)景比如數(shù)據(jù)庫引擎、代理服務(wù)、存儲(chǔ)中間件等。但它對(duì)編程模型的要求更高代碼復(fù)雜度也是直線上升。如果你只是做一個(gè)業(yè)務(wù)API服務(wù)大概率用不到io_uringepoll或者現(xiàn)成的異步框架已經(jīng)綽綽有余。但如果你是做基礎(chǔ)組件、中間件或者深入研究Linux存儲(chǔ)和網(wǎng)絡(luò)棧io_uring值得花時(shí)間了解。這算是一條比較超前的學(xué)習(xí)路徑不急先把epoll玩明白再說。5. 常見錯(cuò)誤與排查經(jīng)驗(yàn)速查給報(bào)錯(cuò)找病根這一部分我把熱詞里出現(xiàn)的、以及我實(shí)際開發(fā)中踩過的典型網(wǎng)絡(luò)報(bào)錯(cuò)整理成速查式說明。任何一個(gè)報(bào)錯(cuò)出現(xiàn)時(shí)先判斷它屬于哪一大類。我把常見錯(cuò)誤歸為四類創(chuàng)建失敗、連接失敗、綁定失敗和運(yùn)行期異常每一類對(duì)應(yīng)不同的排查方向。報(bào)錯(cuò)信息示例問題環(huán)節(jié)常見原因排查命令/手段create socket connection failure (-70028)連接或創(chuàng)建失敗報(bào)文里這段報(bào)錯(cuò)常見于數(shù)據(jù)庫客戶端如某些國產(chǎn)數(shù)據(jù)庫/中間件可能是網(wǎng)絡(luò)不通、端口未監(jiān)聽、或Socket資源耗盡ss -ant,ping,telnet IP 端口,ulimit -nbind: Address already in usebind階段端口已被占用或前一個(gè)進(jìn)程未徹底釋放端口ss -tlnp,lsof -i :端口, 注意SO_REUSEADDRconnect: Connection refusedconnect階段目標(biāo)端口沒有進(jìn)程在監(jiān)聽或者防火墻拒絕了連接也可能是服務(wù)端隊(duì)列已滿但概率較低ss -tlnp,iptables -L -n,nc -vz IP 端口error 2002 (HY000): Cant connect to local MySQL server through socket /tmp/...local socket連接失敗MySQL服務(wù)未啟動(dòng)、Socket文件路徑不對(duì)、權(quán)限不足、或服務(wù)監(jiān)聽在TCP但客戶端走Unix Socketsystemctl status mysql,mysql -h127.0.0.1 -P3306Connection timed outconnect超時(shí)數(shù)據(jù)包被丟棄防火墻、目標(biāo)IP不可達(dá)、對(duì)端負(fù)載過高ping,traceroute, 檢查防火墻/安全組: Connection reset by peerread/write階段對(duì)端進(jìn)程崩潰或主動(dòng)關(guān)閉了連接也可由防火墻RST觸發(fā)抓包看RST標(biāo)記檢查對(duì)端應(yīng)用日志[08S01] create socket connection failure (-70028)連接建立失敗報(bào)錯(cuò)代碼段里的特定錯(cuò)誤先排查基礎(chǔ)網(wǎng)絡(luò)連通性再查目標(biāo)服務(wù)狀態(tài)nc,ss,tcpdump逐步定位下面挑幾個(gè)最常出問題的場(chǎng)景手動(dòng)拆一遍把排查思路走通。5.1 bind報(bào)錯(cuò)Address already in use的完整排查路徑復(fù)現(xiàn)場(chǎng)景你在終端跑了一個(gè)服務(wù)端CtrlC終止馬上重新啟動(dòng)結(jié)果拋出來bind: Address already in use。為什么因?yàn)槟J(rèn)情況下前一個(gè)進(jìn)程雖然是退出了但它之前建立的某些連接或者監(jiān)聽Socket還處于TIME_WAIT狀態(tài)。TIME_WAIT狀態(tài)下該Socket的四元組還占著端口新進(jìn)程想綁定同一個(gè)IP端口組合內(nèi)核會(huì)說“這個(gè)地址已經(jīng)被占用”。此時(shí)最直接的排查是ss -tlnp | grep 端口看輸出的State列。如果顯示TIME-WAIT就等它自然消失大約60秒或者設(shè)置SO_REUSEADDR選項(xiàng)繞過。注意SO_REUSEADDR之所以能生效是因?yàn)樗试S新Socket綁定一個(gè)處于TIME_WAIT狀態(tài)的本地端口這是TCP規(guī)范允許的例外。但還有一種情況端口被另一個(gè)活躍進(jìn)程占著比如另一個(gè)服務(wù)也在監(jiān)聽同樣的端口。ss輸出會(huì)顯示LISTEN狀態(tài)并帶著進(jìn)程名和PID。這時(shí)候你不能輕易殺進(jìn)程得先搞清楚為什么會(huì)撞端口?,F(xiàn)實(shí)中很多沖突來自架構(gòu)設(shè)計(jì)疏忽比如兩臺(tái)服務(wù)在同一臺(tái)機(jī)器上配了相同的端口或者是同一個(gè)進(jìn)程fork了多個(gè)子進(jìn)程子進(jìn)程繼承了父進(jìn)程監(jiān)聽的fd顯示起來像多個(gè)進(jìn)程占用同一端口。處理這個(gè)問題的思路是能復(fù)用端口就用協(xié)議層的機(jī)制不能復(fù)用就改配置不要通過暴力kill的方式掩蓋問題。端口規(guī)劃在服務(wù)上線前就應(yīng)該做好甚至可以考慮用固定端口段約束每個(gè)服務(wù)避免“誰的端口不夠了就隨處借”的亂象。5.2 connect失敗Connection refused 與 Connection timed out 的差異判斷Connection refused的語義其實(shí)是“對(duì)方明確拒絕了你”——最典型的情況是對(duì)端機(jī)器活著但指定端口上沒有任何進(jìn)程在監(jiān)聽。內(nèi)核收到你的SYN報(bào)文后一看沒有對(duì)應(yīng)Socket就直接回了一個(gè)RST你這邊connect()立刻失敗。這種錯(cuò)誤通常是快速失敗的定位也相對(duì)簡(jiǎn)單用ss -tlnp確認(rèn)目標(biāo)端口是否在監(jiān)聽如果沒監(jiān)聽就把服務(wù)拉起來如果有監(jiān)聽但你還是被拒絕那可能存在防火墻或者訪問控制需要繼續(xù)檢查iptables或云安全組。Connection timed out則完全是另一回事。你的SYN包像石沉大海沒有任何回應(yīng)。可能的原因是對(duì)端IP不可達(dá)比如路由不通、對(duì)端防火墻直接把你的SYN丟棄不發(fā)RST、或者目標(biāo)服務(wù)器負(fù)載過高來不及處理新連接。排查手段是分層遞進(jìn)先ping測(cè)主機(jī)通不通再traceroute看路徑上那一跳斷了最后抓包確認(rèn)你的SYN有沒有發(fā)出去、有沒有收到任何回復(fù)。很多云環(huán)境的安全組策略默認(rèn)丟棄而不是拒絕所以“ping通但端口連不上”是云上最常見的組合。還有一個(gè)容易被忽略的點(diǎn)服務(wù)端雖然進(jìn)程活著但全連接隊(duì)列已經(jīng)滿了。此時(shí)系統(tǒng)會(huì)丟棄新來的SYN不回應(yīng)客戶端就表現(xiàn)為超時(shí)。這種情況在ss -tlnp中能看到Recv-Q達(dá)到backlog上限所以看隊(duì)列長度非常重要。5.3 recv/send階段報(bào)錯(cuò)Connection reset by peer 的兩種真面目Connection reset by peer大概是生產(chǎn)環(huán)境里最讓人頭疼的報(bào)錯(cuò)之一。它發(fā)生在你讀寫數(shù)據(jù)的時(shí)候?qū)Ψ桨l(fā)來了RST報(bào)文內(nèi)核通知你“連接已經(jīng)被強(qiáng)制重置”。場(chǎng)景一對(duì)端進(jìn)程崩潰。比如你正從一個(gè)服務(wù)讀取數(shù)據(jù)對(duì)方突然進(jìn)程崩了操作系統(tǒng)在回收進(jìn)程時(shí)會(huì)對(duì)所有未關(guān)閉的連接發(fā)送RST你這邊下一次讀/寫就會(huì)收到Connection reset by peer。這種屬于被動(dòng)發(fā)現(xiàn)通常說明對(duì)端的穩(wěn)定性有問題。場(chǎng)景二對(duì)端應(yīng)用層主動(dòng)制造RST。比如你用SO_LINGER選項(xiàng)配合超時(shí)設(shè)置為0再調(diào)用close()內(nèi)核會(huì)發(fā)送RST而不是正常的FIN揮手。有些服務(wù)器在檢測(cè)到非法請(qǐng)求或者接收數(shù)據(jù)超限時(shí)也會(huì)用這種方式快速殺掉連接以此拒絕服務(wù)。這時(shí)候排查不能只看網(wǎng)絡(luò)要看對(duì)端應(yīng)用日志分析它為什么主動(dòng)斷開。我遇到過一次詭異的場(chǎng)景客戶端報(bào)錯(cuò)Connection reset by peer服務(wù)端日志卻什么異常都沒有。后來抓包才發(fā)現(xiàn)問題出在連接空閑時(shí)間太長中間的網(wǎng)絡(luò)設(shè)備把連接狀態(tài)已經(jīng)清掉了而兩端應(yīng)用都還認(rèn)為活著一有數(shù)據(jù)流量中間設(shè)備直接發(fā)RST。處理方式就是在應(yīng)用層設(shè)計(jì)合適的心跳機(jī)制讓連接不會(huì)靜默到被中間設(shè)備遺忘。5.4 Socket資源耗盡Too many open files 的隱含背景熱詞里的error: listen tcp 127.0.0.1:11434: bind: only one usage of each socket address雖然明面是bind錯(cuò)誤但有些線上環(huán)境里當(dāng)你反復(fù)創(chuàng)建連接不關(guān)閉、或者高并發(fā)場(chǎng)景下fd被耗盡時(shí)你會(huì)先撞上Too many open files。Linux對(duì)每個(gè)進(jìn)程可打開的文件描述符數(shù)量有限制默認(rèn)在ulimit -n查看很多系統(tǒng)默認(rèn)是1024。如果你的服務(wù)需要管理大量并發(fā)連接就必須調(diào)高ulimit -n 1000000但ulimit只影響當(dāng)前shell及其啟動(dòng)的進(jìn)程永久生效要改/etc/security/limits.conf或者systemd服務(wù)單元文件中的LimitNOFILE。要留意的是即使每個(gè)進(jìn)程的限制調(diào)高了整個(gè)系統(tǒng)的fd總量也有上限通過sysctl fs.file-max查看和調(diào)整。fd泄漏是一個(gè)隱蔽的問題。有些服務(wù)代碼里處理完連接后忘掉close()短時(shí)間內(nèi)看不出問題但運(yùn)行久了fd數(shù)量不斷上漲最終觸發(fā)Too many open files服務(wù)突然掛掉。排查辦法是監(jiān)控進(jìn)程的fd數(shù)量ls /proc/PID/fd | wc -l統(tǒng)計(jì)某個(gè)進(jìn)程打開的fd數(shù)量如果持續(xù)上漲且不回落幾乎可以斷定有泄漏。這種問題靠事后救火很被動(dòng)更重要的是一開始就養(yǎng)成資源所有權(quán)思維誰打開誰負(fù)責(zé)關(guān)閉異常分支也要確保close()被執(zhí)行。5.5 backlog隊(duì)列溢出忽好忽壞的連接成功率有一套典型案例值得專門說服務(wù)器并發(fā)不高但客戶端連接時(shí)好時(shí)壞開始時(shí)能連上高峰時(shí)段新連接就超時(shí)。看過很多次問題出在listen(fd, backlog)的backlog設(shè)置太小全連接隊(duì)列一旦滿內(nèi)核直接丟棄新連接。Linux 2.2之后backlog參數(shù)控制的是全連接隊(duì)列長度再早的內(nèi)核版本中它會(huì)同時(shí)影響半連接隊(duì)列。應(yīng)用層判斷是否溢出有兩個(gè)途徑第一ss -tlnp輸出中看Recv-Q那一列是否經(jīng)常等于Send-Q也就是backlog的最大值第二netstat -s看TCP統(tǒng)計(jì)信息中的listen queue overflow計(jì)數(shù)。如果計(jì)數(shù)很高說明你的服務(wù)端accept()速度跟不上連接建立速度此時(shí)調(diào)大backlog只是緩解真正要解決的是讓應(yīng)用層更快地消費(fèi)連接或者增加處理連接的線程。還有一個(gè)經(jīng)典坑某些框架或語言運(yùn)行時(shí)內(nèi)部把backlog重新設(shè)成了固定值比如Go的net.Listen默認(rèn)125你不一定能直接控制它。這時(shí)候判斷隊(duì)列溢出別只盯著代碼里的listen()參數(shù)要用內(nèi)核統(tǒng)計(jì)信息反推真實(shí)值。6. 通信細(xì)節(jié)進(jìn)階端口、地址族與跨網(wǎng)絡(luò)邊界這一部分屬于進(jìn)階掃盲。很多報(bào)錯(cuò)看似代碼寫錯(cuò)了實(shí)際是對(duì)地址族、網(wǎng)段邊界、或者Socket選項(xiàng)的理解不到位。把這幾塊補(bǔ)上排查問題的速度會(huì)再上一個(gè)臺(tái)階。6.1 地址族、端口與字節(jié)序?yàn)槭裁纯偸切枰猦tonl和ntohlSocket編程里一個(gè)躲不掉的概念是字節(jié)序。不同CPU架構(gòu)存放多字節(jié)數(shù)據(jù)的順序不同有大端、小端之分。網(wǎng)絡(luò)傳輸規(guī)定用大端序網(wǎng)絡(luò)字節(jié)序而x86機(jī)器存儲(chǔ)數(shù)字通常是小端序所以你在構(gòu)造協(xié)議頭、填寫端口號(hào)時(shí)往往要把主機(jī)字節(jié)序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序。函數(shù)就是htons()和htonl()host to network short/long反向則是ntohs()和ntohl()。很多新手會(huì)問為什么bind()時(shí)端口要轉(zhuǎn)換字節(jié)序而0.0.0.0這種IP不需要因?yàn)閕net_pton()這類函數(shù)返回的網(wǎng)絡(luò)地址已經(jīng)是網(wǎng)絡(luò)字節(jié)序了不需要你再手動(dòng)倒騰。避免字節(jié)序錯(cuò)誤的一個(gè)好習(xí)慣是凡是你肉眼看到的端口、IP字面值都讓庫函數(shù)去解析不要自己拿整數(shù)去拼。地址族方面IPv4用AF_INETIPv6用AF_INET6如果代碼里寫死AF_INET在純IPv6環(huán)境下創(chuàng)建Socket就可能失敗。解決兼容性的一般做法是用getaddrinfo()解析地址它可以根據(jù)主機(jī)名和端口返回合適的地址族和Socket類型。在寫新代碼時(shí)建議優(yōu)先考慮IPv6就緒的策略——雙棧支持可以讓同一個(gè)Socket同時(shí)接受IPv4和IPv6連接避免未來踩暗坑。6.2 本地環(huán)回、局域網(wǎng)與公網(wǎng)的連通性差異網(wǎng)絡(luò)編程調(diào)試時(shí)環(huán)境不同現(xiàn)象差別巨大。127.0.0.1是本地環(huán)回地址數(shù)據(jù)根本不走物理網(wǎng)卡內(nèi)核直接就在網(wǎng)絡(luò)棧內(nèi)部把包轉(zhuǎn)發(fā)回去了所以延遲極低、不受防火墻網(wǎng)卡配置影響也最容易把問題掩蓋。192.168.x.x是私網(wǎng)地址走真實(shí)網(wǎng)卡和交換機(jī)會(huì)受網(wǎng)卡配置、防火墻、VLAN隔離等影響。公網(wǎng)地址則還要經(jīng)過路由器NAT、運(yùn)營商網(wǎng)絡(luò)、云安全組等復(fù)雜鏈路。一個(gè)典型的誤區(qū)本機(jī)測(cè)試沒問題用127.0.0.1連接部署到別的機(jī)器就連不上用局域網(wǎng)IP連接于是懷疑代碼有問題。其實(shí)大概率是防火墻攔截、監(jiān)聽地址寫成了127.0.0.1、或者目標(biāo)服務(wù)只監(jiān)聽在某個(gè)特定網(wǎng)卡上??吹健氨緳C(jī)能通、別人不能通”這類現(xiàn)象時(shí)先用ss -tlnp確認(rèn)監(jiān)聽地址到底是0.0.0.0還是127.0.0.1。如果是后者改成0.0.0.0就能解決。但這里有一層安全考量監(jiān)聽0.0.0.0意味著所有網(wǎng)卡上都響應(yīng)如果機(jī)器有公網(wǎng)IP等于向公網(wǎng)暴露服務(wù)應(yīng)該配合防火墻或安全組做限制而不是裸奔。6.3 Unix Domain Socket 的本質(zhì)與適用場(chǎng)景熱詞里有一條MySQL通過socket文件連接報(bào)錯(cuò)的例子把Unix Domain Socket拉進(jìn)了視野。Linux的Socket編程不只有TCP/UDP這類網(wǎng)絡(luò)Socket還有本地進(jìn)程間通信用的Unix Domain Socket即IPC。它不需要IP和端口而是使用文件系統(tǒng)路徑作為地址標(biāo)識(shí)。比如MySQL連接時(shí)localhost往往默認(rèn)走Unix Socket文件通常在/tmp/mysql.sock或/var/run/mysqld/mysqld.sock。如果這個(gè)文件不存在或路徑不對(duì)就會(huì)出現(xiàn)Cant connect to local MySQL server through socket的報(bào)錯(cuò)。Unxi Domain Socket的性能比TCP回環(huán)要高因?yàn)樗蛔呔W(wǎng)絡(luò)協(xié)議棧數(shù)據(jù)直接在內(nèi)核內(nèi)部傳遞省去了IP/TCP分組的開銷。所以數(shù)據(jù)庫、消息隊(duì)列、容器編排組件這些對(duì)性能敏感的場(chǎng)景本機(jī)通信都偏好用Unix Socket。它的一個(gè)特點(diǎn)是通信雙方必須在同一臺(tái)機(jī)器上這和“網(wǎng)絡(luò)Socket的連接可以跨機(jī)器”有本質(zhì)區(qū)別。從編程角度Unix Domain Socket依然可以用socket(AF_UNIX, SOCK_STREAM, 0)創(chuàng)建綁定地址時(shí)用sockaddr_un結(jié)構(gòu)體里面填一個(gè)文件路徑。文件權(quán)限會(huì)影響其他進(jìn)程能否連接這也是故障排查時(shí)的一個(gè)角度。如果遇到Permission denied先看Socket文件的權(quán)限和屬主再看進(jìn)程運(yùn)行的用戶身份是否一致。7. 學(xué)習(xí)路徑與工具鏈構(gòu)建從預(yù)備到實(shí)戰(zhàn)的可持續(xù)路線最后一個(gè)部分聊怎么接著往下走。Socket編程是個(gè)接口不大、但背后牽扯極廣的領(lǐng)域。從看懂這篇文章到能獨(dú)立寫出高并發(fā)的網(wǎng)絡(luò)服務(wù)中間還有很長的路把路線規(guī)劃清楚能少走不少彎路。第一個(gè)階段是“能用”。能寫最簡(jiǎn)單的TCP/UDP客戶端和服務(wù)端知道bind、listen、accept、connect幾個(gè)函數(shù)怎么配合會(huì)用ss和tcpdump看現(xiàn)象。這個(gè)階段不需要背函數(shù)重點(diǎn)是跑通實(shí)驗(yàn)、看到連接狀態(tài)的變化。第二個(gè)階段是“懂原理”。能夠解釋三次握手和四次揮手每個(gè)時(shí)機(jī)對(duì)應(yīng)的系統(tǒng)調(diào)用行為能夠說明窗口機(jī)制和緩沖區(qū)的意義能夠辨別阻塞、非阻塞和異步I/O的區(qū)別。到了這個(gè)階段再去看 《TCP/IP詳解》 這類書就不會(huì)覺得枯燥因?yàn)槊總€(gè)機(jī)制你都能在代碼里對(duì)應(yīng)到真實(shí)場(chǎng)景。第三個(gè)階段是“會(huì)排查”。拿到一個(gè)生產(chǎn)環(huán)境報(bào)錯(cuò)能根據(jù)錯(cuò)誤類型快速定位問題層面——是端口占用、隊(duì)列溢出、防火墻攔截還是連接被重置。這篇文章的第五部分就是給你的排查起點(diǎn)。在此基礎(chǔ)上多積累自己的故障案例庫記下每個(gè)詭異問題的排查路徑比看一百篇教程都管用。學(xué)習(xí)過程中強(qiáng)烈建議保持一個(gè)“壞事復(fù)現(xiàn)”的習(xí)慣。別只跑沒問題的代碼故意制造問題把backlog設(shè)成1然后并發(fā)連10個(gè)連接試試把發(fā)送緩沖區(qū)調(diào)小看看部分寫如何發(fā)生用tcpdump觀察一個(gè)處于TIME_WAIT狀態(tài)的連接。只有親眼見過壞的網(wǎng)絡(luò)行為遇到生產(chǎn)事故時(shí)才不會(huì)慌。工具鏈方面必裝的有tcpdump抓包、ss/netstat看連接、lsof看文件、nc快速模擬、strace跟蹤系統(tǒng)調(diào)用。其中strace特別值得多說一句——它可以打印出一個(gè)進(jìn)程發(fā)起的每一次系統(tǒng)調(diào)用當(dāng)你的程序表現(xiàn)異常、但代碼邏輯又看不出毛病時(shí)strace -p PID能直接把卡在哪個(gè)調(diào)用上照出來。這種“內(nèi)核視角”的調(diào)試能力是經(jīng)驗(yàn)豐富的網(wǎng)絡(luò)程序員和普通應(yīng)用開發(fā)者最大的差距之一。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
99热66| 深爱五月天 开心网| 丁香婷婷性久久| 婷婷五月综合网| 五月婷婷激情| 99久精品视频| 五月天激情子轮| 丁香九月综合激情| 美欧日韩国产成人在战| av婷婷丁香| 操人91| 五月天色婷婷图片| 超碰精品在线| 欧美日韩成人一区二区| 色婷婷无吗| 思思热99热| 激情五月少妇| 色丁香久综合在线久综合在线观看| www.com任你艹| 少妇人妻人伦A片| 五月天网站免费欧美| 免费视频舔| 亚洲 成人 电影av在线观看| 97日本操| 97在线99| 少妇熟女视频一区二区三区| 婷婷五月天xxx| 99人人操人人操人人精| 99啪视频在线观看| 婷婷丁香大香蕉| 激情丁香五月| 人人射人人高潮| 色色网站在线免费观看视频| 丁香五月激情啪啪| 久久ww| 超碰97色| 丁香六月av| 亚洲视频在线观看| 激情内射人妻1区2区3区| AV大香蕉| 五月婷婷激情久久| 91精品久久久久久综合五月天| 九九九九这里只有精品| 婷婷五月天在线综合| 婷婷五月天激情综合| 91大神操美女| 五月婷婷激情久久| 97碰在线视频| 婷婷6月综合网| 久久新| 大鸡巴伊人网| 欧美久人人| 91夫妻网站九色| 亚洲中文字幕在线观看| 亚洲情综合五月天| www久久久久久久久久久久久久久久久| 五月丁香激情综合| 年轻的妺妺伦理HD中文| 精品国产一区二区三区四区阿崩 | 99久久国产宗和精品1上映| 97碰在线视频| 婷婷色影院| 99在线热| 少妇高潮A片无套内谢麻豆传| 99操碰| 五月丁香综合啪啪| 夜夜撸夜夜骑| 中字幕视频在线永久在线观看免费| 天天日天天干天天操| 久久久久9| 免费播放AV| 五月日韩中文字幕| 6 9式性爱视频在线播放| 丁香五月激情久久麻豆| 青草青草久9视频在线视频| 丁香五月婷婷老师网站| 26uuu丁香婷婷五月| 日日操夜夜操中国无码| 色婷天天| 亚洲精品操一操、噜一噜、摸一摸、爽| 丁香五月激情宗合网| 91日本在线| 99re热在线视频| 色色色婷| 色婷婷色五月色丁香| 婷婷五月激情片| 99色在线观看| 99热精品在线观看| 99热综合| 69久久久| 丁香五月伊人| 丁香五月大香蕉在线99| 日熟女| 亚洲色夜| 国产综合激情五月久久| 色五月婷婷基地| 激情六月婷婷| 99爱在线视频| 99色在线视频观看| 无码一区二区日韩| 亚洲中文乱字字幕在线永久| 婷婷综合网站| 超碰国产AV| 日本超碰在线| 六月久久狠狠| 亚洲午夜一区二区| www.91.com黄| 婷婷开心激情五月激情网| 五日激情综合| 色天堂婷婷| 久久99免费视频| 日本一级特黄大片AAAAA级| 九九九精品视频免费观看| 99热国产这里只有| pom538精品视频| 五月婷婷激情久久| 91日综合欧美| 狠狠狠狠狠狠狠狠狠狠狠色宗合图片| 丁香五月六月综合激情| 97伦乱| 色丁香五月| 欧美婷婷五月无砖| 久久综合首页| 激情精品久久| 超黄亚洲瑟瑟网站| 九九热黄色| 大香蕉综合网| 99色干| 色婷婷色综合| 综合婷婷六月| 五月色丁香| 欧洲第一无人区观看| 五月情涩综合婷婷| 1995年关宝慧版蜘蛛女| 婷婷五月婷婷| 激情九月综合| 久久精品性爱| 丁香久久在线| 五月天色导航婷婷资源婷婷| 五月天社区婷婷丁香社区| 超碰人人色| 久久免费试看120秒| 激情婷婷五六月天| 天天激情站| 色偷偷人人| 丁香六月婷婷色播| www.激情五月天.com| 中海油常州环保涂料有限公司| 久久九九在线视频| 国产亚洲成AV人片在线观黄桃| 亚洲视频久久| 99色最新在线视频网站| 少妇性BBB搡BBB爽爽爽视頻| VA婷婷| 激情五月久久| 伊人久久大香线蕉综合网站| 五月婷婷性| 天天干,夜夜爽| 婷婷激情视频| 97干视频在线| 国产资源在线视频| 色婷婷丁香五月| 婷婷综合九色伊人| 五月天激情小说婷婷基地| 玖玖资源在线视频| 91一起操| 日本激情ⅩXX免费视频| 婷婷伊人网| 综合一区二区三区| 99精品久久久久| yw.av| 婷婷色情小说| 丁香操逼| 丁香五月激情在线| 91九色无码内射| 欧美性色五月天| 天天爽夜夜操| 涩涩五| www.久久| 色五月视频无码播放| AVDV久久| 丁香六月av| 丁香婷婷五月六月久久| 激情综合五月天| 欧美性丁香色色五月天干干| AV片一区在线观看| 色欲香综合网| 开心婷婷五月激情网小说| 五月婷婷啪啪综合网| 五月激情综合婷婷| 亚洲无码色色| 超级碰碰91| 国産精品| 婷婷丁香色五月天久久88| 亚洲天天| 色情激情五月| 秋霞少妇毛片| www.五月婷婷.com| 99re99热| 丁香8月手机综合| 五月婷六月丁| 婷婷五月天AV在线| 五月天伊人网| 天天天添天天操| 99视频这里有精品| 亚洲色人妻| 五月天婷婷丁香导航| 在线99精品| 五月婷婷成人| 久久这里只有精品07| 粉嫩AV久久一区二区三区| 婷婷六月开心网| 爱99干99| 婷婷五月天丁香社区| 中文字幕av久久爽一区| 亚洲字幕AV一区二区三区四区| 97涩涩丁香五月天| 激情五月婷婷啪啪| 人人摸人人| 秋霞午夜理论| 人妻中文字幕网| 亚洲色图五月丁香| 五月天色婷婷视频| 激情综合色| www色哟哟| 开心婷婷五月| 99这里只有精品视频在线| 草草夜夜操| 99色色色色| 欧美日本国产欧美日本韩国99| 一本色道久久综合狠狠躁小说| 婷婷色系婷色| 久婷久婷| 9|人妻人人操| 色播五月天激情| 99热这里只有国产精品| 五月天久久www| 综合色色色| va婷婷在线免费观看| 久久婷婷资源| 少妇2做爰HD韩国电影| 影音先锋91男人资源在线播放| 五月婷婷五月天| 丁香六月啪啪| 毛v一区二区视频| 很很干天天干| 99a级片| 99热精品在线播放观看| 天天综合网~91综合网| 青青久久五月| 色5月婷婷| 色五月中文网| 丁香婷婷成人在线播放| 热九九在线| 香蕉久久五月| 精品国产乱码久久久久夜深人妻| 精品久久99码| 色欲午夜无码久久久久久张津瑜 | 五月天久久综合婷婷丁香| 97丁香五月| 97干干干丁香| 超碰狠狠操| 色99视频| 激情五月丁香六月| 五月天小说激情| 玖玖五月| 五月丁香婷色| 七七色综合| 亚洲成人免费在线| 久婷| 九九99九九99九九99视频网| 久久机热/这里只有精品| 再次出发二| 操操天堂| 久久综合影院| 成年视频免费观看| 91亚洲视频| 天天操夜夜操| 无码色| www,com,五月色色| 五月婷视频| 婷婷五月天六月| 丁香六月 婷婷六月| 一级精品999WWW| 久久9热好| 激情99| 久久伦乱| 无码区婷婷五月花开| 久久婷婷五月综合色和| 伊人AV五月婷| 手机免费福利视频| 九九九九这里只有精品| 色综合天天天天做夜夜| 婷婷99狠狠躁| 99热6色| 色五月亚洲开心网| 噜噜久| 秋霞影音91人妻久久| 深夜婷婷五月丁香| 激情婷婷五月色| 五月丁香婷婷综合激情基地| 天天操天天操| 精品福利911| 久热这里只有精品在线观看 | 激情狠狠丁香月| 九九精品片一| 丁香五月婷婷六月婷| 轮奸综合网| 91性高潮久久久久久久久| 婷婷内射视频在线| 欧美一级色| 国产成人av在线播放| 亚洲碰碰碰| 日韩av网站在线观看| 99热99思午夜精品| 五月 成人 婷婷| 久久免费丁香| 婷婷久久大香蕉| 2015超碰| 97人人射| 色综合五月在线| 亚洲综合五月天综合| 婷婷丁香五月六月激情| 亭亭五月色男人| 五月天婷婷激情在线色图| 激情九九这里只有精品| www.婷婷五月| 婷婷色五月天在线观看| 国产精品久久久久久久久久免费| 狠狠色狠狠色综合日日91| 涩婷婷视频快播人妻| 天堂在线婷婷| 九九九热精品| 午夜婷婷丁香| 亭亭五月激情亚洲在线| 人人播| 97精品自拍视频| 91偷拍视频| 激情婷婷六月天| 777影视理论片大全在线观看| 2025超碰| 久久婷婷五月综合啪| 久草大| 婷婷五月成年人| 六月天六月婷| 婷婷玖玖五月天| 无码操B| 日日夜夜天天| 日韩无码91| 综合久久综合久久| 六月婷色六月| 玖玖在线| 香蕉人妻AV久久久久天天| 丁香婷婷影院| 天天五月丁香五月| 婷婷射丁香| 婷婷久久网| 99热久久这里只有精品| 五月丁香久人妻中文| 丁香六月 婷婷六月| 日日爽日日爽| 成人看片网站| 哇嘎成人久久| 欧美综合激情五月| 五月天久久久| 99热欲| 超碰久热| 久久久这里有精品| 无码人妻丰满熟妇奶水区码| 婷婷免费无马| 色欲天天综合| 天天做 天天爱| 色日本丁香婷婷| 日日操天天操| 六月丁香久久| 国产激情在线| 99人妻碰碰碰久久久久| a级毛片一区二区免费视频| 俺去也五月| 成人免费在线电影| 在线观看av网站| 六月丁香婷婷五月天| 亚洲激情免费视频| 狠狠色噜噜狠| tingting五月天亚洲| 亚洲色另类| 久久ri精品| 桃色五月婷婷| 欧美在线97| 99热在线网站| 午夜婷婷六月天| 九九九九这里只有精品| 激情黄色小说色五月| 丁香五月综合亚洲| 丰满少妇猛烈A片免费看观看| 五月天激情图片| 三级黄色大片视频| 国产熟女一区二区三区五月婷| 99惹| 亚洲综合激情五月久久| 九九热这里只有精品5| 五月天成人小说网| 丁香五月婷婷激情中文| 999热在线视频| 激情五月婷婷| 婷婷五月综合激情| 99这里有精品视频| 偷偷操99| 久草性爱| www.精品99| 色噜噜狠噜噜视频| A在线观看| 久久只有18视频| 五月天激情美女久久| 精品国产va久久久久久久| 99啪啪| 中文字幕综合| 久热伊人| 深爱婷婷基地| 色99视频| 欧美综合婷婷网| 丁香六月啪| 久久久婷婷| 九九热只有精品| 中文字幕在线免费观看视频| 五月丁香啪啪啪啪| 在线中文av| 色色操| 亚洲色五月| 五月色色色| 婷婷丁香69精华| 另类天堂| 桃色伊人在线| 91主播在线| 九九热99热| 丁香色情五月综合激情| 在线天堂9| 久久婷网| 五月激情六月综合| 日日操,夜夜爽| 97人碰人操| 丁香五月婷婷骚视屏| 久久五月天 91| 五月丁香婷婷综合视频| 99色热视频| 996er热| 精品视频99看在线视频| 69超碰在线| 天天操夜夜爽歪歪| 久久久久8888| 五月天社区| 亚洲色vA| 色丁香五月| 亚洲精品亚洲人成人网| 狠狠干五码| www.久操| 超碰亚洲天堂| 久久综合天天综合| 玖玖99精品视频| 丁香六月综合激情| 第六色在线| 激情丁香五月| 亚洲a色| 26uuu四色| 色综合久久88色综合天天| 色爱综合网| 九九综合色| 五月激情丁香啪啪| 日本一毛片| 欧洲激情网站| 中文字幕亚洲-区久久99婷婷| Av九九| 成人精品一区二区三区四区五区 | 色婷婷丁香五月天| 葵花AV在线| 日本一道久久| 日韩a热| 免费在线a| 五月丁香黄色视频| 婷婷天天综合| 91精品综合久久久久久五月丁香| 五月精品99综合| 夜丁香综合| WWW.夜夜操.com| 色都都狠狠色都都色综合色| 爱婷婷都市激情| 色综合天天网| 另类伊人婷婷| 激情四射亚洲| 婷婷视频网| 香蕉AV777XXX色综合一区| 吊色AV男人的天堂| 色九九九综合| 99热色精品| 能看的av网站| 五月婷导航| 午夜婷婷丁香| 六月激情丁香一道本7777| 99精品国产乱码久久久人妻| 99日本黄站| www.minyis.com【JT】币址百万U预算可预付QQ2101460746 | 五月天婷婷青青| 大香蕉七区| 色色五月天激情| 玖玖99免费视频| 五月色丁香激情| 91色色色| 五月激情综合网| 五月天婷婷涩涩| 亚洲精品又粗又大又爽A片| 色综合综合色| 综合五月天| 丁香六月婷婷综合激情欧美| 五月婷婷激情综合| 丁香综合网| 初夜av| 激情色色| 色婷婷综合综合网| 色婷另类| 亚洲综合成人网站| 色吧网综合| 美国少妇性做爰| 另类小说色婷婷| 婷婷五月天丁香社区| 99热最新| 丁香五月在线观看完整版| 99热 在线观看| 99思思在线视频| 日本3级片偷拍网站| 噜噜狠狠色综合久| 久艹大香蕉| 五月天偷拍| xxxx久| 色婷九九九| 日韩av网址大全| 人妻丰满精品一区二区A片| 色色99色色| 六月丁香网| 丁香五月婷婷超碰在线| 色色色色色色网站| 婷婷色婷婷亚洲成人| 色婷婷丁香五月天| 思恩热国产视频右线观看| 伊人婷婷大香蕉| 久久久ww| 91蜜桃婷婷狠狠久久综合9色| 六月婷婷综合激情| 激情綜合W W W,激情五月天| 99热这里是精品| AV在线观看网站| 亚洲AV综合网| 日韩啪啪视频| 99re热精品在线视频| 开心激情站| 激情婷婷五月亚洲| 国产精品久久欧美久久一区| 五月停停丁香| 亚洲欧美国产A片免费观看| 99热精品无码| AV在线免费网站| 武则天精品久久| 狠狠大香婷婷爱| 亚洲激情网| 加勒比色色| 97综合视频在线| 欧美婷婷五月丁香| 色哟哟性爱av| 五月丁香六月婷婷啪啪| 五月婷婷久久综合| 香蕉久久五月| www..999热久| 丁香五月婷婷亚洲色图| 丁香六月婷婷缴情欧美| 99国产在线| 婷婷 伊人 久久| 色婷婷五月在线| xx综合网| AV中文字幕夜夜操b天天摸bb| 五月婷在线| 狠狠操综合| 激情五月综合网| 婷婷丁香五月天在线| 久久色吧| VA色婷婷| 丁香涩涩五月天| 99啪在线视频| 激情五月婷婷五月| 一区二区三区四区无码| 夜色综合网| 综合久| 丁香欧美| 99大香蕉| 色啦啦视频| 激情综合色婷婷啪啪六月天| 丁香六月婷婷久久综合八月| 九九热99精品| 久久五月天婷婷| 777精品成人a v久久| 中文字幕网站在线观看| 六月激情网| 深爱五月日韩| 天天干,天天舔| 婷婷香蕉精品| 99re在线观看| 日日操天天| 国产免费av在线| 无码激情AAAAA片-区区| 激情五月婷婷在线观看| 亚洲五月天综合| 五月婷婷九九久久| 欧美婷婷| 日韩在线9| 五月 丁香 欧美| www.精品久9| 国产精品a无线| 99热这里只有精品5| 久久婷.com| 99re资源在线视频导航| 九九热在线99| 另类激情综合| 六月婷婷狠狠做| 久综合| 婷婷五月天亚洲综合网| 思思热精品在线| 九九免费精品| 婷婷五月天激情综合婷婷五月天激情综合| www.久久久久久久久久久| 国产日韩欧美| 97九色| 五月天激情啪啪| 九九sese| 久久五月激情| 久久婷婷大香蕉| 欧美电影在线观看| 99操逼| 久久a热| 天天综合天天玩夜夜玩天天玩夜夜玩| 日本不卡中文字幕| 玖玖婷婷色| 91狠狠色丁香婷婷综合久久狠丁香综合久久精品 | 99久久久久| 九九热精品| 六月丁香五月亭亭| 一夜福利不卡| 久久激情五月婷婷| 操操精品| 91成人看| 熟女色色一区二区| 嫩草AV久久伊人妇女超级A| 五月丁香免费视频| 直接看的av| 狠色狠色综合久久| 五月婷婷亚洲综合网| 国产精品大香蕉| 丁香五月激情月| 欧美熟女视频 色婷婷| 欧美成人精品三区综合A片| 超碰在线人人| 性色视频| 亚洲AV色婷婷人禽五月天| 日韩欧美四五区| 色色色综合视频| 久久色情| 中文字幕不卡+婷婷五月| 色色五月婷婷久久| 婷婷五月丁香超碰| 九色无码| 五月丁香花视频| 欧美婷婷丁香五月| 99久热精品在线| 欧美碰碰碰| 大香蕉伊人丁香五月| 成人无码精品1区2区3区免费看| 99热这里只有精品4| 婷婷综合| 丁香六月婷婷色XXXXX| 狠狠色噜噜狠狠狠狠综合| 欧美精品啪啪| 欧美 日韩 成人 在线| 五月天伊人综合| 99色色| 色五婷婷在线视频| 综合性爱网| 热99在线精品| 五月丁香中文字幕| 丁五月激情视频免费| 天天爽夜夜爽夜夜爽精品视频| 色五月在线观看| 人人妻久久妻| 婷婷狠狠色| 天天干天天干天天| 4438激情网| 五月丁香久久网| 日韩啪啪视频| 五月婷婷在线免费观看| 五月天激情小说| 午夜少妇在线观看视频| 天天插天天干| 亚洲色99综合天堂| 91干在线视频| www.色色五月天.com| 超碰成人在线观看| 激情五月婷婷| 激情综合激情五月| 五月天基地| 停婷丁五月在线| 91丨九色丨熟女|老版| 黄色成人网站在线播放| 99久热| 黑人糟蹋人妻HD中文字幕| 日韩专区五月天婷婷丁香| 婷婷五月综合中文字幕| 丁香五月婷婷婷桃花影院| 亚卅毛片| 五月丁香日本在线视频观看| 亭亭五月激情亚洲在线| 色播五月| 国产成人av在线播放| 免费黄色片子| 九色在线五月婷婷网址| 日韩AV在线免费观看| 国产亚洲在线| 五月丁香在线婷婷蜜桃| 狠狠五月天| 五月婷婷丁香婷婷| 综合久久婷婷| 婷婷在线五月综合| enecarbon-materials.com污K127封锁请涟系@wip1688 | 婷婷色丁香五月| www久久99| 五月激情婷婷偷拍| 丁香六月婷婷久久高清| 天天摸天天舔在线视频| 天天色天天色天天色天天色天天色| 色色色图| 五月天婷婷色| 久久久五月天婷婷成人网| 欧美六月| 天天干天天色天天干| 婷婷激情图片| 精品亚洲国产成AV人片传媒| www.99热精品99.com| 久久99久久99精品免视看婷婷| 婷婷六月插屄激情| 99精品视频在线观看| 色婷五月天| 月丁香久久久| 99精品这里只有免费视频| 亚洲色婷婷视频| 婷婷成人综合| 婷婷玉月丁香五月在线视频| 五月婷婷天| 天天干天天拍| 97ai婷婷| 天天色爽| 久婷婷色| 中文字幕网伦射乱中文| 亚洲av成人在线| 丁香婷婷五月六月天| 欧美97色| 五月天操逼激情| 91九色中文字幕女在线观看| 婷婷五月天手机版视频| 91久久综合亚洲鲁鲁五月天| 久久涩视频| WWW久久久| se99视频| 国产毛片精品一区二区色欲黄A片| 97超碰欧美中文字幕| 色青青五月| 激情五月婷黄版| 国产一级片色色| 成人在线不卡| 色婷婷小说| 亚洲九九夜夜| 色婷婷久久综| 拳交大逼| 精品成人无码A片观看香草视频| 五月婷婷丁香大陆免费| 五月丁香无码| 亚洲国产精品VA在线看黑人| 99热e| 五月丁香亚洲婷婷| 国产特级毛片AAAAAAA高清| 香蕉婷婷色五月| 五月天婷婷婷| 精品无码久久久久久久久 | 99综合视频| 成人免费黄色短视频| 久久曰曰| 六月婷婷色色色| 67194线路二在线观看| 人妻久久久久久久久妻久久久久久久久| 人人摸人人澡人人| 欧美性爱专区| 丁香欧美| 国产精自产拍久久久久久蜜| 亚洲激情亚洲激情 | 国内9l视频自拍老熟女九色| 天天日天天摸天天| 丁香五月天之婷婷影院| 狠狠色噜噜狠狠狠狠综合| 欧美日韩一区二区三区四区| 视频一区二区在线| 五月社区婷婷激情| 九九热免费视频| 激情丁香五月天综合| 午夜天堂啪啪| 任你搞网站| 五月丁香龟婷婷| 美国少妇性做爰| 婷婷久久五月| 99re在线观看| 第四色色六月色综合| 天天婷婷综合亚洲亚洲| 亚洲综合久| 中文字幕不卡+婷婷五月| 婷婷欧美激情| 夜夜爱网站| 久久九九九九| www,天天干| 六月色婷婷综合影视| 亚洲AV成人无码久久精品老人法拉利| 久草婷婷网| 夜夜爽日日躁| 婷婷在线播放| 襙逼网| 免费看欧美成人A片无码| 婷婷五月天色综合翘| 天天干,天天日| 婷婷五月免费观看| 无码少妇高潮喷水A片免费| 天天爱天天做综合| 亚洲精品无AMM毛片| 精品99久久久久成人网站免费| 五月丁香六月婷综合成人综合| 激情五月婷黄版| 五月丁香成人网| www.99热国产| 4438亚洲欧美| 五月色俺婷婷| 99热免费18| 性色五月天| 日韩 mm 不卡| 久久狠狠干| 色99在线视频| 99热最新| 国产又黄又爽又激情不遮挡视频在线观看| 色色五月婷婷网| 色综合色综合网| 69综合在线| 天天搞天天色综合| 女性自慰系列第五页| 丁香色五月 97干| 色色色在线免费视频| 亚洲在线免费成人| 五月天 另类图片| 97碰人人操| 日本三级韩三级99久久| 成人色站,在线视频,看片-SS1AV| 国产毛片精品一区二区色欲黄A片| 久久久区区一久久久久久| 琪琪色网址| www.99情趣网| 亚洲啪啪视频| 丁香激情五月| 热成人网| 午夜成人综合| 26uuu国产| av在线色五月丁香婷区久| 99热99天堂| 久久婷婷五月天懂色| 五月婷婷六月丁香激情综合网| 丁香情色五月| 激情婷婷六月天| 五月天亚洲图片婷婷| 五月色综合| 色婷婷综合视频| 伊人网大香| 亚洲乱码日产精品BD| 五月天综合图片| 九九综合| 天天激情站| 日日撸夜夜操| 一起草无码视频| 99热网精品| 夜色综合网| ri电影在线| 综合激情四射一theav| 久久多色| 午夜电影网VA内射| 丁香五月最新地址| 男同91 | 欧美综合婷婷网| 综合网啪| 激情综合五月| 99免费视频| 精品九九在线观看| 亚洲无码成人网| 欧洲色色| 日本高清久| 天色综合网站| 婷婷五月香蕉| 热热色色五月天婷婷| 婷婷伊人网| 色噜噜在线| 九九色婷婷| 五月婷婷黄网站大全| 99热免费精品| 日本五月婷婷| 婷婷色色综合激情| av无码电影| 日日日日日| 情色婷婷五月天| 五月色欧美| 丁香六月激情综合| 92久久久| 亚洲亚洲人成综合网络| 狼友超碰| 色婷婷基地| 激情六月丁香综合| 14色综合婷婷| 丁香五月-激情综合| 激情小说婷婷| 综合在线色婷婷| 五月丁香 啪啪啪| 97人妻碰碰碰久| 五月丁香久久色| 亚洲国产精品VA在线看黑人| 天天爽人人综合免费7799| 另类激情五月天| 青草久久五月婷伊人| 91色噜噜狠狠狠狠色综合| 狠狠狠狠狠狠草| 色婷婷丁香五月天| 九色视频91| 色99在线观看| 婷婷激情六月天视频| 大香蕉久久青青| www夜夜操| 欧美超级视频97| 激情内射p| 五月色丁香国产在线视频| 欧美色图45678| 日本天堂免费99| 亚洲色久| www.五月婷婷| 日韩AAAAA| av网站中文| 日本一级一级一级一级| 大香蕉婷婷丁香| 天天干人人奸97| 欧美色综合天天久久综合精品 | 国产AV成人精品| 蜜臀AV在线观看| 丁香色色网| av大香蕉| 成人婷99最新| 玖玖五月丁香| 五月婷视频| 欧州色色| 天天色色天天| 1024成人在线观看| 99热日本精品| 亚洲人成播放网站| 九九热9| 青青草视频免费观看| 可以免费观看的av| 亚洲天堂色色| 久久九九国产精品怡红院| 日韩啪啪视频| 九九碰九九爱97| enecarbon-materials.comWu染请涟系Bao护@wip1688 | 天天开心天天色| 久久丁香五月婷婷| 91九色|疯狂|高潮|对白|| 色婷婷成人网| 9热精品| 欧美综合五月丁香六月婷| 91无码高清| 六月婷婷视频| 亚洲无aV在线中文字幕| 亚洲av无码精品色午夜| 2015超碰| 91 原创 在线 九色| 麻豆雪千夏| 激情综合99| 日韩无码专区| 六月丁香啪啪| 99热20| 婷婷六月丁香久| 甈你aaaaa| 先锋av性爱成人电影| 五月婷婷丁香色播网| 99re在线这里只有精品视频首页| 久久久99精品| 这里只有精品网站| 亚洲视频色婷婷| 欧美视频五区| 另类在线| 婷婷五月天激情小说| 欧洲第一无人区观看| 狠狠爱成人综合网| www.韩日视频| 99热线观看9| 久久人人九九| 狠狠干天天内射| 天天噜天天爱| 美女妹子后射视频网站在线观看| 天天日日夜夜爽。| 久久精品夜色噜噜亚洲a∨| 五月丁香六月激情综合| 婷婷五月婷婷| www.久久爱| 人人插操| 五月天激情图片网| 成人网站免费在线播放| www.av视频xx999.com| 九九99视频精品| 婷婷丁香五月天中文字幕| 五月丁香中文字幕| 五月丁香婷婷基地| 超碰在线成人| 色综合网页| 色欲婷婷五月天丁香| 影音先锋色色色资源色资源色| site:jszngf.com| 日日舔夜夜操| 久久丁香五月| 日本精品久久久久中文字幕| 亚洲综合色成丁香五月色| 大香蕉欧美在线| 9久久久久久久久久久| 在线视频色五月| 99这里只有精品99| 在线观看欧美| 国产精品久久久久久久久久久久| 91九色超碰| 99热这里都是精品| 五月开心六月婷婷在线播放网站| 五月天婷婷无码视频| 99视频在线播放大全| 99热这里只有精品8| 99在线视频观看| 91丨九色丨熟女| 开心婷婷五| 美女五月天| 99热精品免费| 婷婷黄色网| 精品乱码视频| 一级二级香港秋霞欧美欧美秋霞| 五月天三级久久| 777色婷婷爱五月| 久播影院免费观看电视剧大全最新网| www.色婷婷.com| 中文字幕无码人妻少妇免费视频| 色99欧洲色19| 大功率国产在线| 婷婷激情五月天亚洲综合| 人妻AV在线观看| 激情5月婷婷| 熟女网站久久| 79色色免费| 亚洲操精品| 色婷婷很很十八禁| 午夜激情综合| 欧美狠狠地| 91九色精品熟女内射| 丁香六月婷婷激情| 国内一级精品| 69激情小说| 久久99久久99精品免视看婷婷| 天天日日| www久久五月com| 久久伊人五月天| 欧美性生交XXXXX无码小说 | 激情综合五月婷婷六月丁香| 婷婷免费视频| 秋霞丝袜啪啪啪| 狠狠va| 亚洲欧美综合7777色婷婷| 丁香五月婷婷色综合| 五月丁香六月婷婷亚洲天堂网站| 激情五月,婷婷五月,丁香五月| 99视频在线精品| 2020日日干| 天天日天天做天天操| 婷婷色婷婷| 人人性久久| 激情深爱五月| 激情网五月天| 久久精品婷婷| 欧美成人性爱网| 曰韩少妇内射免费播放| 久久久8| 亚洲视色| 丁香六月婷婷基地| 久久欧洲久久| 五月激情啪啪啪| 成人 九九九九| 色五月六月婷婷| 91操操| 久操大| 亚洲精品色| 波多婷婷久久| 亚洲九九九九| 五月婷婷在线免费观看| 久久色五月| 亚洲男女激情| 日本44久久在线| 99热色精品| 激情深爱综合网| 久久99国产综合精品免费| 国产成人AV在线播放| 五月丁香在线婷婷美女| 熟妇人妻中文字幕无码老熟妇| 色婷丁香| 97热精品| 色播激情婷婷| 六月丁香婷婷尤物| 熟妇人妻中文字幕无码老熟妇| 久久婷色| 色噜噜综合网| 黄涩毛片| 亚韩在线视频| 97人人干| 综合玖玖偷拍| 婷婷丁香午夜综合影视| 99热在线精品观看| 色播五月天激情| 国精产品一区一区三区免费视频| 国产特黄色精品一区二区三区精品无广告| 成人做爰A片免费看视频| 日韩操女| 久久亚洲婷婷综合色五月| 婷婷色五月天在线| 国产亚洲在线观看| 亚洲视频在线网| 这里只有视频精品| 色五月婷婷小说亚洲中文字幕组 | 男人的天堂在线婷婷| 婷婷综合激情| 亚洲激情婷婷| 丁香五月成人| 婷婷情色五月天| 5月婷婷激情6月| 99精品在这里| 99九九中文字幕视频| 天天爽,天天操。| 久操人妻| 国产黄色大片| xx综合网| 大香蕉伊人久久| 91VIP在线观看| 狠狠色情婷婷| 婷婷五月天堂| 色原狠狠综合| 色五月婷激情| 99热地址| 五月丁香九九| 九九亚洲视频| 99成人小视频| 五月丁香成人网| 在线观看日韩12345区| 天天色天天搡| 深爱五月天| 五月停停大香蕉| 亚洲综合色网站| 91精品婷婷国产综合久久| 香蕉色色网| 五月丁香黄色| 色婷视频| 欧美激情综合| 婷婷午夜综合| 99热免费18| 伊人色综在线| 丰满少妇乱A片无码| 丁香五月天在线观看视频| 成人欧美日韩| 色色丁香五月天社区| dingxiangtingtingliuyue| 屁股翘好撅高迎合跪趴| 色色综合色视频| 久久色婷婷| 91在线操| 2025天天日爽| 亚洲第一影院高清无码网站| 激情五月五月五月婷婷| 少妇大叫太大太粗太爽了A片| 99热国品免费| 99视频久久| 久久网日本| 干一干xxxx| 97人人爱人人操| 少妇搡BBBB搡BBB搡毛茸茸 | 狠狠色噜噜狠狠狠狠狠色综合久久| 九九久久综合网站| 五月天综合久久| 婷婷和五月天| 欧美99热| 欧美日韩91| 日韩啊啊啊| 综合亚洲色色| 丁香六月五月天| 九九成人精品免费视频| 激情久久久久久久久久久| 欧美色97| 黄色五月婷婷| 亚韩在线视频| 日本久久99| 日日天天天| 久热精品视频| 久久综合五月天| 91凹凸在线| 五月天婷婷操逼视频| 91婷婷色 | 99这里只有精品|v| 久99久视频| 激情开心五月天| 777色婷婷爱五月| 久草热8精品视频在线观看| 久久久婷丁香五月| 亚洲av| 人人爱人人摸人人澡| 中文字幕婷婷在线| 五月天婷婷7米| 亚洲AV综合在线观看| 狠狠狠狠狠干| www。88热在线视频免费观看| 粉嫩AV久久一区二区三区| 久噜久噜| Www.se.久久| 99热天堂| 色九月婷婷综合| 色色色色色色色色网站| 激情五月天婷婷免费观看| 五月婷婷综合网| 性爱电影科技贸易有限公司| 婷婷色情 | 夜夜爽天天干| 色欲av伊人久久大香线蕉影院| 99热网站| 五月丁香六月情婷婷久久| 欧美婷婷九月| 色六月婷婷| 欧美色骚婷婷五月天| 色综合网页| 色播五月综合网| 99rewww| 十二区无码| 色吧婷婷| 一根材五月婷成人| 日韩精品一曲二曲三曲四曲五曲| 这里只有精品视频| 狠狠艹狠狠艹| 婷婷五月天国产性感美女演员久久久久| 午夜丁香婷婷| 婷婷开心深爱五月天| 97一区二区| 激情99| 天天日狠狠| 久久人操-久草婷婷-成人AV| 九九人人操| 五月婷婷精品无在线| 99日本黄站| 成人超碰网|