情景:当你接入一些物联通讯一些设备时,肯定需要接触到TCP连接,但有时会出现“开始连接正常,中途断开的连接”,具体原因无从下手。
原因:开始连接正常不做多说,断开肯定是客户端无法和服务端通讯导致的
1.tcp并发连接数(swoole->set中max_con默认值:ulimit -n,原因是某些系统设置了 ulimit -n 为 100万,也可以设置reactor_num,worker_num,max_request等参数来处理自己的业务,我这里没有遇到并发的情况,请大家谅解)
2.超出连接最大空闲(心跳时间)
上面两种原因是在下理解的,如果还有其他原因希望大家可以评论告诉我,其实我也是个小白。
第一种原因就不说了,需要根据业务处理并发,或者tcp占用内存什么就不说了,在下也不怎么会。
强烈说下第二种原因:
当一个物体和服务端连接是正常的,但是当服务端或者物体在一定的时间内没有响应就会断开连接,这就是所谓的“心跳”!!!
public $set_param = [
'reactor_num' => 4, //反应堆线程号
'worker_num' => 4, //工作进程号
'daemonize' => false, //进程守护
'max_request' => 2, //进程的最大任务数
'dispatch_mode' => 2, //数据包分发策略
'open_eof_check' => true, //打开EOF检测
'package_eof' => '##', //设置EOF
'open_eof_split' => true, //打开EOF_SPLIT检测
'package_length_type' => 'C', //长度值的类型,接受一个字符参数
'package_length_offset' => '0', //设置长度解析函数
'package_body_offset' => 4, //从第几个字节开始计算长度
'heartbeat_idle_time' => 600, // 表示一个连接如:600秒内未向服务器发送任何数据,此连接将被强制关闭
'heartbeat_check_interval' => 10, // 表示如:每10秒遍历一次
];
public function __construct() {
$this->serv = new \swoole_server('0.0.0.0', $this->port);
$this->serv->set($this->set_param);
$this->serv->on('Start',[$this,'OnStart']);
$this->serv->on('Connect',[$this,'OnConnect']);
$this->serv->on('Receive',[$this,'OnReceive']);
$this->serv->on('Close',[$this,'OnClose']);
$this->serv->start();
}
就像这样,需要set一堆参数,其中“heartbeat_idle_time,heartbeat_check_interval”需要配合使用,文档连接:swoole文档-heartbeat_idle_time,设置“heartbeat_idle_time”超出600秒才会断开,否则物体在30秒说着是50秒没有接收到响应就不会出现断开的情况了。
网上有一种方式是这样的:
sysctl -a |grep keepalive
发现为默认的配置:
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
永久生效,编辑/etc/sysctl.conf,新增或修改为
net.ipv4.tcp_keepalive_time = 200
根据业务自定。
网友评论