解决Jedis链接报超时异常和connection reset异常的方法

本文介绍了Redis链接池的配置方法,并通过Java实现了一个基于哨兵模式的链接池。包括了JedisPoolConfig的参数设置及JedisSentinelPoolConfig类的详细实现,还展示了如何在JedisHelper类中使用这些配置进行列表操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、链接池配置

  <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
     <!-- ${redis.max_total:64}会优先查找是否已经配置redis.max_total的属性,如果没有配置,则为64   -->
    <property name="maxTotal" value="${redis.max_total:300}" />
    <property name="maxIdle" value="${redis.max_idle:8}" />
    <property name="maxWaitMillis" value="${redis.max_wait_millis:30000}" />
    <property name="testOnBorrow" value="true" />
  <!-- whenExhaustedAction为1表示当链接池的实例用完时,阻塞,直到有可用链接资源   -->
    <property name="blockWhenExhausted"  value="true"></property> 
  </bean>

  <bean id="jedisSentinelPoolConfig" class="com.chinacloud.monitoring.api.util.JedisSentinelPoolConfig">
    <constructor-arg index="0" value="${redis.master.name}" />
    <constructor-arg index="1" value="${redis.sentinels}" />
    <constructor-arg index="2" ref="jedisPoolConfig" />
  </bean>

  <bean id="jedisHelper" class="com.chinacloud.monitoring.api.util.JedisHelper" destroy-method="destroy">
    <!--对应于JedisHelper类里面的的构造函数   -->
    <constructor-arg index="0" ref="jedisSentinelPoolConfig" />
  </bean>

二、JedisSentinelPoolConfig类

package com.chinacloud.monitoring.api.util;

import java.util.HashSet;
import java.util.Set;

import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

public class JedisSentinelPoolConfig {
    //在集群中的主机maste-slave模式下
    private String masterName;
    private String sentinels;
    private JedisPoolConfig jedisConfig;

    public JedisSentinelPoolConfig(String masterName, String sentinels, JedisPoolConfig jedisConfig) {
        //TODO: validation
        this.masterName = masterName;
        this.sentinels = sentinels;
        this.jedisConfig = jedisConfig;
        
    }

    //JedisSentinelPool支持集群的链接池
    public JedisSentinelPool getJedisSentinelPool() {
        String[] sentinelstrs = sentinels.split(",");
        Set<String> sentinelsSet = new HashSet<String>(sentinelstrs.length);
        for (String st : sentinelstrs) {
            sentinelsSet.add(st);
        }
        //30000表示超时为30秒
        return new JedisSentinelPool(masterName, sentinelsSet, jedisConfig,30000);
    }
}

三、JedisHelper类

    public <T> List<T> listRange(String listName, Class<T> elementClazz, long start, long end) throws IOException {
        Assert.notNull(listName);
        Assert.notNull(elementClazz);
        Jedis jedis = null;
        boolean borrowOrOprSuccess = true;
        List<T> objects = new ArrayList<>();
        jedis=getJedis();
        try {
                   //同步锁解决高并发情况下的address in use异常
                   synchronized (this) {
                       if(jedis!=null){
                            List<String> elements = jedis.lrange(listName, start, end);                   
                            for (String element : elements) {
                                objects.add(objectMapper.readValue(element, elementClazz));
                            }
                       }
                   }            
        } catch (Exception e) {
            borrowOrOprSuccess = false;
            if (jedis != null)
                jedisPool.returnBrokenResource(jedis);
 
        } finally {
            if (borrowOrOprSuccess){
                jedisPool.returnResource(jedis);
            }            
        }
        return objects;
    }
    
    public  Jedis getJedis()  
    {  
            int timeoutCount = 0;  
            while (true) {  //如果第一次取不到,尝试取三次链接
                try  {  
                    Jedis jedis = jedisPool.getResource();  
                    return jedis;  
                } catch (Exception e)  { 
                    timeoutCount++;
                    if (timeoutCount > 3)  
                    {  
                         break;  
                    } 
                }  
            }  
            return null;  
    } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值