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

前端之家收集整理的这篇文章主要介绍了详解PHP使用Redis存储session时的一个Warning定位前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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里面

PHP;"> [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扩展文件中出错提示

//是否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),"",0 TSRMLS_CC);
  }
}


//看出错<a href="https://www.jb51.cc/tag/tishi/" target="_blank" class="keywords">提示</a>语在这里
if (ret == FAILURE) {
  <a href="https://www.jb51.cc/tag/PHP/" target="_blank" class="keywords">PHP</a>_error_docref(NULL TSRMLS_CC,E_WARNING,"<a href="https://www.jb51.cc/tag/Failed/" target="_blank" class="keywords">Failed</a> 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

这里<a href="https://www.jb51.cc/tag/diaoyong/" target="_blank" class="keywords">调用</a>...
<a href="https://www.jb51.cc/tag/PHP/" target="_blank" class="keywords">PHP</a>_session_save_current_state

}

下面两个函数调用PHP_session_flush()

PHP;"> 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:

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

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

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

系统内存状态:

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

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。

如下:

/dev/null 2>&1 ##check_redis.tag.1

查看脚本内容

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重启。

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

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

原文链接:https://www.f2er.com/php/17187.html

猜你在找的PHP相关文章