日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解PHP Swoole長連接常見問題

瀏覽:239日期:2022-09-07 10:53:49
目錄連接失效問題如何解決如何維持長連接結論連接失效問題

例子

其中,Redis常見的報錯就是:

配置項:timeout

報錯信息:

Error while reading line from the server

Redis可以配置如果客戶端經過多少秒還不給Redis服務器發送數據,那么就會把連接close掉。

MySQL常見的報錯:

配置項:wait_timeout & interactive_timeout

報錯信息:

has gone away

和Redis服務器一樣,MySQL也會定時的去清理掉沒用的連接。

如何解決

1、用的時候進行重連 。優點是簡單,缺點是面臨短連接的問題。

2、定時發送心跳維持連接(推薦)。

如何維持長連接

tcp協議中實現的tcp_keepalive

操作系統底層提供了一組tcp的keepalive配置:

tcp_keepalive_time (integer; default: 7200; since Linux 2.2)The number of seconds a connection needs to be idle before TCPbegins sending out keep-alive probes. Keep-alives are sent onlywhen the SO_KEEPALIVE socket option is enabled. The defaultvalue is 7200 seconds (2 hours). An idle connection isterminated after approximately an additional 11 minutes (9probes an interval of 75 seconds apart) when keep-alive isenabled.Note that underlying connection tracking mechanisms andapplication timeouts may be much shorter.tcp_keepalive_intvl (integer; default: 75; since Linux 2.4)The number of seconds between TCP keep-alive probes.tcp_keepalive_probes (integer; default: 9; since Linux 2.2)The maximum number of TCP keep-alive probes to send beforegiving up and killing the connection if no response is obtainedfrom the other end.8

Swoole底層把這些配置開放出來了,例如:

?php$server = new SwooleServer(’127.0.0.1’, 6666, SWOOLE_PROCESS);$server->set([’worker_num’ => 1,’open_tcp_keepalive’ => 1,’tcp_keepidle’ => 4, // 對應tcp_keepalive_time’tcp_keepinterval’ => 1, // 對應tcp_keepalive_intvl’tcp_keepcount’ => 5, // 對應tcp_keepalive_probes]);

其中:

’open_tcp_keepalive’ => 1, // 總開關,用來開啟tcp_keepalive’tcp_keepidle’ => 4, // 4s沒有數據傳輸就進行檢測// 檢測的策略如下:’tcp_keepinterval’ => 1, // 1s探測一次,即每隔1s給客戶端發一個包(然后客戶端可能會回一個ack的包,如果服務端收到了這個ack包,那么說明這個連接是活著的)’tcp_keepcount’ => 5, // 探測的次數,超過5次后客戶端還沒有回ack包,那么close此連接

我們來實戰測試體驗一下,服務端腳本如下:

<?php$server = new SwooleServer(’127.0.0.1’, 6666, SWOOLE_PROCESS);$server->set([’worker_num’ => 1,’open_tcp_keepalive’ => 1, // 開啟tcp_keepalive’tcp_keepidle’ => 4, // 4s沒有數據傳輸就進行檢測’tcp_keepinterval’ => 1, // 1s探測一次’tcp_keepcount’ => 5, // 探測的次數,超過5次后還沒有回包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('close fd $fd');});$server->start();

我們啟動這個服務器:

~/codeDir/phpCode/hyperf-skeleton # php server.php

然后通過tcpdump進行抓包:

~/codeDir/phpCode/hyperf-skeleton # tcpdump -i lo port 6666tcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes

我們此時正在監聽lo上的6666端口的數據包。

然后我們用客戶端去連接它:

~/codeDir/phpCode/hyperf-skeleton # nc 127.0.0.1 6666

此時服務端會打印出消息:

~/codeDir/phpCode/hyperf-skeleton # php server.php

string(17) 'Client: Connect 1'

tcpdump的輸出信息如下:

01:48:40.178439 IP localhost.33933 > localhost.6666: Flags [S], seq 43162537, win 43690, options [mss 65495,sackOK,TS val 9833698 ecr 0,nop,wscale 7], length 0

01:48:40.178484 IP localhost.6666 > localhost.33933: Flags [S.], seq 1327460565, ack 43162538, win 43690, options [mss 65495,sackOK,TS val 9833698 ecr 9833698,nop,wscale 7], length 0

01:48:40.178519 IP localhost.33933 > localhost.6666: Flags [.], ack 1, win 342, options [nop,nop,TS val 9833698 ecr 9833698], length 0

01:48:44.229926 IP localhost.6666 > localhost.33933: Flags [.], ack 1, win 342, options [nop,nop,TS val 9834104 ecr 9833698], length 0

01:48:44.229951 IP localhost.33933 > localhost.6666: Flags [.], ack 1, win 342, options [nop,nop,TS val 9834104 ecr 9833698], length 0

01:48:44.229926 IP localhost.6666 > localhost.33933: Flags [.], ack 1, win 342, options [nop,nop,TS val 9834104 ecr 9833698], length 0

01:48:44.229951 IP localhost.33933 > localhost.6666: Flags [.], ack 1, win 342, options [nop,nop,TS val 9834104 ecr 9833698], length 0

01:48:44.229926 IP localhost.6666 > localhost.33933: Flags [.], ack 1, win 342, options [nop,nop,TS val 9834104 ecr 9833698], length 0

// 省略了其他的輸出

我們會發現最開始的時候,會打印三次握手的包:

01:48:40.178439 IP localhost.33933 > localhost.6666: Flags [S], seq 43162537, win 43690, options [mss 65495,sackOK,TS val 9833698 ecr 0,nop,wscale 7], length 0

01:48:40.178484 IP localhost.6666 > localhost.33933: Flags [S.], seq 1327460565, ack 43162538, win 43690, options [mss 65495,sackOK,TS val 9833698 ecr 9833698,nop,wscale 7], length 0

01:48:40.178519 IP localhost.33933 > localhost.6666: Flags [.], ack 1, win 342, options [nop,nop,TS val 9833698 ecr 9833698], length 0

然后,停留了4s沒有任何包的輸出。

之后,每隔1s左右就會打印出一組:

01:52:54.359341 IP localhost.6666 > localhost.43101: Flags [.], ack 1, win 342, options [nop,nop,TS val 9859144 ecr 9858736], length 0

01:52:54.359377 IP localhost.43101 > localhost.6666: Flags [.], ack 1, win 342, options [nop,nop,TS val 9859144 ecr 9855887], length 0

其實這就是我們配置的策略:

’tcp_keepinterval’ => 1, // 1s探測一次’tcp_keepcount’ => 5, // 探測的次數,超過5次后還沒有回包close此連接

因為我們操作系統底層會自動的給客戶端回ack,所以這個連接不會在5次探測后被關閉。操作系統底層會持續不斷的發送這樣的一組包:

01:52:54.359341 IP localhost.6666 > localhost.43101: Flags [.], ack 1, win 342, options [nop,nop,TS val 9859144 ecr 9858736], length 0

01:52:54.359377 IP localhost.43101 > localhost.6666: Flags [.], ack 1, win 342, options [nop,nop,TS val 9859144 ecr 9855887], length 0

如果我們要測試5次探測后關閉這個連接,可以禁掉6666端口的包:

~/codeDir/phpCode/hyperf-skeleton # iptables -A INPUT -p tcp --dport 6666 -j DROP

這樣會把所有從6666端口進來的包給禁掉,自然,服務器就接收不到從客戶端那一邊發來的ack包了。

然后服務器過5秒就會打印出close(服務端主動的調用了close方法,給客戶端發送了FIN包):

~/codeDir/phpCode/hyperf-skeleton # php server.php

string(17) 'Client: Connect 1'

string(10) 'close fd 1'

我們恢復一下iptables的規則:

~/codeDir/phpCode # iptables -D INPUT -p tcp -m tcp --dport 6666 -j DROP

即把我們設置的規則給刪除了。

通過tcp_keepalive的方式實現心跳的功能,優點是簡單,不要寫代碼就可以完成這個功能,并且發送的心跳包小。缺點是依賴于系統的網絡環境,必須保證服務器和客戶端都實現了這樣的功能,需要客戶端配合發心跳包。還有一個更為嚴重的缺點是如果客戶端和服務器不是直連的,而是通過代理來進行連接的,例如socks5代理,它只會轉發應用層的包,不會轉發更為底層的tcp探測包,那這個心跳功能就失效了。

所以,Swoole就提供了其他的解決方案,一組檢測死連接的配置。

’heartbeat_check_interval’ => 1, // 1s探測一次’heartbeat_idle_time’ => 5, // 5s未發送數據包就close此連接

swoole實現的heartbeat

我們來測試一下:

<?php$server = new SwooleServer(’127.0.0.1’, 6666, SWOOLE_PROCESS);$server->set([’worker_num’ => 1,’heartbeat_check_interval’ => 1, // 1s探測一次’heartbeat_idle_time’ => 5, // 5s未發送數據包就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('close fd $fd');});$server->start();

然后啟動服務器:

~/codeDir/phpCode/hyperf-skeleton # php server.php

然后啟動tcpdump:

~/codeDir/phpCode # tcpdump -i lo port 6666

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes

然后再啟動客戶端:

~/codeDir/phpCode/hyperf-skeleton # nc 127.0.0.1 6666

此時服務器端打?。?/p>

~/codeDir/phpCode/hyperf-skeleton # php server.php

string(17) 'Client: Connect 1'

然后tcpdump打?。?/p>

02:48:32.516093 IP localhost.42123 > localhost.6666: Flags [S], seq 1088388248, win 43690, options [mss 65495,sackOK,TS val 10193342 ecr 0,nop,wscale 7], length 0

02:48:32.516133 IP localhost.6666 > localhost.42123: Flags [S.], seq 80508236, ack 1088388249, win 43690, options [mss 65495,sackOK,TS val 10193342 ecr 10193342,nop,wscale 7], length 0

02:48:32.516156 IP localhost.42123 > localhost.6666: Flags [.], ack 1, win 342, options [nop,nop,TS val 10193342 ecr 10193342], length 0

這是三次握手信息。

然后過了5s后,tcpdump會打印出:

02:48:36.985027 IP localhost.6666 > localhost.42123: Flags [F.], seq 1, ack 1, win 342, options [nop,nop,TS val 10193789 ecr 10193342], length 0

02:48:36.992172 IP localhost.42123 > localhost.6666: Flags [.], ack 2, win 342, options [nop,nop,TS val 10193790 ecr 10193789], length 0

也就是服務端發送了FIN包。因為客戶端沒有發送數據,所以Swoole關閉了連接。

然后服務器端會打印:

~/codeDir/phpCode/hyperf-skeleton # php server.php

string(17) 'Client: Connect 1'

string(10) 'close fd 1'

所以,heartbeat和tcp keepalive還是有一定的區別的,tcp keepalive有?;钸B接的功能,但是heartbeat存粹是檢測沒有數據的連接,然后關閉它,并且只可以在服務端這邊配置,如果需要保活,也可以讓客戶端配合發送心跳。

如果我們不想讓服務端close掉連接,那么就得在應用層里面不斷的發送數據包來進行?;?,例如我在nc客戶端里面不斷的發送包:

~/codeDir/phpCode/hyperf-skeleton # nc 127.0.0.1 6666

ping

ping

ping

ping

ping

ping

ping

ping

ping

我發送了9個ping包給服務器,tcpdump的輸出如下:

// 省略了三次握手的包

02:57:53.697363 IP localhost.44195 > localhost.6666: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 10249525 ecr 10249307], length 5

02:57:53.697390 IP localhost.6666 > localhost.44195: Flags [.], ack 6, win 342, options [nop,nop,TS val 10249525 ecr 10249525], length 0

02:57:55.309532 IP localhost.44195 > localhost.6666: Flags [P.], seq 6:11, ack 1, win 342, options [nop,nop,TS val 10249686 ecr 10249525], length 5

02:57:55.309576 IP localhost.6666 > localhost.44195: Flags [.], ack 11, win 342, options [nop,nop,TS val 10249686 ecr 10249686], length 0

02:57:58.395206 IP localhost.44195 > localhost.6666: Flags [P.], seq 11:16, ack 1, win 342, options [nop,nop,TS val 10249994 ecr 10249686], length 5

02:57:58.395239 IP localhost.6666 > localhost.44195: Flags [.], ack 16, win 342, options [nop,nop,TS val 10249994 ecr 10249994], length 0

02:58:01.858094 IP localhost.44195 > localhost.6666: Flags [P.], seq 16:21, ack 1, win 342, options [nop,nop,TS val 10250341 ecr 10249994], length 5

02:58:01.858126 IP localhost.6666 > localhost.44195: Flags [.], ack 21, win 342, options [nop,nop,TS val 10250341 ecr 10250341], length 0

02:58:04.132584 IP localhost.44195 > localhost.6666: Flags [P.], seq 21:26, ack 1, win 342, options [nop,nop,TS val 10250568 ecr 10250341], length 5

02:58:04.132609 IP localhost.6666 > localhost.44195: Flags [.], ack 26, win 342, options [nop,nop,TS val 10250568 ecr 10250568], length 0

02:58:05.895704 IP localhost.44195 > localhost.6666: Flags [P.], seq 26:31, ack 1, win 342, options [nop,nop,TS val 10250744 ecr 10250568], length 5

02:58:05.895728 IP localhost.6666 > localhost.44195: Flags [.], ack 31, win 342, options [nop,nop,TS val 10250744 ecr 10250744], length 0

02:58:07.150265 IP localhost.44195 > localhost.6666: Flags [P.], seq 31:36, ack 1, win 342, options [nop,nop,TS val 10250870 ecr 10250744], length 5

02:58:07.150288 IP localhost.6666 > localhost.44195: Flags [.], ack 36, win 342, options [nop,nop,TS val 10250870 ecr 10250870], length 0

02:58:08.349124 IP localhost.44195 > localhost.6666: Flags [P.], seq 36:41, ack 1, win 342, options [nop,nop,TS val 10250990 ecr 10250870], length 5

02:58:08.349156 IP localhost.6666 > localhost.44195: Flags [.], ack 41, win 342, options [nop,nop,TS val 10250990 ecr 10250990], length 0

02:58:09.906223 IP localhost.44195 > localhost.6666: Flags [P.], seq 41:46, ack 1, win 342, options [nop,nop,TS val 10251145 ecr 10250990], length 5

02:58:09.906247 IP localhost.6666 > localhost.44195: Flags [.], ack 46, win 342, options [nop,nop,TS val 10251145 ecr 10251145], length 0

有9組數據包的發送。(這里的Flags [P.]代表Push的含義)

此時服務器還沒有close掉連接,實現了客戶端?;钸B接的功能。然后我們停止發送ping,過了5秒后tcpdump就會輸出一組:

02:58:14.811761 IP localhost.6666 > localhost.44195: Flags [F.], seq 1, ack 46, win 342, options [nop,nop,TS val 10251636 ecr 10251145], length 002:58:14.816420 IP localhost.44195 > localhost.6666: Flags [.], ack 2, win 342, options [nop,nop,TS val 10251637 ecr 10251636], length 0服務端那邊發送了FIN包,說明服務端close掉了連接。服務端的輸出如下:

~/codeDir/phpCode/hyperf-skeleton # php server.php

string(17) 'Client: Connect 1'

string(5) 'ping

'

string(5) 'ping

'

string(5) 'ping

'

string(5) 'ping

'

string(5) 'ping

'

string(5) 'ping

'

string(5) 'ping

'

string(5) 'ping

'

string(5) 'ping

'

string(10) 'close fd 1'

然后我們在客戶端那邊ctrl + c來關閉連接:

~/codeDir/phpCode/hyperf-skeleton # nc 127.0.0.1 6666

ping

ping

ping

ping

ping

ping

ping

ping

ping

^Cpunt!

~/codeDir/phpCode/hyperf-skeleton #

此時,tcpdump的輸出如下:

03:03:02.257667 IP localhost.44195 > localhost.6666: Flags [F.], seq 46, ack 2, win 342, options [nop,nop,TS val 10280414 ecr 10251636], length 0

03:03:02.257734 IP localhost.6666 > localhost.44195: Flags [R], seq 2678621620, win 0, length 0

應用層心跳

1、制定ping/pong協議(mysql等自帶ping協議)

2、客戶端靈活的發送ping心跳包

3、服務端OnRecive檢查可用性回復pong

例如:

$server->on(’receive’, function (SwooleServer $server, $fd, $reactor_id, $data){if ($data == ’ping’){checkDB();checkServiceA();checkRedis();$server->send(’pong’);}});結論

1、tcp的keepalive最簡單,但是有兼容性問題,不夠靈活

2、swoole提供的keepalive最實用,但是需要客戶端配合,復雜度適中

3、應用層的keepalive最靈活但是最麻煩

以上就是詳解PHP Swoole長連接常見問題的詳細內容,更多關于PHP Swoole長連接常見問題的資料請關注好吧啦網其它相關文章!

標簽: PHP
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲午夜免费| 亚洲精品乱码| 久久一区欧美| 国产乱码精品一区二区三区四区 | 精品国产一区二区三区性色av| 欧美亚洲tv| 国产精品2023| 国产在线看片免费视频在线观看| 国产成人77亚洲精品www| 成人在线免费观看91| 性感美女一区二区在线观看| 欧美1区免费| 快she精品国产999| 涩涩涩久久久成人精品| 久久激情av| 久久不卡日韩美女| 精品国产午夜| 日韩精品一区二区三区免费观看| 亚洲香蕉网站| 日本大胆欧美人术艺术动态| 亚洲a成人v| 国产精品主播| 午夜久久中文| 好吊一区二区三区| 亚洲一区二区小说| 国产精品白浆| 色老板在线视频一区二区| 午夜欧美精品| 青青草国产精品亚洲专区无| 久久免费精品| 免费精品国产的网站免费观看| 欧美va天堂| 日韩精品免费观看视频| 久久97视频| 999精品色在线播放| 久久亚洲色图| 国产精品hd| 久久天堂精品| 亚洲九九精品| 日本久久综合| 免费人成精品欧美精品| 国产剧情一区| 欧美日韩中文一区二区| 日韩精品一区二区三区中文字幕| 国产精品一国产精品k频道56| 亚洲啊v在线| 麻豆精品网站| 欧美精品二区| 性欧美精品高清| 九九99久久精品在免费线bt| 激情欧美一区| 欧美三级第一页| 久久久人人人| 青青青国产精品| 韩国精品主播一区二区在线观看 | 国产精品亚洲欧美| 亚洲伦乱视频| 青草国产精品| 激情综合自拍| 国产精品对白| 香蕉久久国产| 成人亚洲欧美| 欧美日韩一区二区三区四区在线观看| 九九精品调教| 国产欧美日韩精品一区二区免费 | 国产成人精品一区二区三区视频 | 欧美在线首页| 亚洲精品电影| 国产a久久精品一区二区三区| 丝袜美腿亚洲色图| 日韩av专区| 国产亚洲第一伦理第一区| 午夜日韩在线| 中文字幕在线免费观看视频| 欧美亚洲自偷自偷| 久久国产精品毛片| 欧美三区四区| 国产精品丝袜在线播放| 亚洲中字黄色| 久久亚洲国产| 精品国产网站| 青青在线精品| 免费在线看一区| 精品成人免费一区二区在线播放| 国产日产高清欧美一区二区三区| 玖玖玖国产精品| 99久久www免费| 另类欧美日韩国产在线| 视频一区二区三区在线| 婷婷成人综合| 亚洲午夜天堂| 国产一区二区视频在线看| 国产欧美一区二区精品久久久 | 欧美aa在线视频| 亚洲精品成a人ⅴ香蕉片| 欧洲激情综合| 久久麻豆精品| 日韩免费视频| 最新中文字幕在线播放 | 国产美女亚洲精品7777| 亚洲精品黄色| 蜜桃久久av| 伊人影院久久| 国内精品福利| 岛国精品一区| 欧美国产精品| 国产精品白丝一区二区三区| 日韩av一区二区三区四区| 综合亚洲视频| 视频一区欧美精品| 美女精品在线| 羞羞答答国产精品www一本| 欧美午夜不卡| 亚洲精品电影| 婷婷综合五月| 99pao成人国产永久免费视频| 久久高清精品| 激情五月色综合国产精品| 美女网站一区| 精品一区在线| 日韩一区二区久久| 久久大逼视频| 亚洲视频国产精品| 亚洲三级毛片| 日本午夜精品视频在线观看| 青青草精品视频| 国产欧美亚洲一区| 国产精品草草| 精品国产精品久久一区免费式| 免费看一区二区三区| 久久久精品区| a日韩av网址| 99久久夜色精品国产亚洲1000部| 91精品国产乱码久久久久久久 | 亚洲性视频h| 日韩视频一区| 亚洲另类av| 国产乱码精品一区二区三区亚洲人| 国产精品v日韩精品v欧美精品网站| 麻豆视频观看网址久久| a国产在线视频| 韩国精品主播一区二区在线观看 | 成人精品高清在线视频| 成人福利视频| 激情五月综合网| 在线观看亚洲精品福利片| 99视频+国产日韩欧美| 日韩精品一二三四| 日本亚洲最大的色成网站www| 日本va欧美va精品发布| 国产精品日韩精品中文字幕| 九九99久久精品在免费线bt| 成人日韩在线观看| 黄色国产精品| 日本伊人午夜精品| 久久天堂影院| 国精品一区二区三区| 亚洲三级视频| 久久一区精品| 欧美粗暴jizz性欧美20| 天海翼亚洲一区二区三区| 天堂va欧美ⅴa亚洲va一国产| 美腿丝袜亚洲一区| av高清一区| 最新国产精品视频| 欧美精品二区| 亚洲二区免费| 婷婷五月色综合香五月| 大香伊人久久精品一区二区| 欧美一区三区| 日韩av一区二区在线影视| 精品国产18久久久久久二百| 91精品电影| 久久国产生活片100| 久久精品国产大片免费观看| 视频一区二区中文字幕| 91精品国产自产在线丝袜啪| 黑人精品一区| 午夜亚洲福利| 日韩精品首页| 日韩综合小视频| 日韩在线短视频| 日韩欧美中文字幕在线视频| 欧美国产小视频| 免费成人性网站| 国产a亚洲精品| 久久国产精品久久久久久电车| 国产日本亚洲| 国产精品91一区二区三区| 国产乱人伦精品一区| 成人久久久久| 中文字幕日韩欧美精品高清在线| 国产夫妻在线| 日韩av一二三| 亚洲电影在线一区二区三区| 久久精品国产久精国产爱| 石原莉奈在线亚洲三区| 麻豆理论在线观看| 久久国产三级| 久久福利影视|