文档章节

关于数据库断线重连的一点点思考

dubox
 dubox
发布于 08/31 21:48
字数 751
阅读 30
收藏 0

最近在写数据库链接池,一个不可逃避的问题就是数据库断线重连。 查了很多资料,因为公司有很多项目用了 TP5 于是也去看了它的源码。

tp5的实现其实很简单,配置了一些数据库连接相关的错误信息关键词(句),然后在执行语句时 catch 异常信息进行比对:

// 服务器断线标识字符
    protected $breakMatchStr = [
        'server has gone away',
        'no connection to the server',
        'Lost connection',
        'is dead or not enabled',
        'Error while sending',
        'decryption failed or bad record mac',
        'server closed the connection unexpectedly',
        'SSL connection has been closed unexpectedly',
        'Error writing data to the connection',
        'Resource deadlock avoided',
        'failed with errno',
    ];
catch (\PDOException $e) {
            if ($this->isBreak($e)) {
                return $this->close()->query($sql, $bind, $master, $pdo);
            }
            throw new PDOException($e, $this->config, $this->getLastsql());
        }
protected function isBreak($e): bool
    {
        if (!$this->config['break_reconnect']) {
            return false;
        }
        $error = $e->getMessage();
        foreach ($this->breakMatchStr as $msg) {
            if (false !== stripos($error, $msg)) {
                return true;
            }
        }
        return false;
    }

(噢 突然发现5.2已经开始使用 php7新特性了)

感觉用 errMessage 没有 errCode 靠谱吧,但是用 errCode 也很头疼啊,我要搜集各种数据库的连接相关的错误码,tp5自带的那些错误信息也只是 mysql 的吧,至少没看见sqlserver 的“TCP Provider: Error code 0x2746”,我的连接池是想支持多种数据库的。。。

正在头疼的时候,突然灵光一现:

从连接池取出db连接对象时,先执行一句类似“select 1”这样的非常简单、不会有语法错误、与业务无关(表无关、字段无关。。。) 的语句,如果报错则理论上证明即使不是连接问题 它也已经不能正常执行业务SQL了,再加一个重连次数限制,防止特殊情况下有可能发生的死循环。。。应该就完美了。。。

/**
     * 检查 db连接对象 是否可用, 主要针对断线重连
     * @param $dbKey
     * @return bool
     */
    static private function _check($dbKey)
    {
        try {
            self::$dbUsing[$dbKey]->check();
        } catch (\Exception $e) {
            return false;
        }
        return true;
    }
function check(){
        $this->prepare('select 1');
        return $this->execute();
    }

还有一种思路是做“心跳”检查,定时把连接池里的对象“请”出来“遛”一下,使其保持“活力”。。。但是这个和断线重连并不冲突,可以叠加使用,效果更好。。。


另:在测试中发现,mysql 好像可以自动重连具体表现为:在一个断开的 pdo连接对象执行第一句sql 时 catch 了异常并让代码继续执行,则后面的 sql 就可以执行成功。

我在网上没有查到这一行为相关资料,所以不确定它与 pdo 有关或是 mysql 的功能 又是否跟mysql版本有关。。。

© 著作权归作者所有

共有 人打赏支持
dubox
粉丝 3
博文 94
码字总数 27160
作品 0
西安
程序员
私信 提问
基于NIO的消息路由的实现(七)客户端的一些实现,维持链路,断线重连

一、客户端代码存在的必要性以及我认为需要解决的问题 就NIO通讯本身而言完全没必要分开,其实客户端代码和服务端代码可以放到一起。但是在业务上是分开的。我在做nio的时候思考了许多我自己...

皮鞋铮亮
2015/08/28
194
0
websocket 心跳包重连

上次我们讲过了websocket断线重连的问题,那么久会有人提出疑问了,心跳包重连跟断线重连有什么区别呢? 其实这两个都是为了达到一个目的,那就是保证当前设备的网络状态保持通畅。。。而断线...

i5--lou
2016/03/11
5.3K
4
写一个“特殊”的查询构造器 - (二、第一条语句)

构造、执行第一条语句 上一篇完成了代码结构的搭建和 PDO 的基础封装,这一篇我们来讲如何构造一个最基本的 SQL 语句,并执行得到结果。 query sql 构造目标: 查询构造器执行语法构造目标:...

MrQ被抢注了
05/11
0
0
websocket 断线重连

websocket是html5发布之后出现的一种新技术,说它是新技术,其实也不是多新的技术了,因为毕竟也有2-3年了,但是找了很多国内的实例,缺发现不多,不知道是它不好用呢,还是说这种技术原来就...

i5--lou
2016/03/09
10K
0
HPsocket Client如何实现断线重连啊?

@伤神小怪兽 你好,想跟你请教个问题: HPsocket Client如何实现断线重连啊?我使用了Client组件,启动了一个线程发送自定义心跳数据。在断线后判断状态为ST_STOPPED就一直在该线程尝试调用c...

kingdom888
2017/04/10
168
2

没有更多内容

加载失败,请刷新页面

加载更多

docker部署springboot项目

安装docker 菜鸟教程 springboot项目 maven依赖 <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001......

yimingkeji
今天
10
0
ios多个target

1.建立3个target,分别为heroone,heroone test,heroone dev;分别为正式环境,test环境,dev环境 2.注意取消掉autocreate以防止名字不对,分别以Duplicate的方式建立另外两个scheme 3.创建...

HeroHY
今天
5
0
php获取客户端IP

php获取客户端IP 首先先阅读关于IP真实性安全的文章:如何正確的取得使用者 IP? 「任何從客戶端取得的資料都是不可信任的!」 HTTP_CLIENT_IP头是有的,但未成标准,不一定服务器都实现。 ...

DrChenXX
昨天
0
0
. The valid characters are defined in RFC 7230 and RFC 问题

通过这里的回答,我们可以知道: Tomcat在 7.0.73, 8.0.39, 8.5.7 版本后,添加了对于http头的验证。 具体来说,就是添加了些规则去限制HTTP头的规范性 参考这里 具体来说: org.apache.tom...

west_coast
昨天
1
0
刷leetcode第704题-二分查找

今天双十一买的算法书到货了,路上刷到有人说的这个题,借(chao)鉴(xi)一下别人的思路,这个是C++标准库里面的经典方法,思路精巧,优雅好品味 int search(int* nums, int numsSize, in...

锟斤拷烫烫烫
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部