Linux下高效能網路編程中的幾個TCP/IP選項

來源:互聯網
上載者:User

http://blog.chinaunix.net/uid-20357359-id-1963666.html

最近在新的平台上測試程式,以前一些沒有注意到的問題都成為了效能瓶頸,通過設定一些TCP/IP選項能夠解決一部分問題,當然根本的解決方案是重構代碼,重新設計伺服器架構。先列出幾個TCP/IP選項:

選項
man 7 socket:
SO_REUSEADDR
SO_RECVBUF/SO_SNDBUF
SO_KEEPALIVE
SO_LINGER

man 7 tcp:
TCP_CORK
TCP_NODELAY
TCP_DEFER_ACCEPT
TCP_KEEPCNT/TCP_KEEPIDLE/TCP_KEEPINTVL

SO_REUSEADDR
在伺服器程式中,SO_REUSEADDR socket選項通常在調用bind()之前被設定。
SO_REUSEADDR可以用在以下四種情況下。 
(摘自《Unix網路編程》卷一,即UNPv1)
1、當有一個有相同本地地址和連接埠的socket1處於TIME_WAIT狀態時,而你啟動的程式的socket2要佔用該地址和連接埠,你的程式就要用到該選項。 
2、SO_REUSEADDR允許同一port上啟動同一伺服器的多個執行個體(多個進程)。但每個執行個體綁定的IP地址是不能相同的。在有多塊網卡或用IP Alias技術的機器可以測試這種情況。 
3、SO_REUSEADDR允許單個進程綁定相同的連接埠到多個socket上,但每個socket綁定的ip地址不同。這和2很相似,區別請看UNPv1。 
4、SO_REUSEADDR允許完全相同的地址和連接埠的重複綁定。但這隻用於UDP的多播,不用於TCP。

TCP_NODELAY/TCP_CHORK
TCP_NODELAY和TCP_CORK基本上控制了包的“Nagle化”,Nagle化在這裡的含義是採用Nagle演算法把較小的包組裝為更大的幀。TCP_NODELAY和TCP_CORK都禁掉了Nagle演算法,只不過他們的行為不同而已。
TCP_NODELAY 不使用Nagle演算法,不會將小包進行拼接成大包再進行發送,直接將小包發送出去,會使得小包時候使用者體驗非常好。
當在傳送大量資料的時候,為了提高TCP發送效率,可以設定TCP_CORK,CORK顧名思義,就是"塞子"的意思,它會盡量在每次發送最大的資料量。當設定了TCP_CORK後,會有阻塞200ms,當阻塞時間過後,資料就會自動傳送。

詳細的資料可以查看參考文獻5。

SO_LINGER
linger,顧名思義是延遲延緩的意思,這裡是延緩連線導向的socket的close操作。預設,close立即返回,但是當發送緩衝區中還有一部分資料的時候,系統將會嘗試將資料發送給對端。SO_LINGER可以改變close的行為。控制SO_LINGER通過下面一個結構:
struct linger
{
 int l_onoff; /*0=off, nonzero=on*/
 int l_linger; /*linger time, POSIX specifies units as seconds*/
};

通過結構體中成員的不同賦值,可以表現為下面幾種情況:
1. l_onoff設定為0,選項被關閉。l_linger值被忽略,就是上面的預設情形,close立即返回。
2. l_onoff設定為非0,l_linger被設定為0,則close()不被阻塞立即執行,丟棄socket發送緩衝區中的資料,並向對端發送一個RST報文。這種關閉方式稱為“強制”或“失效”關閉。
3. l_onoff設定為非0,l_linger被設定為非0,則close()調用阻塞進程,直到所剩資料發送完畢或逾時。這種關閉稱為“優雅的”關閉。

注意:
這個選項需要謹慎使用,尤其是強制式關閉,會丟失伺服器發給用戶端的最後一部分資料。UNP中:
The TIME_WAIT state is our friend and is there to help us(i.e., to let the old duplicate segments expire in the network).

TCP_DEFER_ACCEPT
defer accept,從字面上理解是延遲accept,實際上是當接收到第一個資料之後,才會建立串連。對於像HTTP等非互動伺服器,這個很有意義,可以用來防禦空串連攻擊(只是建立串連,但是不發送任何資料)。
使用方法如下:

val = 5;

setsockopt(srv_socket->fd, SOL_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val)) ;

裡面 val 的單位是秒,注意如果開啟這個功能,kernel 在 val 秒之內還沒有收到資料,不會繼續喚醒進程,而是直接丟棄串連。如果伺服器設定TCP_DEFER_ACCEPT選項後,伺服器受到一個CONNECT請求後,三向交握之後,新的socket狀態依然為SYN_RECV,而不是ESTABLISHED,作業系統不會Accept。
由於設定TCP_DEFER_ACCEPT選項之後,三向交握後狀態沒有達到ESTABLISHED,而是SYN_RECV。這個時候,如果用戶端一直沒有發送"資料"報文,伺服器將重傳SYN/ACK報文,重傳次數受net.ipv4.tcp_synack_retries參數控制,達到重傳次數之後,才會再次進行setsockopt中設定的逾時值,因此會出現SYN_RECV存留時間比設定值大一些的情況。

關於SYN_RECV狀態可以查看參考文獻7。

SO_KEEPALIVE/TCP_KEEPCNT/TCP_KEEPIDLE/TCP_KEEPINTVL
如果一方已經關閉或異常終止串連,而另一方卻不知道,我們將這樣的TCP串連稱為半開啟的。TCP通過保活定時器(KeepAlive)來檢測半開啟串連。
在高並發的網路伺服器中,經常會出現漏掉socket的情況,對應的結果有一種情況就是出現大量的CLOSE_WAIT狀態的串連。這個時候,可以通過設定KEEPALIVE選項來解決這個問題,當然還有其他的方法可以解決這個問題,詳細的情況可以查看參考資料8。

使用方法如下:

//Setting For KeepAlive

int keepalive = 1;

setsockopt(incomingsock,SOL_SOCKET,SO_KEEPALIVE,(void*)(&keepalive),(socklen_t)sizeof(keepalive));

                        

int keepalive_time = 30;

setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPIDLE,(void*)(&keepalive_time),(socklen_t)sizeof(keepalive_time));

int keepalive_intvl = 3;

setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPINTVL,(void*)(&keepalive_intvl),(socklen_t)sizeof(keepalive_intvl));

int keepalive_probes= 3;

setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPCNT,(void*)(&keepalive_probes),(socklen_t)sizeof(keepalive_probes));


設定SO_KEEPALIVE選項來開啟KEEPALIVE,然後通過TCP_KEEPIDLE、TCP_KEEPINTVL和TCP_KEEPCNT設定keepalive的開始時間、間隔、次數等參數。
當然,也可以通過設定/proc/sys/net/ipv4/tcp_keepalive_time、tcp_keepalive_intvl和tcp_keepalive_probes等核心參數來達到目的,但是這樣的話,會影響所有的socket,因此建議使用setsockopt設定。

參考:
1. man 7 socket
2. man 7 tcp
3. 《Unix Network Programming》 Section 7.5 "Generic Socket Options"
4. http://www.linuxsir.org/bbs/showthread.php?t=55738
5. http://blog.chinaunix.net/u/12592/showart_1723934.html
6. http://blog.csdn.net/fullsail/archive/2009/08/09/4429102.aspx
7. http://www.kernelchina.org/?q=node/110
8. http://blog.chinaunix.net/u/12592/showart.php?id=2059174

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.