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的操作,代码如下

c 复制代码
    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']);
        }
		//选择数据库DB
        if (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,如下

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

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

相关推荐
二宝哥27 分钟前
02.springboot项目对接国内模型实现对话聊天
数据库·人工智能·spring boot
秦时明月之君临天下1 小时前
MySQL purge 参数详解:innodb_purge_threads 与 innodb_purge_batch_size
数据库·mysql·1024程序员节
三垣网安1 小时前
某某大学心理健康教育平台弱口令及SQL注入漏洞
数据库·sql
打工仔折腾 AI1 小时前
AI Agent 工程化实战(二):5 分钟跑通 Deep Agent 并逐层拆解底层链路
java·数据库·人工智能·后端·python·langchain·ai agent 实战
Shaoshing1 小时前
MySQL视图
数据库
2401_872418781 小时前
互联网公开信息检索完全指南:Google、Yandex、Wayback Machine、DNS、WHOIS、Shodan 等 OSINT 工具大全
开发语言·php
aixingpan2 小时前
aixingpan.cnAPI开发文档:api_docs_trichart_natal_solar_return_transit2接口指南
前端·php
爱好曙光2 小时前
Redis Cluster 槽迁移:MOVED 重定向与拓扑刷新实战
redis·cluster·性能调优·moved·槽迁移
这个DBA有点耶2 小时前
测试全绿,上线三周数据没入账——那个95%的兼容度报告,漏掉的是边界
数据库·mysql·架构
1024奇点2 小时前
【仓颉语言入门 · 第二篇 第 15 课】
开发语言·数据库·ide·开源