linux服務器性能調優之tcp/ip性能調優

linux服務器性能調優之tcp/ip性能調優

TCP狀態轉移圖linux

1、TCP狀態介紹:golang

在TCP/IP協議中,TCP協議提供可靠的鏈接服務,採用三次握手創建一個鏈接。web

_第一次握手:創建鏈接時,客戶端發送syn包(syn=x)到服務器,並進入SYN_SEND狀態,等待服務器確認;
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=x+1),同時本身也發送一個SYN包(syn=y),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。_

完成三次握手,客戶端與服務器開始傳送數據,在上述過程當中,還有一些重要的概念:apache

未鏈接隊列:在三次握手協議中,服務器維護一個未鏈接隊列,該隊列爲每一個客戶端的SYN包(syn=j)開設一個條目,該條目代表服務器已收到 SYN包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的鏈接在服務器處於Syn_RECV狀態,當服務器收到客戶的確認包時,刪除該條目, 服務器進入ESTABLISHED狀態。
Backlog參數:表示未鏈接隊列的最大容納數目。服務器

SYN-ACK 重傳次數 服務器發送完SYN-ACK包,若是未收到客戶確認包,服務器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,若是重傳次數超 過系統規定的最大重傳次數,系統將該鏈接信息從半鏈接隊列中刪除。注意,每次重傳等待的時間不必定相同。cookie

半鏈接存活時間:是指半鏈接隊列的條目存活的最長時間,也即服務從收到SYN包到確認這個報文無效的最長時間,該時間值是全部重傳請求包的最長等待時間總和。有時咱們也稱半鏈接存活時間爲Timeout時間、SYN_RECV存活時間。網絡

狀態解釋
CLOSED: 表示初始狀態。架構

LISTEN:
表示服務器端的某個SOCKET處於監聽狀態,能夠接受鏈接併發

SYN_RCVD:
表示接受到了SYN報文,在正常狀況下,這個狀態是服務器端的SOCKET在創建TCP鏈接時的三次握手會話過程當中的一箇中間狀態,很短暫,基本上用 netstat你是很難看到這種狀態的,除非你特地寫了一個客戶端測試程序,故意將三次TCP握手過程當中最後一個ACK報文不予發送。所以這種狀態時,當 收到客戶端的ACK報文後,它會進入到ESTABLISHED狀態。socket

SYN_SENT:
這個狀態與SYN_RCVD遙想呼應,當客戶端SOCKET執行CONNECT鏈接時,它首先發送SYN報文,所以也隨即它會進入到了SYN_SENT狀態,並等待服務端的發送三次握手中的第2個報文。SYN_SENT狀態表示客戶端已發送SYN報文。

ESTABLISHED:表示鏈接已經創建

FIN_WAIT_1:
FIN_WAIT_1和FIN_WAIT_2狀態的真正含義都是表示等待對方的FIN報文。而這兩種狀態的區別是:FIN_WAIT_1狀態其實是當 SOCKET在ESTABLISHED狀態時,它想主動關閉鏈接,向對方發送了FIN報文,此時該SOCKET即進入到FIN_WAIT_1狀態。而當對 方迴應ACK報文後,則進入到FIN_WAIT_2狀態,固然在實際的正常狀況下,不管對方何種狀況下,都應該立刻迴應ACK報文,因此 FIN_WAIT_1狀態通常是比較難見到的,而FIN_WAIT_2狀態還有時經常能夠用netstat看到。

FIN_WAIT_2:
FIN_WAIT_2狀態下的SOCKET,表示半鏈接,也即有一方要求close鏈接,但另外還告訴對方,我暫時還有點數據須要傳送給你,稍後再關閉鏈接。

TIME_WAIT:
表示收到了對方的FIN報文,併發送出了ACK報文,就等2MSL後便可回到CLOSED可用狀態了。若是FIN_WAIT_1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,能夠直接進入到TIME_WAIT狀態,而無須通過FIN_WAIT_2狀態。

CLOSING:
正常狀況下,發送FIN報文後,按理來講是應該先收到(或同時收到)對方的ACK報文,再收到對方的FIN報文。可是CLOSING狀態表示你發送FIN 報文後,並無收到對方的ACK報文,反而卻也收到了對方的FIN報文。什麼狀況下會出現此種狀況呢?其實細想一下,也不可貴出結論:那就是若是雙方几乎 在同時close一個SOCKET的話,那麼就出現了雙方同時發送FIN報文的狀況,也即會出現CLOSING狀態,表示雙方都正在關閉SOCKET連 接。

CLOSE_WAIT:
表示在等待關閉。怎麼理解呢?當對方close一個SOCKET後發送FIN報文給本身,你係統毫無疑問地會迴應一個ACK報文給對方,此時則進入到 CLOSE_WAIT狀態。接下來呢,實際上你真正須要考慮的事情是察看你是否還有數據發送給對方,若是沒有的話,那麼你也就能夠 close這個SOCKET,發送FIN報文給對方,也即關閉鏈接。因此你在CLOSE_WAIT狀態下,須要完成的事情是等待你去關閉鏈接。

LAST_ACK:
被動關閉一方在發送FIN報文後,最後等待對方的ACK報文。當收到ACK報文後,也便可以進入到CLOSED可用狀態了。

須要C/C++ Linux服務器架構師學習資料加qun(563998835)獲取(資料包括C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg等),免費分享

linux服務器性能調優之tcp/ip性能調優

2、調優:

全部的TCP/IP調優參數都位於/proc/sys/net/目錄. 例如, 下面是最重要的一些調優參數, 後面是它們的含義:

  1. /proc/sys/net/core/rmem_max — 最大的TCP數據接收緩衝
  2. /proc/sys/net/core/wmem_max — 最大的TCP數據發送緩衝
  3. /proc/sys/net/ipv4/tcp_timestamps — 時間戳在(請參考RFC 1323)TCP的包頭增長12個字節
  4. /proc/sys/net/ipv4/tcp_sack — 有選擇的應答
  5. /proc/sys/net/ipv4/tcp_window_scaling — 支持更大的TCP窗口. 若是TCP窗口最大超過65535(64K), 必須設置該數值爲1
  6. rmem_default — 默認的接收窗口大小
  7. rmem_max — 接收窗口的最大大小
  8. wmem_default — 默認的發送窗口大小
  9. wmem_max — 發送窗口的最大大小
    • *

net.core.rmem_default = 256960
net.core.rmem_max = 256960
net.core.wmem_default = 256960
net.core.wmem_max = 256960

net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_sack =1
net.ipv4.tcp_window_scaling = 1


其餘調優:
開啓SYN Cookies。當出現SYN等待隊列溢出時,啓用cookies來處理,可防範少許SYN*,默認爲0,表示關閉;
net.ipv4.tcp_syncookies = 1

開啓重用。容許將TIME-WAIT sockets從新用於新的TCP鏈接,默認爲0,表示關閉;
net.ipv4.tcp_tw_reuse = 1

開啓TCP鏈接中TIME-WAIT sockets的快速回收,默認爲0,表示關閉;
net.ipv4.tcp_tw_recycle = 1

系統默認的TIMEOUT時間。
net.ipv4.tcp_fin_timeout = 5

當keepalive起用的時候,TCP發送keepalive消息的頻度。缺省是2小時,改成20分鐘(20*60s)
net.ipv4.tcp_keepalive_time = 1200

表示用於向外鏈接的端口範圍。缺省狀況下很小:32768到61000,改成10000到65000
net.ipv4.ip_local_port_range = 10000 65000

SYN隊列的長度,默認爲1024,加大隊列長度爲8192,能夠容納更多等待鏈接的網絡鏈接數
net.ipv4.tcp_max_syn_backlog = 8192

系統同時保持TIME_WAIT的最大數量,若是超過這個數字,TIME_WAIT將馬上被清除並打印警告信息。默認爲180000,改成5000
net.ipv4.tcp_max_tw_buckets = 5000

其餘調優參數
tcp_syn_retries :INTEGER
默認值是5
對於一個新建鏈接,內核要發送多少個 SYN 鏈接請求才決定放棄。不該該大於255,默認值是5,對應於180秒左右時間。(對於大負載而物理通訊良好的網絡而言,這個值偏高,可修改成2.這個值僅 僅是針對對外的鏈接,對進來的鏈接,是由tcp_retries1 決定的)

tcp_synack_retries :INTEGER
默認值是5
對於遠端的鏈接請求SYN,內核會發送SYN + ACK數據報,以確認收到上一個 SYN鏈接請求包。這是所謂的三次握手( threeway handshake)機制的第二個步驟。這裏決定內核在放棄鏈接以前所送出的 SYN+ACK 數目。不該該大於255,默認值是5,對應於180秒左右時間。(能夠根據上面的 tcp_syn_retries 來決定這個值)

tcp_keepalive_time :INTEGER
默認值是7200(2小時)
當keepalive打開的狀況下,TCP發送keepalive消息的頻率。(因爲目前網絡等因素,形成了利用這個進行的很頻繁,曾經也有cu 的朋友提到過,說若是2邊創建了鏈接,而後不發送任何數據或者rst/fin消息,那麼持續的時間是否是就是2小時,空鏈接*? tcp_keepalive_time就是預防此情形的.我我的在作nat服務的時候的修改值爲1800秒)

tcp_keepalive_probes:INTEGER
默認值是9
TCP發送keepalive探測以肯定該鏈接已經斷開的次數。(注意:保持鏈接僅在SO_KEEPALIVE套接字選項被打開是才發送.次數默認不須要修改,固然根據情形也能夠適當地縮短此值.設置爲5比較合適)

tcp_keepalive_intvl:INTEGER
默認值爲75
探測消息發送的頻率,乘以tcp_keepalive_probes就獲得對於從開始探測以來沒有響應的鏈接殺除的時間。默認值爲75秒,也就是沒有活動 的鏈接將在大約11分鐘之後將被丟棄。(對於普通應用來講,這個值有一些偏大,能夠根據須要改小.特別是web類服務器須要改小該值,15是個比較合適的 值)

tcp_retries1 :INTEGER
默認值是3
放棄迴應一個TCP鏈接請求前﹐須要進行多少次重試。RFC 規定最低的數值是3﹐這也是默認值﹐根據RTO的值大約在3秒 – 8分鐘之間。(注意:這個值同時還決定進入的syn鏈接)

tcp_retries2 :INTEGER
默認值爲15
在丟棄激活(已創建通信情況)的TCP鏈接以前﹐須要進行多少次重試。默認值爲15,根據RTO的值來決定,至關於13-30分鐘(RFC1122規定,必須大於100秒).(這個值根據目前的網絡設置,能夠適當地改小,個人網絡內修改成了5)

tcp_orphan_retries :INTEGER
默認值是7
在近端丟棄TCP鏈接以前﹐要進行多少次重試。默認值是7個﹐至關於 50秒 – 16分鐘﹐視 RTO 而定。若是您的系統是負載很大的web服務器﹐那麼也許須要下降該值﹐這類 sockets 可能會耗費大量的資源。另外參的考 tcp_max_orphans 。(事實上作NAT的時候,下降該值也是好處顯著的,我本人的網絡環境中下降該值爲3)

tcp_fin_timeout :INTEGER
默認值是 60
對於本端斷開的socket鏈接,TCP保持在FIN-WAIT-2狀態的時間。對方可能會斷開鏈接或一直不結束鏈接或不可預料的進程死亡。默認值爲 60 秒。過去在2.2版本的內核中是 180 秒。您能夠設置該值﹐但須要注意﹐若是您的機器爲負載很重的web服務器﹐您可能要冒內存被大量無效數據報填滿的風險﹐FIN-WAIT-2 sockets 的危險性低於 FIN-WAIT-1 ﹐由於它們最多隻吃 1.5K 的內存﹐可是它們存在時間更長。另外參考 tcp_max_orphans。(事實上作NAT的時候,下降該值也是好處顯著的,我本人的網絡環境中下降該值爲30)

tcp_max_tw_buckets :INTEGER
默認值是180000
系 統在同時所處理的最大 timewait sockets 數目。若是超過此數的話﹐time-wait socket 會被當即砍除而且顯示警告信息。之因此要設定這個限制﹐純粹爲了抵禦那些簡單的 DoS *﹐千萬不要人爲的下降這個限制﹐不過﹐若是網絡條件須要比默認值更多﹐則能夠提升它(或許還要增長內存)。(事實上作NAT的時候最好能夠適當地增長 該值)

tcp_tw_recycle :BOOLEAN
默認值是0
打開快速 TIME-WAIT sockets 回收。除非獲得技術專家的建議或要求﹐請不要隨意修改這個值。(作NAT的時候,建議打開它)

tcp_tw_reuse:BOOLEAN
默認值是0
該文件表示是否容許從新應用處於TIME-WAIT狀態的socket用於新的TCP鏈接(這個對快速重啓動某些服務,而啓動後提示端口已經被使用的情形很是有幫助)

tcp_max_orphans :INTEGER
缺省值是8192
系統所能處理不屬於任何進程的TCP sockets最大數量。假如超過這個數量﹐那麼不屬於任何進程的鏈接會被當即reset,並同時顯示警告信息。之因此要設定這個限制﹐純粹爲了抵禦那些 簡單的 DoS *﹐千萬不要依賴這個或是人爲的下降這個限制(這個值Redhat AS版本中設置爲32768,可是不少防火牆修改的時候,建議該值修改成2000)

tcp_abort_on_overflow :BOOLEAN
缺省值是0
當守護進程太忙而不能接受新的鏈接,就象對方發送reset消息,默認值是false。這意味着當溢出的緣由是由於一個偶然的猝發,那麼鏈接將恢復狀態。 只有在你確信守護進程真的不能完成鏈接請求時纔打開該選項,該選項會影響客戶的使用。(對待已經滿載的sendmail,apache這類服務的時候,這 個能夠很快讓客戶端終止鏈接,能夠給予服務程序處理已有鏈接的緩衝機會,因此不少防火牆上推薦打開它)

tcp_syncookies :BOOLEAN
默認值是0
只有在內核編譯時選擇了CONFIG_SYNCOOKIES時纔會發生做用。當出現syn等候隊列出現溢出時象對方發送syncookies。目的是爲了防止syn flood*
注意:該選項千萬不能用於那些沒有收到的高負載服務器,若是在日誌中出現synflood消息,可是調查發現沒有收到synflood,而是合法用戶的鏈接負載太高的緣由,你應該調整其它參數來提升服務器性能。參考:
tcp_max_syn_backlog
tcp_synack_retries
tcp_abort_on_overflow
syncookie嚴重的違背TCP協議,不容許使用TCP擴展,可能對某些服務致使嚴重的性能影響(如SMTP轉發)。(注意,該實現與BSD上面使用 的tcp proxy同樣,是違反了RFC中關於tcp鏈接的三次握手實現的,可是對於防護syn-flood的確頗有用.)

tcp_stdurg :BOOLEAN
默認值爲0
使用 TCP urg pointer 字段中的主機請求解釋功能。大部份的主機都使用老舊的 BSD解釋,所以若是您在 Linux 打開它﹐或會致使不能和它們正確溝通。

tcp_max_syn_backlog :INTEGER
對於那些依然還未得到客戶端確認的鏈接請求﹐須要保存在隊列中最大數目。對於超過 128Mb 內存的系統﹐默認值是 1024 ﹐低於 128Mb 的則爲 128。若是服務器常常出現過載﹐能夠嘗試增長這個數字。警告﹗假如您將此值設爲大於 1024﹐最好修改 include/net/tcp.h 裏面的 TCP_SYNQ_HSIZE ﹐以保持 TCP_SYNQ_HSIZE*16<=tcp_max_syn_backlog ﹐而且編進核心以內。(SYN Flood利用TCP協議散佈握手的缺陷,僞造虛假源IP地址發送大量TCP-SYN半打開鏈接到目標系統,最終致使目標系統Socket隊列資源耗 盡而沒法接受新的鏈接。爲了應付這種,現代Unix系統中廣泛採用多鏈接隊列處理的方式來緩衝(而不是解決)這種,是用一個基本隊列處理正常的完 全鏈接應用(Connect()和Accept() ),是用另外一個隊列單獨存放半打開鏈接。這種雙隊列處理方式和其餘一些系統內核措施(例如Syn-Cookies/Caches)聯合應用時,可以比較有 效的緩解小規模的SYN Flood(事實證實<1000p/s)加大SYN隊列長度能夠容納更多等待鏈接的網絡鏈接數,因此對Server來講能夠考慮增大該值.)

tcp_window_scaling :INTEGER
缺省值爲1
該 文件表示設置tcp/ip會話的滑動窗口大小是否可變。參數值爲布爾值,爲1時表示可變,爲0時表示不可變。tcp/ip一般使用的窗口最大可達到 65535 字節,對於高速網絡,該值可能過小,這時候若是啓用了該功能,可使tcp/ip滑動窗口大小增大數個數量級,從而提升數據傳輸的能力(RFC 1323)。(對普通地百M網絡而言,關閉會下降開銷,因此若是不是高速網絡,能夠考慮設置爲0)

tcp_timestamps :BOOLEAN
缺省值爲1
Timestamps 用在其它一些東西中﹐能夠防範那些僞造的 sequence 號碼。一條1G的寬帶線路或許會重遇到帶 out-of-line數值的舊sequence 號碼(假如它是因爲上次產生的)。Timestamp 會讓它知道這是個 ‘舊封包’。(該文件表示是否啓用以一種比超時重發更精確的方法(RFC 1323)來啓用對 RTT 的計算;爲了實現更好的性能應該啓用這個選項。)

tcp_sack :BOOLEAN
缺省值爲1
使 用 Selective ACK﹐它能夠用來查找特定的遺失的數據報— 所以有助於快速恢復狀態。該文件表示是否啓用有選擇的應答(Selective Acknowledgment),這能夠經過有選擇地應答亂序接收到的報文來提升性能(這樣可讓發送者只發送丟失的報文段)。(對於廣域網通訊來講這個 選項應該啓用,可是這會增長對 CPU 的佔用。)

tcp_fack :BOOLEAN
缺省值爲1
打開FACK擁塞避免和快速重傳功能。(注意,當tcp_sack設置爲0的時候,這個值即便設置爲1也無效)

tcp_dsack :BOOLEAN缺省值爲1容許TCP發送」兩個徹底相同」的SACK。

相關文章
相關標籤/搜索