罗田县升平网络工作室,一家专业从事网站建设的工作室

资讯论坛

 找回密码
 加入论坛

快捷登录

回帖中禁止出现的内容,违者将被直接永久禁止访问,删除ID处理 :1.违反法律法规 ,包括但不限于出现带有政治、色情、暴恐信息等内容;2.恶意攻击内容,包括但不限于:恶意攻击党和政府、辱骂跟帖者、攻击主题发布者、不服从论坛管理、挑衅管理者、挑战版规等;3.广告、推广内容,尤其出现带有病毒、恶意代码、广告链接等内容,包括但不限于:QQ号、文字QQ号、微信号、手机号、文字手机号、第三方网址、单位公司名称、网站名称等;4.回帖贴出该主题隐藏资源链接或其它主题隐藏资源链接的行为。
查看: 512|回复: 0

php之redis短线重连案例讲解

[复制链接]

653

主题

678

帖子

767

积分

社区达人

积分
767
发表于 2021-9-27 15:01:36 | 显示全部楼层 |阅读模式
php redis断线重连,pconnect连接失败问题
介绍

在swoole ,workerman等cli长连接模式下,遇到Redis异常断开,后面又开启的情况,一般得重新启动程序才能正常使用,
本文介绍在不重启服务,实现原来的Redis断线重连
原理

Redis 断开的情况下调用
  1. $Redis->ping()会触发Notice错误,Notice: Redis::ping(): send of 14 bytes failed with errno=10054
复制代码
当获取redis实例时,如果ping不通或者出现异常,就重新连接
实现1

因为try catch  捕捉不到notice异常,所以ping不通直接重新连接,catch捕捉新连接的实例没有连接上,下次执行ping触发
  1. Redis server went away 异常
复制代码
  1. public static function getInstance( )    {        try {            if (!self::$_instance) {                new self();            } else {                if (!self::$_instance->ping())                    new self();            }        } catch (\Exception $e) {            // 断线重连            new self();        }        return self::$_instance;    }
复制代码
实现2

1.调用ping之前先抛出个notice异常,
2.调用ping
3.用error_get_last获取最后一个错误,如果错误信息跟我们抛出的一样,说明ping通了,否则抛出个异常 ,让catch捕捉到执行重连,
当重连一次没连上再次调用$_instance->ping()会直接抛出Redis server went away异常让catch捕捉到
  1. public static function getInstance( )    {        if (!self::$_instance) {            new self();        }        else{            try {                @trigger_error('flag', E_USER_NOTICE);                self::$_instance->ping();                $error = error_get_last();                if($error['message'] != 'flag')                    throw new \Exception('Redis server went away');            } catch (\Exception $e) {                // 断线重连                new self();            }        }        return self::$_instance;    }
复制代码
Redis类完整代码
  1. <&#63;php  namespace lib;  class Redis{     private static $_instance; //存储对象    private function __construct( ){        $config = Config::get('redis');        self::$_instance = new \Redis();        //从配置读取        self::$_instance->pconnect($config['host'], $config['port']);        if ('' != $config['password']) {            self::$_instance->auth($config['password']);        }     }        public static function getInstance( )    {        if (!self::$_instance) {            new self();        }        else{            try {                @trigger_error('flag', E_USER_NOTICE);                self::$_instance->ping();                $error = error_get_last();                if($error['message'] != 'flag')                    throw new \Exception('Redis server went away');            } catch (\Exception $e) {                // 断线重连                new self();            }        }        return self::$_instance;    } //    public static function getInstance( )//    {//        try {//            if (!self::$_instance) {//                new self();//            } else {//                if (!self::$_instance->ping())//                    new self();//            }//        } catch (\Exception $e) {//            // 断线重连//            new self();//        }//        return self::$_instance;//    }       /**    * 禁止clone    */    private function __clone(){}     /**     * 其他方法自动调用     * @param $method     * @param $args     * @return mixed     */    public function __call($method,$args)    {        return call_user_func_array([self::$_instance, $method], $args);    }     /**     * 静态调用     * @param $method     * @param $args     * @return mixed     */    public static function __callStatic($method,$args)    {        self::getInstance();        return call_user_func_array([self::$_instance, $method], $args);    }   }
复制代码
调用
  1. $this->handler = Redis::getInstance();        $key    = $this->getCacheKey($name);        $value = $this->handler->get($key);
复制代码
补充
pconnect建立连接后重连失败问题
经测试长连接下使用pconnect建立连接后,redis超时被动断开了链接,
  1. $res = self::$_instance->pconnect($config['host'], $config['port']);
复制代码
$res 会返回true,但不是新建的链接,调用$res-get()会报错
原因
研究发现
使用pconnect,链接在php进程的整个生命周期内被重用,&#160;close的作用仅是使当前php不能再进行redis请求,但无法真正关闭redis长连接,连接在后续请求中仍然会被重用,直至fpm进程生命周期结束。
长连接中只有进程被停止,连接才会断开,所以连接断开时new不起作用,返回连接成功,而事实上已经断了,还是最早的那个连接,从而导致不能进行后续读取数据操作
所以长连接中请使用connect
到此这篇关于php之redis短线重连案例讲解的文章就介绍到这了,更多相关php之redis短线重连内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

来源:http://www.jb51.net/article/219005.htm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
打赏鼓励一下!
回复

使用道具 举报

回帖中禁止出现的内容,违者将被直接永久禁止访问,删除ID处理 :1.违反法律法规 ,包括但不限于出现带有政治、色情、暴恐信息等内容;2.恶意攻击内容,包括但不限于:恶意攻击党和政府、辱骂跟帖者、攻击主题发布者、不服从论坛管理、挑衅管理者、挑战版规等;3.广告、推广内容,尤其出现带有病毒、恶意代码、广告链接等内容,包括但不限于:QQ号、文字QQ号、微信号、手机号、文字手机号、第三方网址、单位公司名称、网站名称等;4.回帖贴出该主题隐藏资源链接或其它主题隐藏资源链接的行为。

浏览排行

(38463)2019-11-5 公共云钱包资金盘骗局揭秘: 网络传销+原始股骗局合体!

(22233)2019-12-20 12月17日 邓智天法院直播庭审疑问全解答!

(20722)2019-12-1 环保币GEC资金盘骗局最新消息: 即将崩盘!

(17244)2019-11-9 巨胸肥臀大长腿,嫩模糯美子真人COS不知火舞福利污图

(15868)2018-12-24 罗田县人民法院公布【第五批失信被执行人名单】 ...

(14972)2019-11-3 曝光!PTFX已经崩盘跑路,投资者血流成河!

(13018)2019-8-7 湖北电力网上缴费,支付宝绑定户号的初始密码是什么?

(12480)2018-10-17 罗田县人民政府“12345”市民服务热线服务指南

(11170)2019-12-11 公安定性了, 趣码是非法传销! 趣码怎么退回365元?

(11081)2019-12-15 满足你对女同事的幻想 风骚秘书阿朱销魂眼神勾魂摄魄

最新发表

[升平网络工作室]2025-8-23 [2025-08-23]罗田天气预报

[升平网络工作室]2025-8-23 西藏自治区成立60周年庆祝大会隆重举行 习近平出席大会

[升平网络工作室]2025-8-23 县委委员会召开查摆问题整改整治情况汇报会

[爱查小程序]2025-8-22 [爱查]在线听音乐操作说明

[升平网络工作室]2025-8-22 [2025-08-22]罗田天气预报

[升平网络工作室]2025-8-22 习近平率中央代表团抵达拉萨出席西藏自治区成立60周年庆祝活动

[升平网络工作室]2025-8-22 县关工委联合经济开发区开展“情系学子”助学活动 助力职工子女圆梦大学

[升平网络工作室]2025-8-21 2025年罗田县卫健系统赴高校公开招聘事业单位工作人员拟聘用人员公示公告

[升平网络工作室]2025-8-21 [2025-08-21]罗田天气预报

[升平网络工作室]2025-8-21 县安防委2025年度第三次全体(扩大)会召开

QQ|Archiver|手机版|小黑屋|资讯论坛BBS.SPW8.CN ( 鄂ICP备2021011341号-3 )|网站地图


手机扫一扫继续访问
[免责声明]
本站系本网编辑转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。
如涉及作品内容、版权和其它问题,请在30日内与本网联系,我们将在第一时间删除内容!
[声明]本站文章版权归原作者所有 内容为作者个人观点 本站只提供参考并不构成任何投资及应用建议。

进入社区 | 发表新帖 | 百度收录 |
技术提供:罗田县升平网络工作室
站长Email:admin@spw8.cn
投诉电话(刮开查看):15374567400

GMT+8, 2025-8-23 17:05 , Processed in 0.236670 second(s), 30 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表