欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > php redis session 多DB操作时异常记录

php redis session 多DB操作时异常记录

2024/10/24 17:24:07 来源:https://blog.csdn.net/lqb3732842/article/details/142064563  浏览:    关键词:php redis session 多DB操作时异常记录

php redis session 多DB 操作异常记录

背景:某个TP项目使用redis 保存session,同时redis 内也保存了其他缓存数据,为了区分session 数据跟缓存数据,项目将session 数据保存于DB 0,缓存数据保存于其他DB;

问题:某些情况下会出现登录过期异常,但是手动查询redis 相关session 是存在的,情况不是经常出现,测试手动测试时并不会异常…

追踪:通过日志记录发现,当并发较高容易出现系统读取session 为空,但是session 链接是正常的,前缀参数等也是正确的,但是就是没有数据.经过多次异常数据调查发现,本应该存储缓存数据的其他 DB也会有可能产生session 数据.

问题点:通过追踪框架代码,发现redis session 驱动底层用的是pconnect, 并且当DB配置为0时 是不会触发修改DB的操作,代码如下

    public function open($savePath, $sessName){// 检测php环境if (!extension_loaded('redis')) {throw new Exception('not support:redis');}$this->handler = new \Redis;// 建立连接$func = $this->config['persistent'] ? 'pconnect' : 'connect';$this->handler->$func($this->config['host'], $this->config['port'], $this->config['timeout']);if ('' != $this->config['password']) {$this->handler->auth($this->config['password']);}//选择数据库DBif (0 != $this->config['select']) {$this->handler->select($this->config['select']);}return true;}

这样可能高并发下FPM复用了之前线程一个redis链接,并且这个链接在上个任务中已经被select DB 1 了,在当前任务重由于配置session DB 为0 导致不会触发 select DB 操作,最后导致部分session读取或者写入到DB 1 去了
解决:
1:在上面驱动代码选择DB 处,每次都重新选择DB,如下

//选择数据库DB
if (isset($this->config['select'])&&is_numeric($this->config['select'])) {$this->handler->select($this->config['select']);}

2:使用短链接方式链接redis,及配置中 persistent 项填flase,用connect 方式链接redis而不是pconnect 方式

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com