Alfresco 5.2迁移至7.0后凌晨4点触发PSQLException: SSL error: readHandshakeRecord致仓库无响应问题求助
我来帮你拆解这个问题,从堆栈跟踪和你的描述来看,核心是Activiti的作业执行器遇到了数据库连接失效导致的SSL握手错误,咱们一步步分析解决:
一、为什么这个作业会在凌晨4点触发?
首先要明确:这个不是你找不到的Quartz任务,而是**Activiti内置的Job Executor(作业执行器)**在定期轮询数据库时出的问题。
Activiti的Job Executor会持续运行线程,每隔一段时间就去数据库的ACT_RU_JOB表查询待执行的作业(比如流程定时器、异步任务)。凌晨4点出现问题的原因大概率是:
- 数据库连接池里的闲置连接被PostgreSQL服务器主动断开了(比如数据库配置了闲置连接超时回收),但连接池没有检测到连接失效,导致Activiti尝试用失效连接时触发SSL握手失败
- 凌晨时段可能有服务器/数据库的运维操作(比如SSL会话过期、网络策略调整),刚好和Activiti的作业轮询撞在了一起
二、如何手动触发验证或临时修复?
如果想快速验证问题或者临时修复,可以试试这些操作:
- 通过JMX刷新Activiti作业执行器:如果你的Alfresco开启了JMX,找到
org.activiti.engine下的JobExecutorBean,调用start()或者retry()方法,强制它重新初始化数据库连接 - 刷新数据库连接池:从堆栈看你用的是Apache DBCP,同样通过JMX找到
BasicDataSource,调用evictIdle()回收所有闲置失效连接,或者close()后再init()重建连接池 - 手动触发Activiti作业:创建一个简单的测试流程实例(比如发起一个空白的Activiti流程),强制引擎去数据库读写,这样会触发连接池获取新连接,替换掉失效的旧连接
三、根本解决方案(无需禁用Activiti)
从错误堆栈和场景来看,核心问题是连接池没有正确处理失效连接,结合PostgreSQL的SSL/连接超时设置导致的,你可以从这几个方向入手:
配置连接池的有效性检测
给你的DBCP数据源添加以下配置,让它在借出连接前自动验证有效性:# 验证连接的SQL(PostgreSQL适用) validationQuery=SELECT 1 # 借连接时验证 testOnBorrow=true # 验证间隔,避免频繁检测 validationInterval=30000这样连接池会自动丢弃失效连接,重新创建可用的连接,从根源避免用失效连接触发SSL错误。
调整PostgreSQL的连接超时设置
检查PostgreSQL的postgresql.conf,调整以下参数:idle_in_transaction_session_timeout:设置闲置事务的超时时间,避免连接长时间闲置tcp_keepalives_idle:开启TCP保活,让数据库和应用之间保持连接活性
确保这些参数和连接池的超时配置匹配,比如连接池的maxIdle时间不要超过数据库的闲置超时时间。
升级PostgreSQL驱动
旧版本的PostgreSQL JDBC驱动可能存在SSL握手的bug,试试升级到最新的稳定版(比如42.2.x及以上),替换Alfrescolib目录下的旧驱动包。优化Activiti作业执行器配置
修改Alfresco的activiti-context.xml,调整作业执行器的参数:- 增加
jobAcquireWaitTimeInMillis,延长作业轮询间隔,减少闲置连接的概率 - 配置
maxIdleTime,让作业执行器在闲置时关闭多余连接,避免连接长时间闲置失效
- 增加
四、为什么找不到对应的Quartz任务?
Activiti的作业执行器是独立于Alfresco的Quartz调度器的,它自己维护了线程池来轮询自身的作业表,并不依赖Alfresco的Quartz任务体系,所以你在Quartz任务列表里找不到对应的任务,这是正常的。
内容的提问来源于stack exchange,提问作者Heiko Robert

