在服務端訪問量大的時候檢測到大量的time wait,並且介面請求延時較高。
執行 netstat -n |awk 『/^tcp/end』
這個shell命令的意思是把netstat -n 後結果的最後一條放到s陣列中,如果相同則執行+1操作。
此時能看到tcp各種狀態下的連線數量,示例
服務端架構是採用nginx 負載均衡後台有多台tomcat。
先說下tcp建立連線和終止連線的流程
tcp三次握手過程:
1、客戶端傳送syn(seq=x)報文給伺服器端,進入syn_send狀態。
2、伺服器端收到syn報文,回應乙個syn (seq=y)ack(ack=x+1)報文,進入syn_recv狀態。
3、客戶端收到伺服器端的syn報文,回應乙個ack(ack=y+1)報文,進入established狀態。
三次握手完成,tcp客戶端和伺服器端成功地建立連線,可以開始傳輸資料了。
tcp四次拜拜的過程:
(1) 某個應用程序首先呼叫close,稱該端執行「主動關閉」(active close)。該端的tcp於是傳送乙個fin分節,表示資料傳送完畢。
(2) 接收到這個fin的對端執行 「被動關閉」(passive close),這個fin由tcp確認。
注意:fin的接收也作為乙個檔案結束符(end-of-file)傳遞給接收端應用程序,放在已排隊等候該應用程序接收的任何其他資料之後,因為,fin的接收意味著接收端應用程序在相應連線上再無額外資料可接收。
(3) 一段時間後,接收到這個檔案結束符的應用程序將呼叫close關閉它的套接字。這導致它的tcp也傳送乙個fin。
(4) 接收這個最終fin的原傳送端tcp(即執行主動關閉的那一端)確認這個fin。
關於tcp狀態轉換圖建議看下這篇文章。
重點說下time_wait、fin_wait_1、fin_wait_2這三個狀態:
time_wait狀態表示收到了對方的fin報文,並傳送出了ack報文,就等2msl後即可回到closed可用狀態了。如果fin_wait_1狀態下,收到了對方同時帶 fin標誌和ack標誌的報文時,可以直接進入到time_wait狀態,而無須經過fin_wait_2狀態。
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狀態**
此部分可以通過調整核心引數完成
vi /etc/sysctl.conf
#表示開啟重用,即允許將time_wait socket用於新的tcp連線。預設是關閉的
net.ipv4.tcp_tw_reuse = 1
#表示開啟time_wait的快速**
net.ipv4.tcp_tw_recycle = 1
#表示如果套接字由本端要求關閉,這個引數決定了它保持在fin-wait-2狀態的時間,預設是60
net.ipv4.tcp_fin_timeout = 10
方法二、建立長連線(推薦)
短連線的方式在請求量大的時候需要頻繁的進行連線的建立和**。
長連線節省了三次握手的時間,但是比較占用伺服器資源。如果每個使用者建立乙個長連線,那麼很快就到系統瓶頸。這時候可以採用長連線復用技術。以nginx+tomcat為例。
nginx配置
nginx利用tomcat實現長連線復用keepalive_timeout與tomcat配置保持一致
upstream mysdc
keepalive_timeout 120s 120s;
tomcat配置maxkeepaliverequests表示每個長連線支撐多少請求,keepalivetimeout超時時間120s
sql大量資料分頁
一種.select top 10 from tb where id not in select top 10 page from tb order by id order by id 其中,page是頁數的索引,實際的頁數要減一,這個分頁,對少數量的資料可以,也比使用游標快,但用到了not in關鍵...
Oracle 插入大量資料
2.假如tab1表中的沒有資料的話 drop table tab1 create table tab1 as select from tab2 然後在建立索引 3.用hint 提示減少操作時間 4.採用不寫日誌及使用hint提示減少資料操作的時間。建議方案是先修改表為不寫日誌 sql alter t...
tcp連線大量CLOSE WAIT
netstat n awk tcp end last ack 1 syn recv 15 close wait 7729 established 471 fin wait1 3 fin wait2 52 syn sent 1 time wait 725 從結果可以看到有大量的連線處於close wa...