连接失效问题
例子
其中,Redis
常见的报错就是:
配置项:timeout
报错信息:Error while reading line from the server
Redis
可以配置如果客户端经过多少秒还不给Redis
服务器发送数据,那么就会把连接close
掉。
MySQL
常见的报错:
配置项:wait_timeout & interactive_timeout
报错信息:has gone away
和Redis
服务器一样,MySQL
也会定时的去清理掉没用的连接。
如何解决
1、用的时候进行重连
2、定时发送心跳维持连接
用的时候进行重连
优点是简单,缺点是面临短连接的问题。
定时发送心跳维持连接
推荐。
swoole实战直播群我的官方群677079770
操作系统底层提供了一组tcp
的keepalive
配置:
-
tcp_keepalive_time (integer; default: 7200; since Linux 2.2) The number of seconds a connection needs to be idle before TCP begins sending out keep-alive probes. Keep-alives are sent only when the SO_KEEPALIVE socket option is enabled. The default value is 7200 seconds (2 hours). An idle connection is terminated after approximately an additional 11 minutes (9 probes an interval of 75 seconds apart) when keep-alive is enabled. Note that underlying connection tracking mechanisms and application 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 before giving up and killing the connection if no response is obtained from the other end.
Swoole
底层把这些配置开放出来了,例如:
<
?php $server = new \Swoole\Server('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 \Swoole\Server('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此连接 ]);