redis学习之:jedis+jedis连接池

背景介绍

最近在做一个硬件项目需要硬件上传数据,然后解析保存到redis里然后由后台去读取redis里的数据.第一选择采用方便的redis官方首选的java客户端jedis.后来发现很多同行在使用中发现jedis连接增多后会报连接超时的异常,而且springboot在2.0版本以后,底层连接池已经换成了lettuce.但是依然要做个记录

使用场景spring boot2.2+

pom应用

<dependency>
   <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.1.0</version>
</dependency>

yml配置

spring:
  #redis单机版
  redis:
    host: ${parm.redis.host-name}
    port: ${parm.redis.port}
    # 密码 没有则可以不填
    password: ${parm.redis.pwd}
    database: ${parm.redis.db1}
    timeout: 2000
    jedis:
      pool:
        max-total: 12
        # 最大活跃链接数 默认8(使用负值表示没有限制)
        max-active: 12
        # 最大空闲连接数 默认8
        max-idle: 12
        # 最小空闲连接数 默认0
        min-idle: 0
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1

jedis启动时配置

启动时配置全局的jedispool,这样能保证每一次获取的jedis连接都是去连接池里面获取,不然每次如果配置jedispool那么就是每次获取了一个jedis连接池.因此在启动时将jedispool的配置交给spring来管理.配置一次全局的

@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxActive;

    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;

    @Value("${spring.redis.jedis.pool.max-wait}")
    private long maxWaitMillis;

    @Bean
    public JedisPool generateJedisPoolFactory() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(maxActive);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWaitMillis(maxWaitMillis);
        JedisPool jedisPool = new JedisPool(poolConfig, host, port, timeout, password);
        return jedisPool;
    }

}

jedis工具类

为什么要封装工具类,
首先如果需要操作redis的业务接口比较多,那么就需要多个连接,需要用到jedis连接池,
其次在使用中发现,如果每次new一个jedis实例,产生一个链接,如果使用完不释放回jedis链接池的话,那么当链接多了的话,就会发生链接被占用,产生链接阻塞.无法访问redis,
这样就需要把每一次的链接调用,封装到工具类里面.使用完了就释放资源
这里特别记录一点:在封装工具类的时候本来在类中添加@component,就可以在其它地方通过@Autowried的方式来注入了,但是不要忘记,我需要在jedis工具类中引用jedispool,而这个jedispool是在启动的时候交给spring托管,返回的一个实体,并不是自定义了一个类,所以在本工具类中,通过注入的方式识别不了,具体原因有待详细的去调查…不过无所谓了…计划换redisTemplte了…在这里坐下记录这是用的@Service接口服务方式实现

@Service
public class RedisServiceImpl implements IRedisService {

    @Autowired
    public JedisPool jedisPool;

    //region 哈希方法

    @Override
    public Long hset(int dbNum, String key, String field, String value) {
        Jedis jedisSet = null;
        Long susNum = 0L;
        try {
            jedisSet = jedisPool.getResource();
            jedisSet.select(dbNum);
            jedisSet.hset(key, field, value);
        } catch (Exception e) {
            if (null != jedisSet) {
                // 释放jedis对象
                jedisSet.close();
            }
            return null;
        } finally {
            jedisSet.close();
        }
        return susNum;
    }

    /**
     * hset
     *
     * @param key
     * @param map
     * @param dbNum
     */
    @Override
    public void hset(String key, Map<String, String> map, int dbNum) {
        Jedis jedisSet = jedisPool.getResource();
        jedisSet.select(dbNum);
        try {
            jedisSet.hset(key, map);
        } catch (Exception e) {
            if (null != jedisSet) {
                // 释放jedis对象
                jedisSet.close();
            }
        } finally {
            jedisSet.close();
        }
    }

    /**
     * hget
     *
     * @param key
     * @param field
     * @return
     */
    @Override
    public String hget(String key, String field, int dbNum) {
        Jedis jedisSet = jedisPool.getResource();
        jedisSet.select(dbNum);
        String object = "";
        try {
            object = jedisSet.hget(key, field);
        } catch (Exception e) {
            if (null != jedisSet) {
                // 释放jedis对象
                jedisSet.close();
            }
            return null;
        } finally {
            jedisSet.close();
        }
        return object;
    }
    //endregion

    //region bit

    /**
     * 设置bit,使用场景签到等
     *
     * @param key
     * @param offset
     * @param value
     * @param dbNum
     */
    @Override
    public void setbit(String key, long offset, boolean value, int dbNum) {

        Jedis jedis = jedisPool.getResource();
        jedis.select(dbNum);
        try {
            jedis.setbit(key, offset, value);
        } catch (Exception e) {
            if (null != jedis) {
                // 释放jedis对象
                jedis.close();
            }
        } finally {
            jedis.close();
        }
    }

    /**
     * 获取bit
     *
     * @param key
     * @param offset
     * @param dbNum
     * @return
     */
    @Override
    public Boolean getbit(String key, long offset, int dbNum) {

        Jedis jedis = jedisPool.getResource();
        jedis.select(dbNum);
        boolean transpotStatus = false;
        try {
            transpotStatus = jedis.getbit(key, offset);
        } catch (Exception e) {
            if (null != jedis) {
                // 释放jedis对象 返回连接池
                jedis.close();
            }
        } finally {
            jedis.close();
        }
        return transpotStatus;
    }

    /**
     * 获取某库中的所有key
     *
     * @param dbNum
     * @return
     */
    @Override
    public List<String> getAllKeys(int dbNum) {
        Jedis jedis = jedisPool.getResource();
        jedis.select(dbNum);
        List<String> resultList = new ArrayList<>();
        try {
            String cursor = "0";
            do {
                ScanParams scanParams = new ScanParams();
                //要查询的key,*代表所有的
                scanParams.match("*");
                //每次查询的数量
                scanParams.count(10);
                ScanResult<String> sr = jedis.scan(cursor, scanParams);
                resultList.addAll(sr.getResult());
                cursor = sr.getCursor();
                //没有下一页则退出
            } while (!cursor.equals("0"));
        } catch (Exception e) {
            if (null != jedis) {
                // 释放jedis对象
                jedis.close();
            }
        } finally {
            jedis.close();
        }
        return resultList;
    }

    //endregion

    //region List--queue 队列

    /**
     * 右进队
     *
     * @param dbNum
     * @param key
     * @param strings
     * @return
     */
    @Override
    public Long rpush(int dbNum, String key, String... strings) {
        Jedis jedisSet = jedisPool.getResource();
        jedisSet.select(dbNum);
        Long susNum = 0L;
        try {
            susNum = jedisSet.rpush(key, strings);
        } catch (Exception e) {
            if (null != jedisSet) {
                // 释放jedis对象
                jedisSet.close();
            }
            return null;
        } finally {
            jedisSet.close();
        }
        return susNum;
    }

    /**
     * 左出队
     *
     * @param dbNum
     * @param key
     * @return
     */
    @Override
    public String lpop(int dbNum, String key) {
        Jedis jedisSet = jedisPool.getResource();
        jedisSet.select(dbNum);
        String data = "";
        try {
            data = jedisSet.lpop(key);
        } catch (Exception e) {
            if (null != jedisSet) {
                // 释放jedis对象
                jedisSet.close();
            }
            return null;
        } finally {
            jedisSet.close();
        }
        return data;
    }
    //endregion

}

调用

在需要的地方直接注入这个service调用就行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值