详解PHP使用Redis存储session时的一个Warning定位

发布时间 - 2026-01-11 02:11:14    点击率:

1. 问题现象

系统页面刷新的时候,偶尔会报错下面的Warnning,但是不经常出现:

Warning: Unknown: Failed to write session data (Redis). Please verify that the current setting of session.save_path is correct (tcp://x.x.x.x:6379?auth=yyy) in Unknown on line 0

看网络有人说是redis版本的问题、但是没有具体结论,那么本着学习的态度,自己试试看看能不能捉出这个bug.

定位问题:

查看PHP文件是否有设置session的地方,发现没有

继续检查php配置文件,发现配置了session存储到redis里面

[Session]
session.save_handler = redis
session.save_path = "tcp://x.x.x.x:6379?auth=yyyy"
session.use_cookies = 1

1、继续查看php Session扩展源代码,定位出错提示语在函数php_session_save_current_state中

检查session扩展文件中出错提示:

static void php_session_save_current_state(TSRMLS_D) /* {{{ */
{
  int ret = FAILURE;

  //是否session数组
  IF_SESSION_VARS() {
    if (PS(mod_data) || PS(mod_user_implemented)) {
      char *val;
      int vallen;

     //变量编码
      val = php_session_encode(&vallen TSRMLS_CC);
      if (val) {
        //保存session数据
        ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC);
        efree(val);
      } else {
        //清空session
        ret = PS(mod)->s_write(&PS(mod_data), PS(id), "", 0 TSRMLS_CC);
      }
    }


    //看出错提示语在这里
    if (ret == FAILURE) {
      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to write session data (%s). Please "
          "verify that the current setting of session.save_path "
          "is correct (%s)",
          PS(mod)->s_name,
          PS(save_path));
    }
  }

  if (PS(mod_data) || PS(mod_user_implemented)) {
    PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);
  }
}




static void php_session_flush(TSRMLS_D){
  如果 (PS(session_status) == php_session_active)
    session_status = none

    这里调用...
    php_session_save_current_state
}

下面两个函数调用:php_session_flush()

static PHP_FUNCTION(session_write_close)
{
  php_session_flush(TSRMLS_C);
}


static PHP_FUNCTION(session_register_shutdown){

}

由上面可以看到,php_session_save_current_state是在 php_session_flush中调用,即在session保存、清空等刷新写session的时候会产生。

由php seesion源码没有发现什么问题,突然想到会不会是Redis本身有没有啥问题,导致的写出错。因而继续从redis里面找问题:

Redis问题定位

1. 首先查看Redis日志文件:

看到如下每5分钟会刷新一下如下log:

[16723] 04 Jul 15:15:01.987 # Server started, Redis version 2.8.9
[16723] 04 Jul 15:15:01.987 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
[16723] 04 Jul 15:15:01.996 * DB loaded from disk: 0.008 seconds
[16723] 04 Jul 15:15:01.996 * The server is now ready to accept connections on port 6379

怀疑这就是问题的PHP写日志失败的原因了。那么Redis为啥会5分钟重启呢?继续追查!

2. 是系统内存不够、Redis core了?

查看系统和Redis内存使用状态:

系统内存状态:

$ free -m
       total    used    free   shared  buffers   cached
Mem:     3516    3171    345     0    684    1680
-/+ buffers/cache:    806    2709
Swap:     2055    724    1330

Redis服务器占用的内存状态:

used_memory:2841648
used_memory_human:2.71M
used_memory_rss:3710976
used_memory_peak:2877576
used_memory_peak_human:2.74M
used_memory_lua:33792
mem_fragmentation_ratio:1.31
mem_allocator:jemalloc-3.2.0

可以看到Redis其实内存占用非常少。redis重启原因暂且不明。

3. 定时脚本

因为重启日志5分钟一次、非常规律,因而怀疑是不是别的原因导致Redis重启,比如定时脚本。

因为本人没有root corntab权限,找老板提权,看到赫然存在着一个crontab,5分钟监控一次redis。

如下:

/5 * * * /data/scripts/check_redis.sh >/dev/null 2>&1 ##check_redis.tag.1

查看脚本内容

PORT='6379'
ETH1_ADDR=`/sbin/ifconfig eth1 | awk -F ':' '/inet addr/{print $2}' | sed 's/[a-zA-Z ]//g'`

retval=`nmap --system-dns -sT -p ${PORT} ${ETH1_ADDR} | grep open`
if [ "${retval}X" = "X" ]; then
    /sbin/service redis restart >/dev/null 2>&1
fi

这是一个检查Redis端口是否提供服务的脚本,如果检查不成功,就拉起Redis。

可以看到这个脚本本来没有什么问题。

但是:通过手动执行这个命令发现:

这台机器没有安装nmap 这个命令,

所以这个脚本最后总是执行失败!然后Redis重启。

因为问题根源找到了,找运维安装相关命令,问题解决。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# PHP使用Redis存储session  # PHP存储session定位  # Redis 的 GeoHash详解  # 重启  # 可以看到  # 什么问题  # 清空  # 是在  # 在这里  # 这就是  # 会不会  # 这是一个  # 报错  # 拉起  # 不成功  # 即在  # 这台  # 配置文件  # 源代码  # 大家多多  # 没有安装  # 找到了  # E_WARNING 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel项目怎么部署到Linux_Laravel Nginx配置详解  C++时间戳转换成日期时间的步骤和示例代码  Java类加载基本过程详细介绍  如何挑选优质建站一级代理提升网站排名?  西安专业网站制作公司有哪些,陕西省建行官方网站?  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  怎么用AI帮你为初创公司进行市场定位分析?  如何撰写建站申请书?关键要点有哪些?  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  Laravel Admin后台管理框架推荐_Laravel快速开发后台工具  昵图网官网入口 昵图网素材平台官方入口  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  如何在不使用负向后查找的情况下匹配特定条件前的换行符  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  如何快速搭建安全的FTP站点?  如何在阿里云完成域名注册与建站?  如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】  Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】  如何用AWS免费套餐快速搭建高效网站?  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  网站制作报价单模板图片,小松挖机官方网站报价?  如何用美橙互联一键搭建多站合一网站?  详解MySQL数据库的安装与密码配置  Laravel如何配置Horizon来管理队列?(安装和使用)  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  Laravel如何升级到最新版本?(升级指南和步骤)  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  昵图网官方站入口 昵图网素材图库官网入口  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  node.js报错:Cannot find module 'ejs'的解决办法  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  JS碰撞运动实现方法详解  郑州企业网站制作公司,郑州招聘网站有哪些?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)  如何为不同团队 ID 动态生成多个“认领值班”按钮  JavaScript如何操作视频_媒体API怎么控制播放  Python函数文档自动校验_规范解析【教程】  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】  PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑  新三国志曹操传主线渭水交兵攻略  Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析