摘要:一般產(chǎn)生的原因是系統(tǒng)沒(méi)有主動(dòng)關(guān)閉連接如連接資源沒(méi)有關(guān)閉關(guān)于網(wǎng)絡(luò)鏈路中追蹤異常用到的運(yùn)維命令以下顯示的和端口均為假數(shù)據(jù)中查看的狀態(tài)參數(shù)說(shuō)明已使用的所有協(xié)議套接字總量正在使用正在偵聽(tīng)的套接字?jǐn)?shù)量。其值等于已分配已建立已申請(qǐng)到的套接字?jǐn)?shù)量。
HTTP請(qǐng)求的流程梳理
用戶輸入url如http:www.baidu.com到瀏覽器,瀏覽器如chrom需要將其解析為ip地址才知道需要到哪里去訪問(wèn)哪個(gè)服務(wù)器。瀏覽器解析DNS步驟如下
搜索瀏覽器自身的dns緩存,這個(gè)緩存緩存時(shí)間短,緩存數(shù)目有限。
搜索操作系統(tǒng)的dns緩存
讀取host文件的dns映射(一般做本地開發(fā)映射都是修改這個(gè)文件來(lái)達(dá)到攔截瀏覽器請(qǐng)求到本地服務(wù)器的目的,從而使本地可以成功映射服務(wù)器地址)
先本地網(wǎng)卡配置里的dns服務(wù)器發(fā)起域名解析請(qǐng)求,這里好像還有一套運(yùn)營(yíng)商的處理流程就不在展開了。
下面好像還有一些流程,由于基本不會(huì)執(zhí)行到這一步,一般所以dns運(yùn)營(yíng)商的dns服務(wù)器都會(huì)搞定的。
解析失敗,以上任何一步成功都會(huì)返回一個(gè)成功的ip地址
瀏覽器以一個(gè)隨機(jī)的端口享這個(gè)ip地址的特定端口(默認(rèn)80)發(fā)起著名的TCP3次握手。關(guān)于一個(gè)http請(qǐng)求是如何到達(dá)nginx服務(wù)的流程大致如下:
握手完成后的瀏覽器和服務(wù)器就可以愉快地發(fā)送http請(qǐng)求了,具體在nginx上流程如下:
PHP-FPM在服務(wù)端出來(lái)請(qǐng)求中扮演了什么角色 PHP、nginx與CGI協(xié)議對(duì)于一個(gè)PHP的web程序來(lái)說(shuō),web服務(wù)器(如:nginx)要想與它通信需要通過(guò)CGI協(xié)議。當(dāng)一個(gè)web請(qǐng)求觸達(dá)web服務(wù)器時(shí),web服務(wù)器會(huì)創(chuàng)建一個(gè)CGI進(jìn)程,CGI進(jìn)程將web的請(qǐng)求按照固定的格式進(jìn)行解析,然后寫入標(biāo)準(zhǔn)輸入(STDIN)和環(huán)境變量中,然后PHP啟動(dòng)的CGI解析器會(huì)從標(biāo)準(zhǔn)輸入(STDIN)和環(huán)境變量中讀取http請(qǐng)求的數(shù)據(jù),所以$_SERVER才會(huì)有數(shù)據(jù),然后做出相應(yīng)的邏輯處理,然后將處理結(jié)果放入標(biāo)準(zhǔn)輸出(STDOUT),CGI進(jìn)程從STDOUT中讀取響應(yīng)數(shù)據(jù)然后傳輸給瀏覽器,這樣服務(wù)端就完成了一次http請(qǐng)求。
上面是CGI的實(shí)現(xiàn)流程,但是使用CGI協(xié)議的服務(wù)器在用戶每次訪問(wèn)服務(wù)器的時(shí)候都需要fork/銷毀CGI進(jìn)程,必然照成多余的系統(tǒng)開銷,所以FASTCGI就是為了解決這個(gè)問(wèn)題的。
什么是FastCGI協(xié)議FastCGI會(huì)創(chuàng)建一個(gè)常駐的master進(jìn)程和多個(gè)worker進(jìn)程,master進(jìn)程負(fù)責(zé)管理和為worker進(jìn)程反派任務(wù),worker進(jìn)程負(fù)責(zé)內(nèi)部嵌入了CGI解析器用于解釋php代碼。
PHP-FPM是一個(gè)FastCGI進(jìn)程管理器,在LNMP體系中就是由它來(lái)實(shí)現(xiàn)FastCGI協(xié)議的。同樣,它也會(huì)創(chuàng)建一個(gè)常駐的master進(jìn)程和多個(gè)worker進(jìn)程,master進(jìn)程負(fù)責(zé)監(jiān)聽(tīng)端口和接收來(lái)自nginx的請(qǐng)求,指派任務(wù)給worker進(jìn)程。worker進(jìn)程的負(fù)責(zé)解釋php代碼。PHP-FPM可以通過(guò)配置預(yù)先啟動(dòng)一定數(shù)量的worker進(jìn)程,這樣當(dāng)http請(qǐng)求觸達(dá)時(shí)就可以更快速的響應(yīng)。
Nginx關(guān)于FastCGI的配置nginx與PHP-FPM之間的通信一般通過(guò)其ngx_http_fastcgi_module模塊來(lái)實(shí)現(xiàn)。其中fastcgi_pass用于設(shè)置fastcgi服務(wù)器的IP地址;fastcgi_param設(shè)置傳入fastcgi服務(wù)器的參數(shù)。這個(gè)模塊出現(xiàn)的配置問(wèn)題一般集中在這一塊。
相對(duì)于并發(fā)狀態(tài)下出現(xiàn)的問(wèn)題,一般也都集中在fastcgi服務(wù)器上,具體表現(xiàn)為fastcgi服務(wù)器為了應(yīng)對(duì)大量的http請(qǐng)求必須不停的fork新的worker進(jìn)程,這時(shí)就需要考慮服務(wù)器可支持的最大鏈接數(shù)和最大打開文件數(shù)(可通過(guò)ulimit -n查看)以及php-fpm配置里的最低開啟worker數(shù)和最高開啟worker數(shù)的限制。高性能服務(wù)器可以在這個(gè)方向上調(diào)優(yōu)。
HTTP協(xié)議三次握手四次揮手的細(xì)節(jié) 協(xié)議過(guò)程中客服端與服務(wù)端的狀態(tài)圖 TCP的標(biāo)志位說(shuō)明標(biāo)志位 | 英文 | 說(shuō)明 |
---|---|---|
SYN | synchronous | 建立聯(lián)機(jī) |
ACK | acknowledgement | 確認(rèn) |
PSH | push | 傳送 |
FIN | finish | 結(jié)束 |
RST | reset | 重置 |
URG | urgent | 緊急 |
Sequence numbe | - | 順序號(hào)碼 |
Acknowledge number | - | 確認(rèn)號(hào)碼 |
狀態(tài) | 說(shuō)明 |
---|---|
LISTEN | 偵聽(tīng)狀態(tài) |
SYN_SEND | 發(fā)送連接請(qǐng)求[SYN=J]后等待匹配連接請(qǐng)求 |
SYN_RECEIVED | 收到連接請(qǐng)求[SYN=J]后發(fā)送連接確認(rèn)包[SYN=k,ack=J+1]后等待收到確認(rèn)包[Ack=k+1]狀態(tài) |
ESTABLISHED | 打開連接后,可以開始傳輸數(shù)據(jù) |
FIN_WAIT_1 | 發(fā)起連接中斷請(qǐng)求[FIN=M]后等待遠(yuǎn)程TCP確認(rèn)時(shí)[Ack=M+1]狀態(tài) |
FIN_WAIT_2 | 收到遠(yuǎn)程中斷確認(rèn)[Ack=M+1]后,等待遠(yuǎn)程中斷請(qǐng)求[FIN=N] |
CLOSE_WAIT | 收到連接中斷請(qǐng)求[FIN=M]后未發(fā)送出中斷確認(rèn)包[Ack=M=1]狀態(tài) |
TIME_WAIT | 發(fā)送確認(rèn)遠(yuǎn)程中斷請(qǐng)求[Ack=N+1]包后,進(jìn)入等待狀態(tài),用以保證被重新分配的socket不會(huì)受到之前殘留的延遲重發(fā)報(bào)文影響的機(jī)制 |
在四次揮手?jǐn)嚅_連接中,發(fā)起socket主動(dòng)關(guān)閉的一方 socket將進(jìn)入TIME_WAIT狀態(tài),TIME_WAIT狀態(tài)將持續(xù)2個(gè)MSL(Max Segment Lifetime),TIME_WAIT狀態(tài)下的socket不能被回收使用.
具體現(xiàn)象是對(duì)于一個(gè)處理大量短連接的服務(wù)器,如果是由服務(wù)器主動(dòng)關(guān)閉客戶端的連接,將導(dǎo)致服務(wù)器端存在大量的處于TIME_WAIT狀態(tài)的socket, 甚至比處于Established狀態(tài)下的socket多的多,嚴(yán)重影響服務(wù)器的處理能力,甚至耗盡可用的socket,停止服務(wù).
TIME_WAIT是TCP協(xié)議用以保證被重新分配的socket不會(huì)受到之前殘留的延遲重發(fā)報(bào)文影響的機(jī)制,是必要的邏輯保證。一般產(chǎn)生的原因是系統(tǒng)沒(méi)有主動(dòng)關(guān)閉連接,如mysql連接資源沒(méi)有關(guān)閉
關(guān)于網(wǎng)絡(luò)鏈路中追蹤異常用到的運(yùn)維命令(以下顯示的IP和端口均為假數(shù)據(jù))
Linux中查看socket的狀態(tài)cat /proc/net/sockstat
參數(shù) | 說(shuō)明 | ||
---|---|---|---|
sockets:used | 已使用的所有協(xié)議套接字總量 | ||
TCP:inuse | 正在使用(正在偵聽(tīng))的TCP套接字?jǐn)?shù)量。其值≤ netstat –lnt | grep ^tcp | wc –l |
TCP:orphan | 無(wú)主(不屬于任何進(jìn)程)的TCP連接數(shù)(無(wú)用、待銷毀的TCP socket數(shù)) | ||
TCP:tw | 等待關(guān)閉的TCP連接數(shù)。其值等于netstat –ant | grep TIME_WAIT | wc –l |
TCP:alloc | 已分配(已建立、已申請(qǐng)到sk_buff)的TCP套接字?jǐn)?shù)量。其值等于netstat –ant | grep ^tcp | wc –l |
TCP:mem | 套接字緩沖區(qū)使用量 | ||
UDP:inuse | 正在使用的UDP套接字?jǐn)?shù)量 | ||
FRAG | 使用的IP段數(shù)量 |
netstat -na | awk "/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}"
參數(shù) | 說(shuō)明 |
---|---|
LISTEN | 正在監(jiān)聽(tīng)狀態(tài) |
CLOSE_WAIT | 對(duì)方主動(dòng)關(guān)閉連接或者網(wǎng)絡(luò)異常導(dǎo)致連接中斷,這時(shí)我方的狀態(tài)會(huì)變成CLOSE_WAIT 此時(shí)我方要調(diào)用close()來(lái)使得連接正確關(guān)閉 |
ESTABLISHED | 建立連接,正在通信 |
TIME_WAIT | 我方主動(dòng)調(diào)用close()斷開連接,收到對(duì)方確認(rèn)后狀態(tài)變?yōu)門IME_WAIT |
tcpdump -n port 3306mysql 主動(dòng)斷開鏈接
11:38:45.693382 IP 172.18.0.3.3306 > 172.18.0.5.38822: Flags [F.], seq 123, ack 144, win 227, options [nop,nop,TS val 3000355 ecr 2997359], length 0 # MySQL發(fā)送fin包給我
11:38:45.740958 IP 172.18.0.5.38822 > 172.18.0.3.3306: Flags [.], ack 124, win 229, options [nop,nop,TS val 3000360 ecr 3000355], length 0 # 我回復(fù)ack給它
11:38:45.740960 IP 172.18.0.3.3306 > 172.18.0.5.38822: Flags [F.], ack 125, win 231, options [nop,nop,TS val 3000360 ecr 3000355], length 0 # MySQL發(fā)送fin包給客戶端
11:38:45.740965 IP 172.18.0.5.38822 > 172.18.0.3.3306: Flags [.], ack 125, win 229, options [nop,nop,TS val 3000360 ecr 3000355], length 0 # 客戶端回復(fù)ack給我
......
src > dst: flags data-seqno ack window urgent options # 發(fā)生了 3次握手 11:38:15.679863 IP 172.18.0.5.38822 > 172.18.0.3.3306: Flags [S], seq 4065722321, win 29200, options [mss 1460,sackOK,TS val 2997352 ecr 0,nop,wscale 7], length 0 11:38:15.679923 IP 172.18.0.3.3306 > 172.18.0.5.38822: Flags [S.], seq 780487619, ack 4065722322, win 28960, options [mss 1460,sackOK,TS val 2997352 ecr 2997352,nop,wscale 7], length 0 11:38:15.679936 IP 172.18.0.5.38822 > 172.18.0.3.3306: Flags [.], ack 1, win 229, options [nop,nop,TS val 2997352 ecr 2997352], length 0
參數(shù) | 說(shuō)明 |
---|---|
src > dst | 表明從源地址到目的地址 |
flags | 是TCP包中的標(biāo)志信息,S 是SYN標(biāo)志, F(FIN), P(PUSH) , R(RST) "."(沒(méi)有標(biāo)記) |
data-seqno | 是數(shù)據(jù)包中的數(shù)據(jù)的順序號(hào) |
ack | 是下次期望的順序號(hào) |
window | 是接收緩存的窗口大小 |
urgent | 表明數(shù)據(jù)包中是否有緊急指針 |
options | 是選項(xiàng) |
傳送門
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/30986.html
摘要:一般產(chǎn)生的原因是系統(tǒng)沒(méi)有主動(dòng)關(guān)閉連接如連接資源沒(méi)有關(guān)閉關(guān)于網(wǎng)絡(luò)鏈路中追蹤異常用到的運(yùn)維命令以下顯示的和端口均為假數(shù)據(jù)中查看的狀態(tài)參數(shù)說(shuō)明已使用的所有協(xié)議套接字總量正在使用正在偵聽(tīng)的套接字?jǐn)?shù)量。其值等于已分配已建立已申請(qǐng)到的套接字?jǐn)?shù)量。 HTTP請(qǐng)求的流程梳理 用戶輸入url如http:www.baidu.com到瀏覽器,瀏覽器如chrom需要將其解析為ip地址才知道需要到哪里去訪問(wèn)...
摘要:因?yàn)槭嵌噙M(jìn)程單線程同步模式,即一個(gè)子進(jìn)程同時(shí)最多處理一個(gè)請(qǐng)求,所以子進(jìn)程數(shù)等于最大并發(fā)數(shù)。 a little tips in my code career | 碼碼踩過(guò)的那些坑2015-2016 記一下這一年碼碼中我需要去了解的基礎(chǔ)知識(shí),有不對(duì)的歡迎大家指證出來(lái):https://github.com/TIGERB/car... 關(guān)于設(shè)計(jì)模式 關(guān)于PHP 關(guān)于互聯(lián)網(wǎng)協(xié)議 設(shè)計(jì)模...
閱讀 3561·2023-04-26 00:39
閱讀 4787·2021-09-22 10:02
閱讀 2612·2021-08-09 13:46
閱讀 1175·2019-08-29 18:40
閱讀 1498·2019-08-29 18:33
閱讀 827·2019-08-29 17:14
閱讀 1570·2019-08-29 12:40
閱讀 3092·2019-08-28 18:07