<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > Linux協(xié)議棧accept和syn隊列問(wèn)題

Linux協(xié)議棧accept和syn隊列問(wèn)題

作者: 時(shí)間:2016-10-08 來(lái)源:網(wǎng)絡(luò ) 收藏

環(huán)境:

本文引用地址:http://dyxdggzs.com/article/201610/305659.htm

Client 通過(guò)tcp 連接server,server端只是listen,但是不調用accept。通過(guò)netstat –ant查看兩端的連接情況。

server端listen,不調用accept。

client一直去connect server。

問(wèn)題:

運行一段時(shí)間后,為什么server端的ESTABLISHED連接的個(gè)數基本是固定的129個(gè),但是client端的ESTABLISHED連接的個(gè)數卻在不斷增加?

分析

Linux內核協(xié)議棧為一個(gè)tcp連接管理使用兩個(gè)隊列,一個(gè)是半鏈接隊列(用來(lái)保存處于SYN_SENT和SYN_RECV狀態(tài)的請求),一個(gè)是accpetd隊列(用來(lái)保存處于established狀態(tài),但是應用層沒(méi)有調用accept取走的請求)。

第一個(gè)隊列的長(cháng)度是/proc/sys/net/ipv4/tcp_max_syn_backlog,默認是1024。如果開(kāi)啟了syncookies,那么基本上沒(méi)有限制。

第二個(gè)隊列的長(cháng)度是/proc/sys/net/core/somaxconn,默認是128,表示最多有129個(gè)established鏈接等待accept。(為什么是129?詳見(jiàn)下面的附錄1)。

現在假設acceptd隊列已經(jīng)達到129的情況:

client發(fā)送syn到server。client(SYN_SENT),server(SYN_RECV)

server端處理流程:tcp_v4_do_rcv--->tcp_rcv_state_process--->tcp_v4_conn_request

if(sk_acceptq_is_full(sk) inet_csk_reqsk_queue_yong(sk)>1)

goto drop;

inet_csk_reqsk_queue_yong(sk)的含義是請求隊列中有多少個(gè)握手過(guò)程中沒(méi)有重傳過(guò)的段。

在第一次的時(shí)候,之前的握手過(guò)程都沒(méi)有重傳過(guò),所以這個(gè)syn包server端會(huì )直接drop掉,之后client會(huì )重傳syn,當inet_csk_reqsk_queue_yong(sk) 1,那么這個(gè)syn被server端接受。server會(huì )回復synack給client。這樣一來(lái)兩邊的狀態(tài)就變?yōu)閏lient(ESTABLISHED), server(SYN_SENT)

Client收到synack后回復ack給server。

server端處理流程: tcp_check_req--->syn_recv_sock-->tcp_v4_syn_recv_sock

if(sk_acceptq_is_full(sk)

goto exit_overflow;

如果server端設置了sysctl_tcp_abort_on_overflow,那么server會(huì )發(fā)送rst給client,并刪除掉這個(gè)鏈接;否則server端只是記錄一下LINUX_MIB_LISTENOVERFLOWS(詳見(jiàn)附錄2),然后返回。默認情況下是不會(huì )設置的,server端只是標記連接請求塊的acked標志,之后連接建立定時(shí)器,會(huì )遍歷半連接表,重新發(fā)送synack,重復上面的過(guò)程(具體的函數是inet_csk_reqsk_queue_prune),如果重傳次數超過(guò)synack重傳的閥值(/proc/sys/net/ipv4/tcp_synack_retries),會(huì )把該連接從半連接鏈表中刪除。

一次異常問(wèn)題分析

Nginx通過(guò)FASTCGI協(xié)議連接cgi程序,出現cgi程序read讀取socket內容的時(shí)候永遠block。通過(guò)netstat查看,cgi程序所在的服務(wù)器上顯示連接存在,但是nginx所在的服務(wù)器上顯示不存在該連接。

下面是原始數據圖:

我們從上面的數據流來(lái)分析一下:

出現問(wèn)題的時(shí)候,cgi程序(tcp server端)處理非常慢,導致大量的連接請求放到accept隊列,把accept隊列阻塞。

148021 nginx(tcp client端) 連接cgi程序,發(fā)送syn

此時(shí)server端accpet隊列已滿(mǎn),并且inet_csk_reqsk_queue_yong(sk) > 1,server端直接丟棄該數據包

148840 client端等待3秒后,重傳SYN

此時(shí)server端狀態(tài)與之前送變化,仍然丟棄該數據包

150163 client端又等待6秒后,重傳SYN

此時(shí)server端accept隊列仍然是滿(mǎn)的,但是存在了重傳握手的連接請求,server端接受連接請求,并發(fā)送synack給client端(150164)

150166 client端收到synack,標記本地連接為ESTABLISHED狀態(tài),給server端應答ack,connect系統調用完成。

Server收到ack后,嘗試將連接放到accept隊列,但是因為accept隊列已滿(mǎn),所以只是標記連接為acked,并不會(huì )將連接移動(dòng)到accept隊列中,也不會(huì )為連接分配sendbuf和recvbuf等資源。

150167 client端的應用程序,檢測到connect系統調用完成,開(kāi)始向該連接發(fā)送數據。

Server端收到數據包,由于acept隊列仍然是滿(mǎn)的,所以server端處理也只是標記acked,然后返回。

150225 client端由于沒(méi)有收到剛才發(fā)送數據的ack,所以會(huì )重傳剛才的數據包

150296 同上

150496 同上

150920 同上

151112 server端連接建立定時(shí)器生效,遍歷半連接鏈表,發(fā)現剛才acked的連接,重新發(fā)送synack給client端。

151113 client端收到synack后,根據ack值,使用SACK算法,只重傳最后一個(gè)ack內容。

Server端收到數據包,由于accept隊列仍然是滿(mǎn)的,所以server端處理也只是標記acked,然后返回。

151896 client端等待3秒后,沒(méi)有收到對應的ack,認為之前的數據包也丟失,所以重傳之前的內容數據包。

152579 server端連接建立定時(shí)器生效,遍歷半連接鏈表,發(fā)現剛才acked的連接,synack重傳次數在閥值以?xún)?,重新發(fā)送synack給client端。

152581 cient端收到synack后,根據ack值,使用SACK算法,只重傳最后一個(gè)ack內容。

Server端收到數據包,由于accept隊列仍然是滿(mǎn)的,所以server端處理也只是標記acked,然后返回

153455 client端等待3秒后,沒(méi)有收到對應的ack,認為之前的數據包也丟失,所以重傳之前的內容數據包。

155399 server端連接建立定時(shí)器生效,遍歷半連接鏈表,發(fā)現剛才acked的連接,synack重傳次數在閥值以?xún)?,重新發(fā)送synack給client端。

155400 cient端收到synack后,根據ack值,使用SACK算法,只重傳最后一個(gè)ack內容。

Server端收到數據包,由于accept隊列仍然是滿(mǎn)的,所以server端處理也只是標記acked,然后返回。

156468 client端等待幾秒后,沒(méi)有收到對應的ack,認為之前的數據包也丟失,所以重傳之前的內容數據包。

161309 server端連接建立定時(shí)器生效,遍歷半連接鏈表,發(fā)現剛才acked的連接,synack重傳次數在閥值以?xún)?,重新發(fā)送synack給client端。


上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞:

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>