zoukankan      html  css  js  c++  java
  • 为什么要用Jedis连接池+浅谈jedis连接池使用

    为什么要使用Jedis连接池

    Redis作为缓存数据库理论上和MySQL一样需要客户端和服务端建立起来连接进行相关操作,使用MySQL的时候相信大家都会使用一款开源的连接池,例如C3P0.因为直连会消耗大量的数据库资源,每一次新建一个连接之,使用后再断开连接,对于频繁访问的场景,这显然不是高效的。

    Jedis连接池的使用

    Jedis直连Redis

    生产环境一般使用连接池的方式对Redis连接进行管理,所有Jedis对象先放在池子中每一次需要的时候连接Redis,只需要在池子中借,用完了再归还给池子。

    Jedis连接池的使用

    Jedis连接池使用方式

    客户端连接Redis使用的是TCP协议,直连的方式每次需要建立TCP连接,而连接池的方式是可以预先初始化好Jedis连接,所以每次只需要从Jedis连接池借用即可,而借用和归还操作是在本地进行的,只有少量的并发同步开销,远远小于新建TCP连接的开销。另外直连的方式无法限制Jedis对象的个数,在极端情况下可能会造成连接泄露,而连接池的形式可以有效的保护和控制资源的使用。但是直连的方式也并不是一无是处,下面给出两种方式各自的优劣势。

    Jedis连接池的使用

    Jedis直连方式和连接池方式对比

    Jedis提供了JedisPool这个类作为对Jedis的连接池。使用如下:
     1 public class RedisPool {
     2     //声明成static的原因:保证jedis连接池在tomcat启动时就加载出来
     3     //jedis连接池
     4     private static JedisPool pool;
     5     //与redis连接池连接的最大连接数
     6     private static Integer maxTotal = Integer.parseInt(PropertiesUtil.getProperty("redis.max.total", "20"));
     7     //在这个连接池中最多有多少个状态为idle的jedis实例,jedis连接池里就是jedis的实例,idle就是空闲的jedis实例
     8     //在jedis连接池中最大的idle状态(空闲的)的jedis实例的个数
     9     private static Integer maxIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.max.idle", "10"));
    10     //在jedis连接池中最小的idle状态(空闲的)的jedis实例的个数
    11     private static Integer minIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.min.idle", "2"));
    12 
    13     //在borrow一个jedis实例的时候,是否要进行验证操作,如果赋值为true,则得到的jedis实例肯定是可用的
    14     private static Boolean testOnBorrow = Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.borrow", "true"));
    15     //在return一个jedis实例的时候,是否要进行验证操作,如果赋值为true,则返回jedis连接池的jedis实例肯定是可用的
    16     private static Boolean testOnReturn = Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.return", "true"));
    17 
    18     private static String redisIp = PropertiesUtil.getProperty("redis.ip");
    19     private static Integer redisPort = Integer.parseInt(PropertiesUtil.getProperty("redis.port"));
    20 
    21     //初始化连接池,只会调用一次
    22     private static void initPool() {
    23         JedisPoolConfig config = new JedisPoolConfig();
    24 
    25         config.setMaxTotal(maxTotal);
    26         config.setMaxIdle(maxIdle);
    27         config.setMinIdle(minIdle);
    28 
    29         config.setTestOnBorrow(testOnBorrow);
    30         config.setTestOnReturn(testOnReturn);
    31 
    32         //连接池耗尽的时候,是否阻塞,false会抛出异常,true阻塞直到超时,会抛出超时异常,默认为true
    33         config.setBlockWhenExhausted(true);
    34 
    35         //这里超时时间是2s
    36         pool = new JedisPool(config, redisIp, redisPort, 1000*2);
    37 
    38     }
    39 
    40     static {
    41         initPool();
    42     }
    43 
    44     //从连接池中拿取一个实例
    45     public static Jedis getJedis() {
    46         return pool.getResource();
    47     }
    48 
    49     //将正常实例放回jedis连接池
    50     public static void returnResource(Jedis jedis) {
    51         pool.returnResource(jedis);
    52     }
    53 
    54     //将破损实例放回jedis连接池
    55     public static void returnBrokenResource(Jedis jedis) {
    56         pool.returnResource(jedis);
    57     }
    58 
    59 }
    View Code

    JedisPoolUtil向外提供的工具类如下所示:

     1 public class RedisPoolUtil {
     2 
     3     //重新设置有效期
     4     //参数只有key和有效期,因为只需要根据key设置有效期即可
     5     public static Long expire(String key, int exTime) {
     6         Jedis jedis = null;
     7         Long result = null;
     8         try {
     9             jedis = RedisPool.getJedis();
    10             //设置有效期
    11             result = jedis.expire(key, exTime);
    12         } catch (Exception e) {
    13             log.error("setex key:{} error", key, e);
    14             RedisPool.returnBrokenResource(jedis);
    15             return result;
    16         }
    17         RedisPool.returnResource(jedis);
    18         return result;
    19     }
    20 
    21     //exTime单位是s,设置session有效时间
    22     //当用户初次登录的时候,需要设置有限期,存在redis session中
    23     //后续如果用户再次请求登录,则只需要调用expire,重新设置有效期即可
    24     public static String setEx(String key, String value, int exTime) {
    25         Jedis jedis = null;
    26         String result = null;
    27         try {
    28             jedis = RedisPool.getJedis();
    29             result = jedis.setex(key, exTime, value);
    30         } catch (Exception e) {
    31             log.error("setex key:{} value:{} error", key, value, e);
    32             RedisPool.returnBrokenResource(jedis);
    33             return result;
    34         }
    35         RedisPool.returnResource(jedis);
    36         return result;
    37     }
    38 
    39     public static String set(String key, String value) {
    40         Jedis jedis = null;
    41         //jedis返回的结果
    42         String result = null;
    43         try {
    44             jedis = RedisPool.getJedis();
    45             //设置key-value
    46             result = jedis.set(key, value);
    47         } catch (Exception e) {
    48             log.error("set key:{} value:{} error", key, value, e);
    49             RedisPool.returnBrokenResource(jedis);
    50             return result;
    51         }
    52         RedisPool.returnResource(jedis);
    53         return result;
    54     }
    55 
    56     public static String get(String key) {
    57         Jedis jedis = null;
    58         String result = null;
    59         try {
    60             jedis = RedisPool.getJedis();
    61             //根据key获取value值
    62             result = jedis.get(key);
    63         } catch (Exception e) {
    64             log.error("set key:{} error", key, e);
    65             RedisPool.returnBrokenResource(jedis);
    66             return result;
    67         }
    68         RedisPool.returnResource(jedis);
    69         return result;
    70     }
    71 
    72     public static Long del(String key) {
    73         Jedis jedis = null;
    74         Long result = null;
    75         try {
    76             jedis = RedisPool.getJedis();
    77             //根据key删除key-value
    78             result = jedis.del(key);
    79         } catch (Exception e) {
    80             log.error("set key:{} error", key, e);
    81             RedisPool.returnBrokenResource(jedis);
    82             return result;
    83         }
    84         RedisPool.returnResource(jedis);
    85         return result;
    86     }
    87 }
    View Code
  • 相关阅读:
    CF1276F
    CF1082F
    CF1366G
    CF1221G
    CentOS7统计某个进程当前的线程数
    centos7备份系统日志
    mysql删除带外键约束的表的方法
    django.db.models.query.QuerySet格式的数据输出
    Linux命令大全
    django创建多对多表三种方法,和ORM操作增删改查
  • 原文地址:https://www.cnblogs.com/cing/p/9133662.html
Copyright © 2011-2022 走看看