Closed lincepro closed 3 weeks ago
添加断线重连代码即可
参考 MySQL server has gone away ,添加断线重连代码
解决办法:
Try to reconnect to the database. reference
最佳的方案是进行断线重连
添加断线重连代码即可
参考 MySQL server has gone away ,添加断线重连代码
解决办法:
Try to reconnect to the database. reference
- MySQL server has gone away - how to deal with it #4131 (comment)
- Swoole 4.2.3 Task中使用协程MySQL报错 #2041
- https://github.com/swoole/swoole-wiki/blob/master/doc/15.11%20-%20MySQL%E7%9A%84%E8%BF%9E%E6%8E%A5%E6%B1%A0%E3%80%81%E5%BC%82%E6%AD%A5%E3%80%81%E6%96%AD%E7%BA%BF%E9%87%8D%E8%BF%9E.md
- PDOPool does not reconnect on connection timeout. #4141
- php8.2版本 swoole 5.0.3 使用mysqlipool 会报错 mysql server has gone away in @swoole/library/core/Database/MysqliProxy.php(51) #5143
最佳的方案是进行断线重连
无法捕获异常,如何知道断线了呢? pdo断线了会抛出 PDOEXCEPTION
执行sql 之前,需要判断 $conn
是否有效
$reconnect_count=0
A:
$conn = $obj->connect("host=postgres port=5432 dbname=postges user=postgres password=postgres", 3);
if (!$conn) {
var_dump($pg->error);
$reconnect_count++
if($reconnect_count<4){
goto A;
}
return;
}
或者用Swoole\Database\PDOPool
代替PostgreSQL协程客户端,这里已经封装了断线重连的逻辑了
执行sql 之前,需要判断
$conn
是否有效
$conn当然是有效的, 第一次的sql都能正常执行,是等了30秒后的第二次sql执行出问题
或者用Swoole\Database\PDOPool代替PostgreSQL协程客户端,这里已经封装了断线重连的逻辑了
Coroutine\PostgreSQL 之后是不再维护了么? 我们线上客户环境都没有安装pdo_pgsql扩展 另外这个真的不是断线重连的问题,只要抛出异常让用户知道故障了就行
或者你可以判断$stmt = $obj->query('SELECT 1');
是不是返回false,是的话将$obj->error
作为错误信息返回出去
或者你可以判断
$stmt = $obj->query('SELECT 1');
是不是返回false,是的话将$obj->error
作为错误信息返回出去
漏说了一句, 因为我有注册 set_error_handler, 这个注册的函数能拿到这个错误: Swoole\Coroutine\PostgreSQL::query(): swoole_event_del failed
但是try catch 却捕获不到, 导致断线之后想在局部捕获都捕获不了,一定会抛给全局的错误处理函数
Swoole\Coroutine\PostgreSQL::query(): swoole_event_del failed
这个错误它不是异常来的,是swoole
内核直接将错误信息写入终端
需要检查 query 方法的返回值是不是 false,并获取错误码。据此实现断线重连
建议使用 pdo_pgsql + Runtime Hook, Swoole\Coroutine\PostgreSQL
已废弃了
Please answer these questions before submitting your issue.
use Swoole\Coroutine; use Swoole\Coroutine\System;
Coroutine\run(function () { Coroutine::create(function () { $obj = new Coroutine\PostgreSQL; $conn = $obj->connect("host=postgres port=5432 dbname=postges user=postgres password=postgres", 3); $stmt = $obj->query('SELECT 1');
});