[toc]html
擴展學習:java
TCP/IP 三次握手。四次揮手過程 http://www.doc88.com/p-9913773324388.htmlmysql
當中的%util是一個重要指標,指的是io等待的時間,即佔用CPU的時間,是一個時間比,當達到50%,60%的時候說明磁盤的IO太差,很忙,也就有問題。linux
輸入命令iotopios
free命令能夠顯示當前系統未使用的和已使用的內存數目,還能夠顯示被內核使用的內存緩衝區。nginx
total:內存總數;tatal=used+free+buff/cacheweb
used:已經使用的內存數;sql
free:空閒的內存數;編程
shared:當前已經廢棄不用;瀏覽器
buff/cache:分配給buffer和cache的內存總共有多大;
available:系統可以使用內存大小,avaliable包含free和buffer/cache剩餘部分。
數據通過CPU計算(很快計算完),即將要寫入磁盤(磁盤寫太慢了),這時用的內存爲buffer來臨時存儲,而後寫給磁盤;CPU要計算時,須要把數據從磁盤中讀出來,臨時放在內存中,這部份內存就是cache。因此係統必須預留一部分空間給buff/cache.
ps命令用於報告當前系統的進程狀態。能夠搭配kill指令隨時中斷、刪除沒必要要的程序。ps命令是最基本同時也是很是強大的進程查看命令,使用該命令能夠肯定有哪些進程正在運行和運行的狀態、進程是否結束、進程有沒有僵死、哪些進程佔用了過多的資源等等,總之大部分信息都是能夠經過執行該命令獲得的。以下示例:
[root@localhost ~]# ps aux |grep mysql [root@localhost ~]# ps aux |grep nginx
[ ] D:不能中斷的進程(一般爲IO),會影響系統負載.
[ ] R(run):正在運行中的進程,其中包括了等待CPU的時間片的進程(某時間段內)
[ ] S(sleep):已經中斷的進程,一般狀況下,系統中大部分進程都是這個狀態
[ ] T:已經中止或者暫停的進程,若是咱們正在運行一個命令,好比說 sleep 10 若是咱們按一下ctrl -z 讓他暫停,那麼咱們用ps查看就會顯示T這個狀態
[ ] W:這個好像是說,從內核2.6xx 之後,表示爲沒有足夠的內存頁分配
[ ] Z:殭屍進程,殺不掉,打不死的垃圾進程,佔系統一小點資源,不過沒有關係。若是太多,就有問題了。通常不會出現。
[ ] <:高優先級進程
[ ] N:低優先級進程
[ ] L:在內存中被鎖了內存分頁
[ ] s:主進程
[ ] l:多線程進程,該進程有多個線程.
[ ] +:表明在前臺運行的進程,好比當前終端執行ps aux就是前臺進程,前面出現的S+
netstat命令用來打印網絡鏈接情況、系統所開放端口、路由表等信息。
[root@localhost ~]# netstat -lnp //打印當前系統啓動哪些端口
[root@localhost ~]# netstat -an //打印網絡連接狀況
ESTABLISHED 45 這是一個很重要的參數,必須在1000之內.客戶端同時和你的服務器通訊。
若是沒有tcpdump 這個命令,須要用yum install -y tcpdump命令去安裝一下。
//-n第一個n表示不把主機的網絡地址轉換成名字,以數字形式顯示
[root@localhost ~]# tcpdump -nn -i ens33
# tcpdump -nn -i ens33 port 22 //只抓22端口的包 # tcpdump host 192.168.x.x //抓取指定ip的包 # tcpdump -nn -i ens33 tcp and not port 22 //指定抓tcp的包,可是不要22端口的 # tcpdump -nn -i ens33 port 22 and port 53 //只抓22和53端口的包
抓包命令是tshark,這條命令用於web服務器,將顯示的是web訪問日誌,若是服務器沒有配置訪問日誌,能夠臨時使用該命令查看一下當前服務器上的Web請求。要注意的是若是你的機器上沒有開啓Web服務,是不會顯示任何內容的
tshark -n -t a -R http.request -T fields -e "frame.time" -e "ip.src" -e "http.host" -e "http.request.method" -e "http.request.uri"
一般狀況下:一個正常的TCP鏈接,都會有三個階段:一、TCP三次握手;二、數據傳送;三、TCP四次揮手
注:如下說明最好能結合」圖2.5 :TCP的狀態機」來理解。
[ ] SYN: (同步序列編號,Synchronize Sequence Numbers)該標誌僅在三次握手創建TCP鏈接時有效。表示一個新的TCP鏈接請求。
[ ] ACK: (確認編號,Acknowledgement Number)是對TCP請求的確認標誌,同時提示對端系統已經成功接收全部數據。
[ ] FIN: (結束標誌,FINish)用來結束一個TCP回話.但對應端口仍處於開放狀態,準備接收後續數據。
LISTEN:首先服務端須要打開一個socket進行監聽,狀態爲LISTEN. /* The socket is listening for incoming connections. 偵聽來自遠方TCP端口的鏈接請求 */
SYN_SENT:客戶端經過應用程序調用connect進行active open.因而客戶端tcp發送一個SYN以請求創建一個鏈接.以後狀態置爲SYN_SENT. /*The socket is actively attempting to establish a connection. 在發送鏈接請求後等待匹配的鏈接請求 */
SYN_RECV:服務端應發出ACK確認客戶端的SYN,同時本身向客戶端發送一個SYN. 以後狀態置爲SYN_RECV /* A connection request has been received from the network. 在收到和發送一個鏈接請求後等待對鏈接請求的確認 */
ESTABLISHED: 表明一個打開的鏈接,雙方能夠進行或已經在數據交互了。/* The socket has an established connection. 表明一個打開的鏈接,數據能夠傳送給用戶 */
FIN_WAIT1:主動關閉(active close)端應用程序調用close,因而其TCP發出FIN請求主動關閉鏈接,以後進入FIN_WAIT1狀態./* The socket is closed, and the connection is shutting down. 等待遠程TCP的鏈接中斷請求,或先前的鏈接中斷請求的確認 */
CLOSE_WAIT:被動關閉(passive close)端TCP接到FIN後,就發出ACK以迴應FIN請求(它的接收也做爲文件結束符傳遞給上層應用程序),並進入CLOSE_WAIT. /* The remote end has shut down, waiting for the socket to close. 等待從本地用戶發來的鏈接中斷請求 */
FIN_WAIT2:主動關閉端接到ACK後,就進入了FIN-WAIT-2 ./* Connection is closed, and the socket is waiting for a shutdown from the remote end. 從遠程TCP等待鏈接中斷請求 */
LAST_ACK:被動關閉端一段時間後,接收到文件結束符的應用程序將調用CLOSE關閉鏈接。這致使它的TCP也發送一個 FIN,等待對方的ACK.就進入了LAST-ACK . /* The remote end has shut down, and the socket is closed. Waiting for acknowledgement. 等待原來發向遠程TCP的鏈接中斷請求的確認 */
TIME_WAIT:在主動關閉端接收到FIN後,TCP就發送ACK包,並進入TIME-WAIT狀態。/* The socket is waiting after close to handle packets still in the network.等待足夠的時間以確保遠程TCP接收到鏈接中斷請求的確認 */
CLOSING: 比較少見./* Both sockets are shut down but we still don’t have all our data sent. 等待遠程TCP對鏈接中斷的確認 */
CLOSED: 被動關閉端在接受到ACK包後,就進入了closed的狀態。鏈接結束./* The socket is not being used. 沒有任何鏈接狀態 */
TIME_WAIT狀態的造成只發生在主動關閉鏈接的一方。
主動關閉方在接收到被動關閉方的FIN請求後,發送成功給對方一個ACK後,將本身的狀態由FIN_WAIT2修改成TIME_WAIT,而必須再等2倍 的MSL(Maximum Segment Lifetime,MSL是一個數據報在internetwork中能存在的時間)時間以後雙方纔能把狀態 都改成CLOSED以關閉鏈接。目前RHEL裏保持TIME_WAIT狀態的時間爲60秒。
固然上述不少TCP狀態在系統裏都有對應的解釋或設置,可見man tcp
長鏈接(keepalive)是須要靠雙方不斷的發送探測包來維持的,keepalive期間服務端和客戶端的TCP鏈接狀態是ESTABLISHED.目前http 1.1版本里默認都是keepalive(1.0版本默認是不keepalive的),ie6/7/8和firefox都默認用的是http 1.1版本了(如何查看當前瀏覽器用的是哪一個版本,這裏再也不贅述)。Apache,java
一個應用至於究竟是該使用短鏈接仍是長鏈接,應該視具體狀況而定。通常的應用應該使用長鏈接。
2.1 Linux的相關keepalive參數
a、 tcp_keepalive_time - INTEGER How often TCP sends out keepalive messages when keepalive is enabled. Default: 2hours. b、 tcp_keepalive_probes - INTEGER How many keepalive probes TCP sends out, until it decides that the connection is broken. 在認定鏈接失效以前,發送多少個TCP的keepalive探測包。 Default value: 9. 缺省值是9,這個值乘以tcp_keepalive_intvl以後決定了,一個鏈接發送了keepalive以後能夠有多少時間沒有迴應。 c、 tcp_keepalive_intvl - INTEGER How frequently the probes are send out. Multiplied by tcp_keepalive_probes it is time to kill not responding connection, after probes started. Default value: 75sec i.e. connection will be aborted after ~11 minutes of retries. 當探測沒有確認時,從新發送探測的頻度,缺省值是75秒
二、F5負載均衡上的相關參數說明
a、Keep Alive Interval Specifies, when enabled, how frequently the system sends data over an idle TCP connection, to determine whether the connection is still valid.V Specify: Specifies the interval at which the system sends data over an idle connection, to determine whether the connection is still valid. The default is 1800 milliseconds. b、Time Wait Specifies the length of time that a TCP connection remains in the TIME-WAIT state before entering the CLOSED state. Specify: Specifies the number of milliseconds that a TCP connection can remain in the TIME-WAIT state. The defaultis 2000.
c、Idle Timeout
Specifies the length of time that a connection is idle (has no traffic) before the connection is eligible for deletion.
Specify: Specifies a number of seconds that the TCP connection can remain idle before the system deletes it. The default is 300 seconds.
三、Apache的相關參數說明
如下是Apache/2.0.61版本的默認參數和說明
a、KeepAlive: default On.Whether or not to allow persistent connections (more than one request per connection). Set to 「Off」 to deactivate. b、MaxKeepAliveRequests: default 100.The maximum number of requests to allow during a persistent connection. Set to 0 to allow an unlimited amount. We recommend you leave this number high, for maximum performance. c、KeepAliveTimeout: default 15. Number of seconds to wait for the next request from the same client on the same connection.
本地的進程間通訊(IPC)有不少種方式,但能夠總結爲下面4類:
咱們要討論的是網絡中進程之間如何通訊?首要解決的問題是如何惟一標識一個進程,不然通訊無從談起!在本地能夠經過進程PID來惟一標識一個進程,可是在網絡中這是行不通的。其實TCP/IP協議族已經幫咱們解決了這個問題,網絡層的「ip地址」能夠惟一標識網絡中的主機,而傳輸層的「協議+端口」能夠惟一標識主機中的應用程序(進程)。這樣利用三元組--ip地址,協議,端口就能夠標識網絡的進程了,網絡中的進程通訊就能夠利用這個標誌與其它進程進行交互。
使用TCP/IP協議的應用程序一般採用應用編程接口:UNIX BSD的套接字(socket)和UNIX System V的TLI(已經被淘汰),來實現網絡進程之間的通訊。就目前而言,幾乎全部的應用程序都是採用socket,而如今又是網絡時代,網絡中進程通訊是無處不在,這就是我爲何說「一切皆socket」。
TCP/IP(Transmission Control Protocol/Internet Protocol)即傳輸控制協議/網間協議,是一個工業標準的協議集,它是爲廣域網(WANs)設計的。 TCP/IP協議存在於OS中,網絡服務經過OS提供,在OS中增長支持TCP/IP的系統調用——Berkeley套接字,如Socket,Connect,Send,Recv等 UDP(User Data Protocol,用戶數據報協議)是與TCP相對應的協議。它是屬於TCP/IP協議族中的一種。如圖:
上面咱們已經知道網絡中的進程是經過socket來通訊的,那什麼是socket呢?socket起源於Unix,而Unix/Linux基本哲學之一就是「一切皆文件」,均可以用「打開open –> 讀寫write/read –> 關閉close」模式來操做。個人理解就是Socket就是該模式的一個實現,socket便是一種特殊的文件,一些socket函數就是對其進行的操做(讀/寫IO、打開、關閉),這些函數咱們在後面進行介紹。
socket一詞的起源
在組網領域的首次使用是在1970年2月12日發佈的文獻IETF RFC33中發現的,撰寫者爲Stephen Carr、Steve Crocker和Vint Cerf。根據美國計算機歷史博物館的記載,Croker寫道:「命名空間的元素均可稱爲套接字接口。一個套接字接口構成一個鏈接的一端,而一個鏈接可徹底由一對套接字接口規定。」計算機歷史博物館補充道:「這比BSD的套接字接口定義早了大約12年。」
既然socket是「open—write/read—close」模式的一種實現,那麼socket就提供了這些操做對應的函數接口。下面以TCP爲例,介紹幾個基本的socket接口函數。
tcp socket 流程
咱們知道tcp創建鏈接要進行「三次握手」,即交換三個分組。大體流程以下:
咱們以張三和李四的見面來模擬該過程,這三次握手就比如兩人在間隔50的地方見到對方,由於霧霾等緣由不能100%確認,因此要招手來相互確認對方是否定識本身。 張三主動招手(SYN)和李四打招呼,李四還以微笑(ACK)並招手(SYN)確認是不是張三,張三點頭微笑(ACK),李四看到張三的ACK後,確認後,進入了established狀態。
咱們看到這個過程當中一共是四個動做,張三招手--李四點頭微笑--李四招手--張三點頭微笑。
其中李四連續進行了2個動做,先是點頭微笑(回覆對方),而後再次招手(尋求確認),實際上能夠將這兩個動做合一,招手的同時點頭和微笑(syn+ack)。
因而四個動做就簡化成了三個動做,張三招手--李四點頭微笑並招手--張三點頭微笑。這就是三次握手的本質,中間的一次動做是兩個動做的合併。
咱們看到有兩個中間狀態,syn_sent和syn_rcvd,這兩個狀態叫着「半打開」狀態,就是向對方招手了,可是還沒來得及看到對方的點頭微笑。
syn_sent是主動打開方的「半打開」狀態,syn_rcvd是被動打開方的「半打開」狀態。客戶端是主動打開方,服務器是被動打開方。
syn_sent: syn package has been sent syn_rcvd: syn package has been received
TCP 數據傳輸就是兩我的隔空對話,差了一點距離,因此須要對方反覆確認聽見了本身的話。
張三喊了一句話(data),李四聽見了以後要向張三回覆本身聽見了(ack)。
若是張三喊了一句,半天沒聽到李四回覆,張三就認爲本身的話被大風吹走了,李四沒聽見,因此須要從新喊話,這就是tcp重傳。
也有多是李四聽到了張三的話,可是李四向張三的回覆被大風吹走了,以致於張三沒聽見李四的回覆。
張三並不能判斷到底是本身的話被大風吹走了仍是李四的回覆被大風吹走了,張三也不用管,重傳一下就是。
既然會重傳,李四就有可能同一句話聽見了兩次,這就是「去重」。「重傳」和「去重」工做操做系統的網絡內核模塊都已經幫咱們處理好了,用戶層是不用關心的。 張三能夠向李四喊話,一樣李四也能夠向張三喊話,由於tcp連接是「雙工的」,雙方均可以主動發起數據傳輸。不過不管是哪方喊話,都須要收到對方的確認才能認爲對方收到了本身的喊話。
張三多是個高射炮,一說連說了八句話,這時候李四能夠不用一句一句回覆,而是連續聽了這八句話以後,一塊兒向對方回覆說前面你說的八句話我都聽見了,這就是批量ack。
可是張三也不能一次性說了太多話,李四的腦子短期可能沒法消化太多,兩人之間須要有協商好的合適的發送和接受速率,這個就是「TCP窗口大小」。
網絡環境的數據交互同人類之間的對話還要複雜一些,它存在數據包亂序的現象。
同一個來源發出來的不一樣數據包在「網際路由」上可能會走過不一樣的路徑,最終達到同一個地方時,順序就不同了。
操做系統的網絡內核模塊會負責對數據包進行排序,到用戶層時順序就已經徹底一致了。
客戶端向服務器發送一個SYN J 服務器向客戶端響應一個SYN K,並對SYN J進行確認ACK J+1 客戶端再想服務器發一個確認ACK K+1 只有就完了三次握手,可是這個三次握手發生在socket的那幾個函數中呢?請看下圖:
圖一、socket中發送的TCP三次握手
從圖中能夠看出,當客戶端調用connect時,觸發了鏈接請求,向服務器發送了SYN J包,這時connect進入阻塞狀態;服務器監聽到鏈接請求,即收到SYN J包,調用accept函數接收請求向客戶端發送SYN K ,ACK J+1,這時accept進入阻塞狀態;客戶端收到服務器的SYN K ,ACK J+1以後,這時connect返回,並對SYN K進行確認;服務器收到ACK K+1時,accept返回,至此三次握手完畢,鏈接創建。
總結:客戶端的connect在三次握手的第二個次返回,而服務器端的accept在三次握手的第三次返回。
上面介紹了socket中TCP的三次握手創建過程,及其涉及的socket函數。如今咱們介紹socket中的四次握手釋放鏈接的過程,請看下圖: 圖二、socket中發送的TCP四次握手
圖示過程以下:
這樣每一個方向上都有一個FIN和ACK。
TCP斷開連接的過程和創建連接的過程比較相似,只不過中間的兩部並不老是會合成一步走,因此它分紅了4個動做,張三揮手(fin)——李四傷感地微笑(ack)——李四揮手(fin)——張三傷感地微笑(ack)。
之因此中間的兩個動做沒有合併,是由於tcp存在「半關閉」狀態,也就是單向關閉。
張三已經揮了手,但是人尚未走,只是再也不說話,可是耳朵仍是能夠繼續聽,李四呢繼續喊話。等待李四累了,也再也不說話了,超張三揮了揮手,張三傷感地微笑了一下,才完全結束了。
上面有一個很是特殊的狀態time_wait,它是主動關閉的一方在回覆完對方的揮手後進入的一個長期狀態,這個狀態標準的持續時間是4分鐘,4分鐘後纔會進入到closed狀態,釋放套接字資源。不過在具體實現上這個時間是能夠調整的。
它就比如主動分手方要承擔的責任,是你提出的要分手,你得付出代價。這個後果就是持續4分鐘的time_wait狀態,不能釋放套接字資源(端口),就比如守寡期,這段時間內套接字資源(端口)不得回收利用。
它的做用是重傳最後一個ack報文,確保對方能夠收到。由於若是對方沒有收到ack的話,會重傳fin報文,處於time_wait狀態的套接字會當即向對方重發ack報文。
同時在這段時間內,該連接在對話期間於網際路由上產生的殘留報文(由於路徑過於崎嶇,數據報文走的時間太長,重傳的報文都收到了,原始報文還在路上)傳過來時,都會被當即丟棄掉。
4分鐘的時間足以使得這些殘留報文完全消逝。否則當新的端口被重複利用時,這些殘留報文可能會干擾新的連接。
4分鐘就是2個MSL,每一個MSL是2分鐘。MSL就是maximium segment lifetime——最長報文壽命。這個時間是由官方RFC協議規定的。至於爲何是2個MSL而不是1個MSL,我尚未看到一個很是滿意的解釋。
四次揮手也並不老是四次揮手,中間的兩個動做有時候是能夠合併一塊兒進行的,這個時候就成了三次揮手,主動關閉方就會從fin_wait_1狀態直接進入到time_wait狀態,跳過了fin_wait_2狀態。
參考文獻:http://blog.csdn.net/banbanlin/article/details/46368031