Jedis断线重连问题

2019-04-16  本文已影响0人  新签名

问题以及现象

前一阵子发现redis断线重连后,会出现类似如下的错误:

错误日志

解决思路

socket write error之前以为redisTemplate不支持断线重连,也就没当回事。后来请教一个比我更有经验的开发人员,他说jedis支持断线重连,并给我写了一个demo,发现确实会断线重连。

但项目上跑的服务为什么不会断线重连呢,接连排除了redis版本、redisTemplate版本、redisTemplate使用不当可能引起的问题,最后在redisTemplate中发现以下代码:

redisTemplate#execute(RedisCallback<T> , boolean , boolean )

public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
        Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(action, "Callback object must not be null");

        RedisConnectionFactory factory = getConnectionFactory();
        RedisConnection conn = null;
        try {

            if (enableTransactionSupport) {
                // only bind resources in case of potential transaction synchronization
                conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
            } else {
                conn = RedisConnectionUtils.getConnection(factory);
            }

            boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);

            RedisConnection connToUse = preProcessConnection(conn, existingConnection);

            boolean pipelineStatus = connToUse.isPipelined();
            if (pipeline && !pipelineStatus) {
                connToUse.openPipeline();
            }

            RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
            T result = action.doInRedis(connToExpose);

            // close pipeline
            if (pipeline && !pipelineStatus) {
                connToUse.closePipeline();
            }

            // TODO: any other connection processing?
            return postProcessResult(result, connToUse, existingConnection);
        } finally {

            if (!enableTransactionSupport) {
                RedisConnectionUtils.releaseConnection(conn, factory);
            }
        }
    }

在最后的finally中发现如果启用事务并不会释放连接,猜想可能是这个原因。果然项目上redisTemplate配置了启用事务这个选项,最后将其去掉,一切回归正常,断线10min后连接仍可以连上。

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    <property name="enableTransactionSupport" value="false" />
</bean>

其他

RedisTemplate redisTemplate = (RedisTemplate) applicationContext.getBean("redisTemplate");

try{
    redisTemplate.multi();
    ......
    redisTemplate.exec();
} catch(Exception e){
    redisTemplate.discard();
}
上一篇下一篇

猜你喜欢

热点阅读