织梦session失效频繁解决
现象描述
织梦后台管理员或前台会员登录后,短时间内(几分钟到十几分钟)自动掉线,需反复登录。有时操作中途Session丢失导致表单数据丢失,严重影响使用体验。此问题多发于虚拟主机、集群部署或PHP 7+环境。
常见原因分析
- Session存储目录无写权限:PHP默认把Session存于
/tmp,若该目录不可写或被定期清理,Session文件丢失。 - Session.gc_maxlifetime过短:PHP垃圾回收机制定期清理过期Session,若该值设置过小(如1440秒=24分钟),空闲即被清。
- 多服务器Session不共享:负载均衡下,请求被分发到不同服务器,各服务器Session独立,导致登录态丢失。
- Cookie域不匹配:跨子域名访问时Cookie未共享,每次跳转都生成新Session。
- session.save_path配置错误:路径不存在或磁盘满,Session写入失败。
解决方案一:调整PHP配置
修改php.ini,增大Session存活时间:
session.save_path="/tmp/sessions" ; 指定独立目录 session.gc_maxlifetime=86400 ; Session存活24小时 session.cookie_lifetime=86400 ; Cookie存活24小时 session.gc_probability=1 session.gc_divisor=1000 ; 垃圾回收概率0.1%
修改后创建Session目录并赋权:
mkdir /tmp/sessions chmod 777 /tmp/sessions
重启PHP-FPM使配置生效。
/include/common.inc.php开头用ini_set动态设置,但需在session_start()之前调用。解决方案二:自定义Session存储目录
在/include/common.inc.php中session_start()之前加入:
// 在织梦data目录下建sessions文件夹
$sessionPath=DEDEDATA.'/sessions';
if(!is_dir($sessionPath)){
@mkdir($sessionPath, 0777, true);
}
session_save_path($sessionPath);
ini_set('session.gc_maxlifetime', 86400);
ini_set('session.cookie_lifetime', 86400);
session_start();
这样Session存于网站目录内,不受服务器/tmp清理影响,迁移时也一并带走。
解决方案三:改用Redis存储Session
集群部署或多服务器场景下,把Session统一存Redis,所有节点共享:
修改php.ini:
session.save_handler=redis session.save_path="tcp://127.0.0.1:6379?auth=yourpassword&database=1" session.gc_maxlifetime=86400
或在代码中动态设置:
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');
session_start();
需安装PHP的redis扩展(php-redis)。Redis存储的Session天然支持过期,且读取速度快。
方案四:Cookie域配置
跨子域名掉线问题,需让Cookie在所有子域名生效:
session_set_cookie_params(86400, '/', '.example.com'); session_start();
注意.example.com前的点号,表示www.example.com、m.example.com等子域名共享。
排查步骤
1. 检查Session是否写入成功
登录后查看Session目录是否有新文件生成:
ls -la /tmp/sessions/
若无新文件,是写权限或路径问题。
2. 查看PHP错误日志
tail -f /var/log/php-fpm/error.log # 或织梦日志 tail -f /data/logs/*.log
搜session关键字,看是否有"Failed to write session data"等错误。
3. 打印Session ID
在不同页面输出session_id(),若每次不同说明Cookie未携带,是Cookie域或HTTPS问题。
织梦特有的Session问题
后台验证码频繁失效
后台登录验证码基于Session,若Session失效会提示验证码错误。在/include/vdimgck.php中检查Session写入是否正常。
CSRF token失效
织梦后台表单有token校验,存于Session。Session丢失会报"数据校验不对"。可在/dede/config.php中调整token有效期。
fastcgi_cache,可能缓存了带Session的页面,需排除登录态请求。长期运维建议
建议把Session存储从文件切换到Redis/Memcached,不仅能根治掉线问题,还能为后续多服务器扩展打好基础。同时上线Session监控,统计每日Session丢失率,发现异常及时告警。对敏感操作(如支付、改密码)额外要求二次验证,不单纯依赖Session保活。