版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第詳解PHPSwoole長(zhǎng)連接常見(jiàn)問(wèn)題Redis可以配置如果客戶端經(jīng)過(guò)多少秒還不給Redis服務(wù)器發(fā)送數(shù)據(jù),那么就會(huì)把連接close掉。
MySQL常見(jiàn)的報(bào)錯(cuò):
配置項(xiàng):wait_timeoutinteractive_timeout
報(bào)錯(cuò)信息:
hasgoneaway
和Redis服務(wù)器一樣,MySQL也會(huì)定時(shí)的去清理掉沒(méi)用的連接。
如何解決
1、用的時(shí)候進(jìn)行重連。優(yōu)點(diǎn)是簡(jiǎn)單,缺點(diǎn)是面臨短連接的問(wèn)題。
2、定時(shí)發(fā)送心跳維持連接(推薦)。
如何維持長(zhǎng)連接
tcp協(xié)議中實(shí)現(xiàn)的tcp_keepalive
操作系統(tǒng)底層提供了一組tcp的keepalive配置:
tcp_keepalive_time(integer;default:7200;sinceLinux2.2)
ThenumberofsecondsaconnectionneedstobeidlebeforeTCP
beginssendingoutkeep-aliveprobes.Keep-alivesaresentonly
whentheSO_KEEPALIVEsocketoptionisenabled.Thedefault
valueis7200seconds(2hours).Anidleconnectionis
terminatedafterapproximatelyanadditional11minutes(9
probesanintervalof75secondsapart)whenkeep-aliveis
enabled.
Notethatunderlyingconnectiontrackingmechanismsand
applicationtimeoutsmaybemuchshorter.
tcp_keepalive_intvl(integer;default:75;sinceLinux2.4)
ThenumberofsecondsbetweenTCPkeep-aliveprobes.
tcp_keepalive_probes(integer;default:9;sinceLinux2.2)
ThemaximumnumberofTCPkeep-aliveprobestosendbefore
givingupandkillingtheconnectionifnoresponseisobtained
fromtheotherend.
8
Swoole底層把這些配置開(kāi)放出來(lái)了,例如:
$server=new\Swoole\Server('127.0.0.1',6666,SWOOLE_PROCESS);
$server-set([
'worker_num'=1,
'open_tcp_keepalive'=1,
'tcp_keepidle'=4,//對(duì)應(yīng)tcp_keepalive_time
'tcp_keepinterval'=1,//對(duì)應(yīng)tcp_keepalive_intvl
'tcp_keepcount'=5,//對(duì)應(yīng)tcp_keepalive_probes
]);
其中:
'open_tcp_keepalive'=1,//總開(kāi)關(guān),用來(lái)開(kāi)啟tcp_keepalive
'tcp_keepidle'=4,//4s沒(méi)有數(shù)據(jù)傳輸就進(jìn)行檢測(cè)
//檢測(cè)的策略如下:
'tcp_keepinterval'=1,//1s探測(cè)一次,即每隔1s給客戶端發(fā)一個(gè)包(然后客戶端可能會(huì)回一個(gè)ack的包,如果服務(wù)端收到了這個(gè)ack包,那么說(shuō)明這個(gè)連接是活著的)
'tcp_keepcount'=5,//探測(cè)的次數(shù),超過(guò)5次后客戶端還沒(méi)有回ack包,那么close此連接
我們來(lái)實(shí)戰(zhàn)測(cè)試體驗(yàn)一下,服務(wù)端腳本如下:
$server=new\Swoole\Server('127.0.0.1',6666,SWOOLE_PROCESS);
$server-set([
'worker_num'=1,
'open_tcp_keepalive'=1,//開(kāi)啟tcp_keepalive
'tcp_keepidle'=4,//4s沒(méi)有數(shù)據(jù)傳輸就進(jìn)行檢測(cè)
'tcp_keepinterval'=1,//1s探測(cè)一次
'tcp_keepcount'=5,//探測(cè)的次數(shù),超過(guò)5次后還沒(méi)有回包c(diǎn)lose此連接
$server-on('connect',function($server,$fd){
var_dump("Client:Connect$fd");
$server-on('receive',function($server,$fd,$reactor_id,$data){
var_dump($data);
$server-on('close',function($server,$fd){
var_dump("closefd$fd");
$server-start();
我們啟動(dòng)這個(gè)服務(wù)器:
~/codeDir/phpCode/hyperf-skeleton#phpserver.php
然后通過(guò)tcpdump進(jìn)行抓包:
~/codeDir/phpCode/hyperf-skeleton#tcpdump-iloport6666
tcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecode
listeningonlo,link-typeEN10MB(Ethernet),capturesize262144bytes
我們此時(shí)正在監(jiān)聽(tīng)lo上的6666端口的數(shù)據(jù)包。
然后我們用客戶端去連接它:
~/codeDir/phpCode/hyperf-skeleton#nc127.0.0.16666
此時(shí)服務(wù)端會(huì)打印出消息:
~/codeDir/phpCode/hyperf-skeleton#phpserver.php
string(17)"Client:Connect1"
tcpdump的輸出信息如下:
01:48:40.178439IPlocalhost.33933localhost.6666:Flags[S],seq43162537,win43690,options[mss65495,sackOK,TSval9833698ecr0,nop,wscale7],length0
01:48:40.178484IPlocalhost.6666localhost.33933:Flags[S.],seq1327460565,ack43162538,win43690,options[mss65495,sackOK,TSval9833698ecr9833698,nop,wscale7],length0
01:48:40.178519IPlocalhost.33933localhost.6666:Flags[.],ack1,win342,options[nop,nop,TSval9833698ecr9833698],length0
01:48:44.229926IPlocalhost.6666localhost.33933:Flags[.],ack1,win342,options[nop,nop,TSval9834104ecr9833698],length0
01:48:44.229951IPlocalhost.33933localhost.6666:Flags[.],ack1,win342,options[nop,nop,TSval9834104ecr9833698],length0
01:48:44.229926IPlocalhost.6666localhost.33933:Flags[.],ack1,win342,options[nop,nop,TSval9834104ecr9833698],length0
01:48:44.229951IPlocalhost.33933localhost.6666:Flags[.],ack1,win342,options[nop,nop,TSval9834104ecr9833698],length0
01:48:44.229926IPlocalhost.6666localhost.33933:Flags[.],ack1,win342,options[nop,nop,TSval9834104ecr9833698],length0
//省略了其他的輸出
我們會(huì)發(fā)現(xiàn)最開(kāi)始的時(shí)候,會(huì)打印三次握手的包:
01:48:40.178439IPlocalhost.33933localhost.6666:Flags[S],seq43162537,win43690,options[mss65495,sackOK,TSval9833698ecr0,nop,wscale7],length0
01:48:40.178484IPlocalhost.6666localhost.33933:Flags[S.],seq1327460565,ack43162538,win43690,options[mss65495,sackOK,TSval9833698ecr9833698,nop,wscale7],length0
01:48:40.178519IPlocalhost.33933localhost.6666:Flags[.],ack1,win342,options[nop,nop,TSval9833698ecr9833698],length0
然后,停留了4s沒(méi)有任何包的輸出。
之后,每隔1s左右就會(huì)打印出一組:
01:52:54.359341IPlocalhost.6666localhost.43101:Flags[.],ack1,win342,options[nop,nop,TSval9859144ecr9858736],length0
01:52:54.359377IPlocalhost.43101localhost.6666:Flags[.],ack1,win342,options[nop,nop,TSval9859144ecr9855887],length0
其實(shí)這就是我們配置的策略:
'tcp_keepinterval'=1,//1s探測(cè)一次
'tcp_keepcount'=5,//探測(cè)的次數(shù),超過(guò)5次后還沒(méi)有回包c(diǎn)lose此連接
因?yàn)槲覀儾僮飨到y(tǒng)底層會(huì)自動(dòng)的給客戶端回ack,所以這個(gè)連接不會(huì)在5次探測(cè)后被關(guān)閉。操作系統(tǒng)底層會(huì)持續(xù)不斷的發(fā)送這樣的一組包:
01:52:54.359341IPlocalhost.6666localhost.43101:Flags[.],ack1,win342,options[nop,nop,TSval9859144ecr9858736],length0
01:52:54.359377IPlocalhost.43101localhost.6666:Flags[.],ack1,win342,options[nop,nop,TSval9859144ecr9855887],length0
如果我們要測(cè)試5次探測(cè)后關(guān)閉這個(gè)連接,可以禁掉6666端口的包:
~/codeDir/phpCode/hyperf-skeleton#iptables-AINPUT-ptcp--dport6666-jDROP
這樣會(huì)把所有從6666端口進(jìn)來(lái)的包給禁掉,自然,服務(wù)器就接收不到從客戶端那一邊發(fā)來(lái)的ack包了。
然后服務(wù)器過(guò)5秒就會(huì)打印出close(服務(wù)端主動(dòng)的調(diào)用了close方法,給客戶端發(fā)送了FIN包):
~/codeDir/phpCode/hyperf-skeleton#phpserver.php
string(17)"Client:Connect1"
string(10)"closefd1"
我們恢復(fù)一下iptables的規(guī)則:
~/codeDir/phpCode#iptables-DINPUT-ptcp-mtcp--dport6666-jDROP
即把我們?cè)O(shè)置的規(guī)則給刪除了。
通過(guò)tcp_keepalive的方式實(shí)現(xiàn)心跳的功能,優(yōu)點(diǎn)是簡(jiǎn)單,不要寫(xiě)代碼就可以完成這個(gè)功能,并且發(fā)送的心跳包小。缺點(diǎn)是依賴于系統(tǒng)的網(wǎng)絡(luò)環(huán)境,必須保證服務(wù)器和客戶端都實(shí)現(xiàn)了這樣的功能,需要客戶端配合發(fā)心跳包。還有一個(gè)更為嚴(yán)重的缺點(diǎn)是如果客戶端和服務(wù)器不是直連的,而是通過(guò)代理來(lái)進(jìn)行連接的,例如socks5代理,它只會(huì)轉(zhuǎn)發(fā)應(yīng)用層的包,不會(huì)轉(zhuǎn)發(fā)更為底層的tcp探測(cè)包,那這個(gè)心跳功能就失效了。
所以,Swoole就提供了其他的解決方案,一組檢測(cè)死連接的配置。
'heartbeat_check_interval'=1,//1s探測(cè)一次
'heartbeat_idle_time'=5,//5s未發(fā)送數(shù)據(jù)包就close此連接
swoole實(shí)現(xiàn)的heartbeat
我們來(lái)測(cè)試一下:
$server=new\Swoole\Server('127.0.0.1',6666,SWOOLE_PROCESS);
$server-set([
'worker_num'=1,
'heartbeat_check_interval'=1,//1s探測(cè)一次
'heartbeat_idle_time'=5,//5s未發(fā)送數(shù)據(jù)包就close此連接
$server-on('connect',function($server,$fd){
var_dump("Client:Connect$fd");
$server-on('receive',function($server,$fd,$reactor_id,$data){
var_dump($data);
$server-on('close',function($server,$fd){
var_dump("closefd$fd");
$server-start();
然后啟動(dòng)服務(wù)器:
~/codeDir/phpCode/hyperf-skeleton#phpserver.php
然后啟動(dòng)tcpdump:
~/codeDir/phpCode#tcpdump-iloport6666
tcpdump:verboseoutputsuppressed,use-vor-vvforfullprotocoldecode
listeningonlo,link-typeEN10MB(Ethernet),capturesize262144bytes
然后再啟動(dòng)客戶端:
~/codeDir/phpCode/hyperf-skeleton#nc127.0.0.16666
此時(shí)服務(wù)器端打印:
~/codeDir/phpCode/hyperf-skeleton#phpserver.php
string(17)"Client:Connect1"
然后tcpdump打?。?/p>
02:48:32.516093IPlocalhost.42123localhost.6666:Flags[S],seq1088388248,win43690,options[mss65495,sackOK,TSval10193342ecr0,nop,wscale7],length0
02:48:32.516133IPlocalhost.6666localhost.42123:Flags[S.],seq80508236,ack1088388249,win43690,options[mss65495,sackOK,TSval10193342ecr10193342,nop,wscale7],length0
02:48:32.516156IPlocalhost.42123localhost.6666:Flags[.],ack1,win342,options[nop,nop,TSval10193342ecr10193342],length0
這是三次握手信息。
然后過(guò)了5s后,tcpdump會(huì)打印出:
02:48:36.985027IPlocalhost.6666localhost.42123:Flags[F.],seq1,ack1,win342,options[nop,nop,TSval10193789ecr10193342],length0
02:48:36.992172IPlocalhost.42123localhost.6666:Flags[.],ack2,win342,options[nop,nop,TSval10193790ecr10193789],length0
也就是服務(wù)端發(fā)送了FIN包。因?yàn)榭蛻舳藳](méi)有發(fā)送數(shù)據(jù),所以Swoole關(guān)閉了連接。
然后服務(wù)器端會(huì)打印:
~/codeDir/phpCode/hyperf-skeleton#phpserver.php
string(17)"Client:Connect1"
string(10)"closefd1"
所以,heartbeat和tcpkeepalive還是有一定的區(qū)別的,tcpkeepalive有?;钸B接的功能,但是heartbeat存粹是檢測(cè)沒(méi)有數(shù)據(jù)的連接,然后關(guān)閉它,并且只可以在服務(wù)端這邊配置,如果需要保活,也可以讓客戶端配合發(fā)送心跳。
如果我們不想讓服務(wù)端close掉連接,那么就得在應(yīng)用層里面不斷的發(fā)送數(shù)據(jù)包來(lái)進(jìn)行保活,例如我在nc客戶端里面不斷的發(fā)送包:
~/codeDir/phpCode/hyperf-skeleton#nc127.0.0.16666
ping
ping
ping
ping
ping
ping
ping
ping
ping
我發(fā)送了9個(gè)ping包給服務(wù)器,tcpdump的輸出如下:
//省略了三次握手的包
02:57:53.697363IPlocalhost.44195localhost.6666:Flags[P.],seq1:6,ack1,win342,options[nop,nop,TSval10249525ecr10249307],length5
02:57:53.697390IPlocalhost.6666localhost.44195:Flags[.],ack6,win342,options[nop,nop,TSval10249525ecr10249525],length0
02:57:55.309532IPlocalhost.44195localhost.6666:Flags[P.],seq6:11,ack1,win342,options[nop,nop,TSval10249686ecr10249525],length5
02:57:55.309576IPlocalhost.6666localhost.44195:Flags[.],ack11,win342,options[nop,nop,TSval10249686ecr10249686],length0
02:57:58.395206IPlocalhost.44195localhost.6666:Flags[P.],seq11:16,ack1,win342,options[nop,nop,TSval10249994ecr10249686],length5
02:57:58.395239IPlocalhost.6666localhost.44195:Flags[.],ack16,win342,options[nop,nop,TSval10249994ecr10249994],length0
02:58:01.858094IPlocalhost.44195localhost.6666:Flags[P.],seq16:21,ack1,win342,options[nop,nop,TSval10250341ecr10249994],length5
02:58:01.858126IPlocalhost.6666localhost.44195:Flags[.],ack21,win342,options[nop,nop,TSval10250341ecr10250341],length0
02:58:04.132584IPlocalhost.44195localhost.6666:Flags[P.],seq21:26,ack1,win342,options[nop,nop,TSval10250568ecr10250341],length5
02:58:04.132609IPlocalhost.6666localhost.44195:Flags[.],ack26,win342,options[nop,nop,TSval10250568ecr10250568],length0
02:58:05.895704IPlocalhost.44195localhost.6666:Flags[P.],seq26:31,ack1,win342,options[nop,nop,TSval10250744ecr10250568],length5
02:58:05.895728IPlocalhost.6666localhost.44195:Flags[.],ack31,win342,options[nop,nop,TSval10250744ecr10250744],length0
02:58:07.150265IPlocalhost.44195localhost.6666:Flags[P.],seq31:36,ack1,win342,options[nop,nop,TSval10250870ecr10250744],length5
02:58:07.150288IPlocalhost.6666localhost.44195:Flags[.],ack36,win342,options[nop,nop,TSval10250870ecr10250870],length0
02:58:08.349124IPlocalhost.44195localhost.6666:Flags[P.],seq36:41,ack1,win342,options[nop,nop,TSval10250990ecr10250870],length5
02:58:08.349156IPlocalhost.6666localhost.44195:Flags[.],ack41,win342,options[nop,nop,TSval10250990ecr10250990],length0
02:58:09.906223IPlocalhost.44195localhost.6666:Flags[P.],seq41:46,ack1,win342,options[nop,nop,TSval10251145ecr10250990],length5
02:58:09.906247IPlocalhost.6666localhost.44195:Flags[.],ack46,win342,options[nop,nop,TSval10251145ecr10251145],length0
有9組數(shù)據(jù)包的發(fā)送。(這里的Flags[P.]代表Push的含義)
此時(shí)服務(wù)器還沒(méi)有close掉連接,實(shí)現(xiàn)了客戶端?;钸B接的功能。然后我們停止發(fā)送ping,過(guò)了5秒后tcpdump就會(huì)輸出一組:
02:58:14.811761IPlocalhost.6666localhost.44195:Flags[F.],seq1,ack46,win342,options[nop,nop,TSval10251636ecr10251145],length0
02:58:14.816420IPlocalhost.44195localhost.6666:Flags[.],ack2,win342,options[nop,nop,TSval10251637ecr10251636],length0
服務(wù)端那邊發(fā)送了FIN包,說(shuō)明服務(wù)端close掉了連接。服務(wù)端的輸出如下:
~/codeDir/phpCode/hyperf-sk
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 中學(xué)教師職稱晉升制度
- 企業(yè)員工培訓(xùn)與素質(zhì)拓展訓(xùn)練制度
- 交通宣傳教育材料制作與發(fā)放制度
- 2026年工程監(jiān)理員工程質(zhì)量控制與安全管理試題
- 2026年全科醫(yī)師規(guī)范化培訓(xùn)結(jié)業(yè)考試醫(yī)學(xué)診斷技能題
- 鑄造培訓(xùn)課件范文
- 昆蟲(chóng)標(biāo)本鑒定服務(wù)合同
- 古對(duì)今課件練習(xí)題
- 2026適應(yīng)氣候變化從業(yè)人員指南:自然環(huán)境風(fēng)險(xiǎn)與解決方案-
- 2024年靈璧縣幼兒園教師招教考試備考題庫(kù)帶答案解析(奪冠)
- 經(jīng)銷商會(huì)議總結(jié)模版
- 兩癌預(yù)防知識(shí)講座
- 用電安全隱患檢測(cè)的新技術(shù)及應(yīng)用
- 新疆克州阿合奇縣2024-2025學(xué)年七年級(jí)上學(xué)期期末質(zhì)量檢測(cè)英語(yǔ)試卷(含答案及聽(tīng)力原文無(wú)音頻)
- 《水庫(kù)泥沙淤積及影響評(píng)估技術(shù)規(guī)范》
- 2023-2024學(xué)年浙江省杭州市西湖區(qū)教科版五年級(jí)上冊(cè)期末考試科學(xué)試卷
- GB/T 7948-2024滑動(dòng)軸承塑料軸套極限PV試驗(yàn)方法
- DL∕T 1057-2023 自動(dòng)跟蹤補(bǔ)償消弧線圈成套裝置技術(shù)條件
- AQ 2003-2018 軋鋼安全規(guī)程(正式版)
- 村委會(huì)指定監(jiān)護(hù)人證明書(shū)模板
- 送給業(yè)主禮物方案
評(píng)論
0/150
提交評(píng)論