WildFly部署因'unable to build Hibernate SessionFactory'失败,如何配置自动重试?
先给你提个小问题:你的数据源配置里jta="false",但persistence.xml里却用了<jta-data-source>,这明显是配置冲突,得先把persistence.xml里的<jta-data-source>改成<non-jta-data-source>,不然Hibernate会纠结怎么处理这个数据源,反而可能加重启动失败的问题。
回到你的核心需求:夜间服务器更新后,数据库没及时起来导致WildFly部署失败,没人值守的情况下总不能每次都手动重启对吧?下面几个配置调整应该能帮你解决这个问题:
方案1:调整数据源连接池,避免启动时强制连数据库
WildFly默认启动时会初始化连接池的初始连接,这时候数据库没起来就直接炸了。咱们改一下数据源配置,让它启动时不创建连接,等实际用的时候再去尝试,同时加上连接有效性检查,数据库恢复后自动重建连接:
<datasource jta="false" jndi-name="java:jboss/datasources/xxx" pool-name="xxx"> <connection-url>jdbc:sqlserver://xxx.xxx.de\INSTANCE;DatabaseName=xxx;encrypt=false</connection-url> <driver>mssql</driver> <security> <user-name>CENSORED</user-name> <password>CENSORED</password> </security> <pool> <initial-pool-size>0</initial-pool-size> <!-- 启动时不创建初始连接 --> <min-pool-size>0</min-pool-size> <max-pool-size>20</max-pool-size> </pool> <validation> <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker"/> <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLExceptionSorter"/> <!-- 识别数据库不可用的异常 --> <background-validation>true</background-validation> <!-- 后台定期检查连接有效性 --> <background-validation-millis>60000</background-validation-millis> <!-- 每分钟检查一次 --> <validate-on-match>true</validate-on-match> <!-- 获取连接时先验证 --> </validation> <timeout> <blocking-timeout-millis>30000</blocking-timeout-millis> <!-- 获取连接超时30秒 --> <idle-timeout-minutes>10</idle-timeout-minutes> </timeout> <new-connection-sql>SELECT 1</new-connection-sql> <!-- 创建新连接时执行验证SQL --> </datasource>
这样配置后,WildFly启动时不会因为数据库没起来而卡住,等数据库恢复后,应用第一次访问数据库时,连接池会自动创建可用连接,业务就能正常跑了。
方案2:给WildFly加部署自动重试机制
如果上面的方案还不够稳妥,咱们可以再给部署流程加个重试兜底。修改standalone-full.xml里的部署扫描器配置,让它在部署失败后自动重试:
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" retry-interval="60000" max-retry-attempts="20" auto-deploy-zipped="true"/>
retry-interval:部署失败后每隔60秒重试一次(单位是毫秒)max-retry-attempts:最多重试20次,你可以根据数据库恢复的大概时长调整这个数值
这样就算启动时因为数据库问题部署失败了,WildFly也会自动每隔一分钟重试一次,直到数据库恢复、部署成功为止。
方案3:调整Hibernate的Schema验证策略
如果你的业务允许,可以把hibernate.hbm2ddl.auto从validate改成none,这样Hibernate在启动时不会去数据库验证Schema结构,也就不需要在启动时建立数据库连接:
<property name="hibernate.hbm2ddl.auto" value="none"/>
要是必须保留Schema验证,那可能得改点代码——比如在应用里加个初始化监听器,等数据库可用后再手动触发验证,不过这个相对麻烦,优先考虑前面两个方案更省心。
总结一下:先把数据源和persistence的JTA配置冲突改了,然后组合方案1和方案2,基本就能解决夜间更新后应用无法自动恢复的问题了。
备注:内容来源于stack exchange,提问作者maio290

