java端在使用jedispool 连接redis的时候,在高并发的时候经常卡死,或报连接异常,JedisConnectionException,或者getResource 异常等各种问题

在使用jedispool 的时候一定要注意两点

1、 在获取 jedisPool和jedis的时候加上线程同步,保证不要创建过多的jedispool 和 jedis

2、 用完Jedis实例后需要返还给JedisPool

整理了一下redis工具类,通过大量测试和高并发测试的。

package com.util;
 
import org.apache.log4j.Logger;
 
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
 
/**
 * Redis 工具类
 * @author think
 */
public class RedisUtil {
     
    protected static Logger logger = Logger.getLogger(RedisUtil.class);
     
    //Redis服务器IP
    private static String ADDR_ARRAY = FileUtil.getPropertyValue("/properties/redis.properties""server");
     
    //Redis的端口号
    private static int PORT = FileUtil.getPropertyValueInt("/properties/redis.properties""port");
     
    //访问密码
//    private static String AUTH = FileUtil.getPropertyValue("/properties/redis.properties", "auth");
     
    //可用连接实例的最大数目,默认值为8;
    //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
    private static int MAX_ACTIVE = FileUtil.getPropertyValueInt("/properties/redis.properties""max_active");;
     
    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
    private static int MAX_IDLE = FileUtil.getPropertyValueInt("/properties/redis.properties""max_idle");;
     
    //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
    private static int MAX_WAIT = FileUtil.getPropertyValueInt("/properties/redis.properties""max_wait");;
 
    //超时时间
    private static int TIMEOUT = FileUtil.getPropertyValueInt("/properties/redis.properties""timeout");;
     
    //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
    private static boolean TEST_ON_BORROW = FileUtil.getPropertyValueBoolean("/properties/redis.properties""test_on_borrow");;
     
    private static JedisPool jedisPool = null;
     
    /**
     * redis过期时间,以秒为单位
     */
    public final static int EXRP_HOUR = 60*60;          //一小时
    public final static int EXRP_DAY = 60*60*24;        //一天
    public final static int EXRP_MONTH = 60*60*24*30;   //一个月
     
    /**
     * 初始化Redis连接池
     */
    private static void initialPool(){
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWaitMillis(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[0], PORT, TIMEOUT);
        catch (Exception e) {
            logger.error("First create JedisPool error : "+e);
            try{
                //如果第一个IP异常,则访问第二个IP
                JedisPoolConfig config = new JedisPoolConfig();
                config.setMaxTotal(MAX_ACTIVE);
                config.setMaxIdle(MAX_IDLE);
                config.setMaxWaitMillis(MAX_WAIT);
                config.setTestOnBorrow(TEST_ON_BORROW);
                jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[1], PORT, TIMEOUT);
            }catch(Exception e2){
                logger.error("Second create JedisPool error : "+e2);
            }
        }
    }
     
     
    /**
     * 在多线程环境同步初始化
     */
    private static synchronized void poolInit() {
        if (jedisPool == null) { 
            initialPool();
        }
    }
 
     
    /**
     * 同步获取Jedis实例
     * @return Jedis
     */
    public synchronized static Jedis getJedis() { 
        if (jedisPool == null) { 
            poolInit();
        }
        Jedis jedis = null;
        try 
            if (jedisPool != null) { 
                // 从池中获取一个Jedis对象
                jedis = jedisPool.getResource();
            }
        catch (Exception e) { 
            logger.error("Get jedis error : "+e);
        }finally{
            returnResource(jedis);
        }
        return jedis;
    
     
     
    /**
     * 释放jedis资源
     * @param jedis
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null && jedisPool !=null) {
            jedisPool.returnResource(jedis);
        }
    }
     
     
    /**
     * 设置 String
     * @param key
     * @param value
     */
    public static void setString(String key ,String value){
        try {
            value = StringUtil.isEmpty(value) ? "" : value;
            getJedis().set(key,value);
        catch (Exception e) {
            logger.error("Set key error : "+e);
        }
    }
     
    /**
     * 设置 过期时间
     * @param key
     * @param seconds 以秒为单位
     * @param value
     */
    public static void setString(String key ,int seconds,String value){
        try {
            value = StringUtil.isEmpty(value) ? "" : value;
            getJedis().setex(key, seconds, value);
        catch (Exception e) {
            logger.error("Set keyex error : "+e);
        }
    }
     
    /**
     * 获取String值
     * @param key
     * @return value
     */
    public static String getString(String key){
        if(getJedis() == null || !getJedis().exists(key)){
            return null;
        }
        return getJedis().get(key);
    }
     
}

jedispool 连 redis的更多相关文章

  1. Jedis/JedisPool和Redis数据类型与特性

    1.介绍Jedis Jedis 是 Redis 的 java 版本客户端,使用Jedis可以连接 Redis的数据库,Jedis连接方式有三种Jedis/JedisPool 连接.ShardedJed ...

  2. spring boot redis缓存JedisPool使用

    spring boot redis缓存JedisPool使用 添加依赖pom.xml中添加如下依赖 <!-- Spring Boot Redis --> <dependency> ...

  3. redis 工具类 单个redis、JedisPool 及多个redis、shardedJedisPool与spring的集成配置

    http://www.cnblogs.com/edisonfeng/p/3571870.html http://javacrazyer.iteye.com/blog/1840161 http://ww ...

  4. 三:Redis连接池、JedisPool详解、Redisi分布式

    单机模式: package com.ljq.utils; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; ...

  5. redis设置密码以及jedisPool设置密码

    转: redis设置密码以及jedisPool设置密码 2019年01月02日 20:24:43 宇文荒雪 阅读数:1118   版权声明:本文为博主原创文章,未经博主允许不得转载. https:// ...

  6. Java与redis交互、Jedis连接池JedisPool

    Java与redis交互比较常用的是Jedis. 先导入jar包: commons-pool2-2.3.jar jedis-2.7.0.jar 基本使用: public class RedisTest ...

  7. redis连接池(JedisPool)资源归还及timeout详解

    转载. https://blog.csdn.net/yaomingyang/article/details/79043019 一.连接池资源类详解都在注释上 package redis.v1.clie ...

  8. redis连接池——JedisPool和JedisCluster的介绍与使用

    目录 Jedis使用方式的介绍 Redis连接池介绍 创建连接池配置文件 单机版的Redis连接池 集群版的Redis连接池 总结 Jedis使用方式的介绍 Jedis就是Java实现的操作Redis ...

  9. (二)Redis之Jedis概念和HelloWorld实现以及JedisPool的使用

    一.Jedis概念 实际开发中,我们需要用Redis的连接工具连接Redis然后操作Redis, 对于主流语言,Redis都提供了对应的客户端: 官网:https://redis.io/clients ...

随机推荐

  1. 10分钟学会搭建Android开发环境 Eclipse: The import android.support cannot be resolved

    10分钟学会搭建Android开发环境_隋雨辰 http://v.youku.com/v_show/id_XNTE2OTI5Njg0.html?from=s1.8-1-1.2 The import a ...

  2. Linux命令-文件处理命令:head

    从头开始往下查看文件,区别于从末尾往上查看文件命令tail head -n /etc/services 查看etc目录下面的services文件的前10行内容 head /etc/services 查 ...

  3. EMQ ---payload

    问:payload传输过程中会不会拆包,粘包?业务层拿到payload还需要自己组包吗? 答:不需要,mqtt协议有约定,emq会帮忙处理tcp的粘包拆包.总之,直接拿出来用即可. 问:payload ...

  4. java项目部署后的文件路径获取

    //eclipse部署工程 String path = request.getServletContext().getRealPath( File.separator+ "WEB-INF&q ...

  5. cocos2d-x中的宏定义CC_PROPERTY

    cocos2d-x定义了很多宏定义,帮我们提高开发效率,下面看下CC_PROPERTY, CC_PROPERTY定义 CC_PROPERTY的声明在CCPlatformMacros.h中,结构如下 # ...

  6. 三、请求库之requests模块

    一 介绍   #介绍:使用requests可以模拟浏览器的请求,比起之前用到的urllib,requests模块的api更加便捷(本质就是封装了urllib3) #注意:requests库发送请求将网 ...

  7. vue项目中,main.js,App.vue,index.html如何调用

    1.main.js是我们的入口文件,主要作用是初始化vue实例,并引入所需要的插件 2.App.vue是我们的主组件,所有页面都是在App.vue下进行切换的.其实你也可以理解为所有的路由也是App. ...

  8. MySQL编码问题集合

    1.以root用户的身份登录,查看编码设置 mysql> SHOW VARIABLES LIKE 'character%'; +--------------------------+------ ...

  9. scala,spark练习题提高

    1.求每家公司有哪些产品 val arr3 = List("Apache" -> "Spark", "Apache" -> &q ...

  10. linux 域和xenomai 实时域之间的交互

    /* * XDDP-based RT/NRT threads communication demo. * * Real-time Xenomai threads and regular Linux t ...