首页 > 技术分享 > Swoole
收藏

Swoole异步MySQL连接超时,Swoole的HTTP服务实现心跳检测机制

10/22 16:20
大潇博客 原创文章,转载请标明出处

在PHP中,访问MySQL数据库往往是性能提升的瓶颈。而MySQL连接池我想大家都不陌生,这是一个很好的提升数据库访问性能的方式。传统的MySQL连接池,是预先申请一定数量的连接,每一个新的请求都会占用其中一个连接,请求结束后再将连接放回池中,如果所有连接都被占用,新来的连接则会进入等待状态。


知道了MySQL连接池的实现原理,那我们来看如何使用Swoole实现一个连接池。
首先,Swoole允许开启一定量的Task Worker进程,我们可以让每个进程都拥有一个MySQL连接,并保持这个连接,这样,我们就创建了一个连接池。
其次,设置swoole的dispatch_mode为抢占模式(主进程会根据Worker的忙闲状态选择投递,只会投递给处于闲置状态的Worker)。这样,每个task都会被投递给闲置的Task Worker。这样,我们保证了每个新的task都会被闲置的Task Worker处理,如果全部Task Worker都被占用,则会进入等待队列。


mysql连接默认等待时间(wait_timeout)是28800秒(8个小时),也就是说客户端建立一个连接,没有主动断开连接,也没有任何操作,MySQL会在到达设置的wait_timeout后断开这个连接。

问题由此产生,如果使用Swoole异步处理数据,长时间未发送数据给Swoole服务端,那么这个来连接就可能因超过wait_timeout等待时间而被MySQL强制关闭。


解决此问题,Swoole内置了心跳检测功能,而开启心跳检测功能,只需要设置heartbeat_check_interval和heartbeat_idle_time即可。

'heartbeat_idle_time' => 60, // 表示一个连接如果600秒内未向服务器发送任何数据,此连接将被强制关闭
'heartbeat_check_interval' => 10 // 表示每60秒遍历一次


但心跳检测功能仅支持TCP服务,这些参数对HTTP服务无效,所以最好的办法是手动创建一个心跳检测机制。


远离比较简单,做一个定时器,定时发送请求,保持MySQL连接,在启动Swoole的时候,同时启动定时器。

定时器要单独开启一个进程,否则会和单前的HTTP服务器冲突,并发出警告:

PHP Warning: Swoole\Server::start(): eventLoop has already been created, unable to start Swoole\Http\Server


正确做法:

use Swoole\Process;

$http = new Swoole\Http\Server("0.0.0.0", 9501);

//创建 子进程

$process = new Process(function () {

//默认定时器在执行回调函数时会自动创建协程

Swoole\Timer::tick(2000, function (int $timer_id) { //单位:毫秒

echo "coro-----1 " . Coroutine::getcid() . " start\n";

});

});

$http->addProcess($process);


时间原因,先记录这些。

参考文章:

https://blog.csdn.net/sunrj_niu/article/details/129706148

https://blog.csdn.net/weixin_33923762/article/details/92145939

https://developer.aliyun.com/article/1547450


打赏

阅读排行

大家都在搜

博客维护不易,感谢你的肯定
扫码打赏,建议金额1-10元
  • 15601023311