1. 问题现象与背景分析
最近在帮客户升级禅道项目管理软件时遇到了一个典型问题:从8.2.1版本升级到12.5.3后,访问系统时浏览器反复提示"重定向次数过多"错误(ERR_TOO_MANY_REDIRECTS)。这个报错会导致用户完全无法登录系统,所有页面请求都会陷入无限循环。
禅道作为国内广泛使用的开源项目管理工具,其版本跨度较大的升级过程中常会遇到各类兼容性问题。我排查发现,这个问题主要源于新旧版本间会话管理机制的变更。在8.2.1版本中,会话信息默认存储在文件中,而12.5.3版本则强化了安全策略,默认要求使用数据库存储会话数据。当旧版会话文件与新版的会话处理逻辑冲突时,就会触发这个重定向循环。
2. 问题根因深度解析
2.1 会话存储机制变更
禅道8.x系列使用简单的文件会话存储(session.save_handler = files),所有会话数据以文件形式保存在zt/tmp/session目录下。而12.x版本为了提升性能和安全性,改为优先使用数据库存储会话(session.save_handler = user)。这种底层架构的变更导致升级后系统无法正确处理原有的会话信息。
2.2 重定向逻辑冲突
新版的安全机制会检测到异常的会话信息,并尝试通过重定向到登录页来重建会话。但由于旧会话文件仍然存在,这个检测-重定向的过程会不断循环。具体表现为:
- 浏览器请求任意页面
- 服务端检测到无效会话
- 返回302重定向到/login
- 重定向请求再次触发会话检测
- 形成无限循环
2.3 配置参数差异
对比两个版本的config/my.php配置文件,关键差异包括:
- 8.2.1版本缺少session.save_handler配置(默认files)
- 12.5.3版本明确配置了
$config->sessionHandler = 'db' - 新版增加了CSRF防护等安全机制
3. 完整解决方案
3.1 紧急恢复步骤
当遇到重定向循环时,可按以下步骤快速恢复系统可用性:
bash复制# 进入禅道安装目录
cd /opt/zentaopms
# 备份后删除旧会话文件
mkdir -p /tmp/session_backup
cp -r zt/tmp/session/* /tmp/session_backup/
rm -rf zt/tmp/session/*
# 清理浏览器缓存和Cookie
重要提示:执行上述操作会导致所有用户被迫重新登录,请确保在业务低峰期操作。
3.2 永久解决方案
- 修改会话配置
编辑config/my.php,添加明确的会话处理配置:
php复制$config->sessionHandler = 'db'; // 使用数据库存储会话
$config->sessionSavePath = ''; // 清空文件会话路径
- 数据库会话表迁移
执行以下SQL创建会话表:
sql复制CREATE TABLE IF NOT EXISTS `zt_session` (
`id` char(32) NOT NULL,
`expiry` int(10) unsigned NOT NULL,
`data` longtext NOT NULL,
PRIMARY KEY (`id`),
KEY `expiry` (`expiry`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- PHP配置调整
确保php.ini中包含以下参数:
ini复制session.save_handler = user
session.serialize_handler = php
3.3 验证步骤
- 使用隐私窗口访问系统,确认可以正常登录
- 检查数据库中的zt_session表是否有新记录生成
- 观察zt/tmp/session目录是否不再有新文件产生
- 测试多标签页登录是否正常
4. 深度优化建议
4.1 会话安全加固
在config/my.php中增加以下安全配置:
php复制$config->sessionCookieLifetime = 14400; // 4小时有效期
$config->sessionGcProbability = 1; // 垃圾回收概率
$config->sessionGcDivisor = 100;
$config->sessionGcMaxlifetime = 14400; // 最大存活时间
4.2 Nginx配置调整
如果使用Nginx,需确保正确传递会话参数:
nginx复制location / {
try_files $uri $uri/ /index.php?$args;
fastcgi_param PHP_VALUE "session.save_handler=user";
}
location ~ \.php$ {
fastcgi_param HTTP_PROXY "";
fastcgi_param HTTPS $https if_not_empty;
}
4.3 升级后检查清单
- 确认所有扩展模块已升级到兼容版本
- 检查自定义插件是否适配新会话机制
- 验证定时任务中的API调用是否正常
- 测试移动端访问兼容性
5. 典型问题排查指南
5.1 问题现象:登录后仍然跳转
可能原因:
- 浏览器缓存了旧的重定向规则
- CDN或代理服务器缓存了302响应
解决方案:
- 强制刷新浏览器(Ctrl+F5)
- 清除CDN缓存
- 检查Location头是否指向正确地址
5.2 问题现象:会话随机丢失
可能原因:
- 数据库会话表未正确维护
- 服务器时间不同步
解决方案:
sql复制-- 定期清理过期会话
CREATE EVENT cleanup_sessions
ON SCHEDULE EVERY 1 HOUR
DO DELETE FROM zt_session WHERE expiry < UNIX_TIMESTAMP();
5.3 性能调优参数
对于高并发场景,建议调整:
php复制$config->sessionCacheLimiter = 'nocache';
$config->sessionUseCookies = 1;
$config->sessionUseOnlyCookies = 1;
$config->sessionCookieSecure = 1; // 启用HTTPS时使用
6. 升级最佳实践
-
预升级检查
- 备份数据库和代码目录
- 记录当前会话配置
- 准备回滚方案
-
分阶段升级
mermaid复制graph LR A[8.2.1] --> B[9.x] B --> C[10.x] C --> D[11.x] D --> E[12.5.3] -
验证流程
- 先在小规模测试环境验证
- 检查所有自定义模块
- 验证第三方集成
经验之谈:大版本升级后,建议先用测试账号完整走一遍核心业务流程,包括任务创建、流转、统计报表生成等关键操作。