java设置redis保持长连接_java原生程序redis连接(连接池/长连接和短连接)选择问题...

最近遇到的连接问题我准备从重构的几个程序(redis和mysql)长连接和短连接,以及连接池和单连接等问题用几篇博客来总结下。

这个问题的具体发生在java原生程序和redis的交互中。这个问题对我最深刻的教训就是说明获取连接不能迷信连接池和原封不动的搬运以前代码的utils。在连接的建立的一开始就应该思考连接的稳定性和是否应该关闭连接。否则这些问题在线上运行十几个小时可能才会暴露,即使知道了问题反过来的排查和修改也会很困难。甚至在重构之前用一种勉强凑合的方式掩盖问题(给自己挖坑)

应用场景

java原生程序,内部写多个线程,定时循环监测(一小时一次),使用了redis连接。

最开始是采用长连接的方式,在main方法中用连接池获取连接后分配到各线程,这种方式虽然只创建一次连接,但在长时间的程序休眠中,仍然会产生对连接的占用,也会导致掉连接的问题,以下是从连接池获取连接的代码(也可拆分成获取连接池和通过连接池单独获取连接):

public Jedis createJedisCluterInstance(Map<String, Object> props){

String[] hostPortStr = String.valueOf(this.config.getOrDefault(REDIS_CLUSTER_NODE_PORT,props.get(REDIS_CLUSTER_NODE_PORT))).split(":");

GenericObjectPoolConfig config = new GenericObjectPoolConfig();

config.setMaxTotal(Integer.valueOf(String.valueOf(this.config.getOrDefault(REDIS_MAX_TOTAL,props.get(REDIS_MAX_TOTAL)))));

config.setMaxIdle(Integer.valueOf(String.valueOf(this.config.getOrDefault(REDIS_MAX_IDLE,props.get(REDIS_MAX_IDLE)))));

config.setMaxWaitMillis(Integer.valueOf(String.valueOf(this.config.getOrDefault(REDIS_MAX_WAIT_MILLIS,props.get(REDIS_MAX_WAIT_MILLIS)))));

JedisPool jedisPool = new JedisPool(config,hostPortStr[0],Integer.valueOf(hostPortStr[1]));

final Jedis[] jedis= {null};

Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()

.retryIfException()

.withWaitStrategy(WaitStrategies.fixedWait(1000, TimeUnit.MILLISECONDS))

.withStopStrategy(StopStrategies.stopAfterAttempt(10))

.build();

try {

retryer.call(() -> {

jedis[0] = jedisPool.getResource();

jedis[0].auth("123");

String value = jedis[0].ping();

return StringUtils.isNotBlank(value);

});

} catch (Exception e) {

LOGGER.error("多次获取Redis连接失败!");

}

return jedis[0];

}

当时处理掉连接的方式是采用了定时任务按每分钟一次的频率监测,对异常trycatch后直接退出程序。

这种方法产生了很大的资源消耗,也对业务造成影响,主要原因是盲目使用连接池造成的。

修改后采用传入配置到线程中,在线程中启动连接,同时修改连接池连接为直接获取连接。减少了资源消耗,同时也处理了掉连接的问题。并在每次循环结束后关闭redis连接 :关闭方法redis.close(); 并在下次循环开始后重新初始化,直接获取redis对象代码:

public Jedis getJedis(Map<String, Object> props){

String[] hostPortStr = String.valueOf(this.config.getOrDefault(REDIS_CLUSTER_NODE_PORT, props.get(REDIS_CLUSTER_NODE_PORT))).split(":");

Jedis jedis = new Jedis(hostPortStr[0],Integer.valueOf(hostPortStr[1]),Integer.valueOf(String.valueOf(this.config.getOrDefault(REDIS_MAX_WAIT_MILLIS, props.get(REDIS_MAX_WAIT_MILLIS)))));

jedis.auth("123");

return jedis;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值