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. 虚析构函数? vptr? 指针偏移?多态数组? delete 基类指针 内存泄漏?崩溃?

    五条基本规则: 1.如果基类已经插入了vptr, 则派生类将继承和重用该vptr.vptr(一般在对象内存模型的顶部)必须随着对象类型的变化而不断地改变它的指向,以保证其值和当前对象的实际类型是一致的 ...

  2. NPN/PNP和N沟道/P沟道负载的接法

    N沟道mos管和p沟道mos管负载的接法不一样,随意接的话导致VGS不满足条件:如下图N沟道接法,下拉电阻R2必须接,否则电路状态不稳定. 三极管原理类似如下图(满足三极管导通条件) NPN型三极管: ...

  3. Python sql注入 过滤字符串的非法字符

    #coding:utf8 #在开发过程中,要对前端传过来的数据进行验证,防止sql注入攻击,其中的一个方案就是过滤用户传过来的非法的字符 def sql_filter(sql, max_length= ...

  4. Ubuntu快捷键截图

    gnome-screenshot #全屏截图 gnome-screenshot -a #区域截图 在设置-键盘-快捷键-自定义快捷键中添加这个指令,创建快捷键. 注:我本人是在VBox里装的Ubunt ...

  5. spring in action 8.1 使用Spring web flow

    一.说明 Spring Web Flow是spring MVC的扩展,它支持基于流程的应用程序,他将流程的定义和实现流程行为的类和视图分离开来. 1.1 spring中配置web flow,目前需要在 ...

  6. xcode下build release版本号的.a库

    1. 点击房子 图标button watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcnlmZGl6dW8=/font/5a6L5L2T/fontsize/40 ...

  7. 线程相关函数(7)-sem_post(), sem_wait() 信号量

    sem_tsem_initsem_waitsem_trywaitsem_timedwaitsem_postsem_destroy 生产者消费者实例: #include <stdlib.h> ...

  8. 新建一个用户,让他只能看到某一个视图(View),如何设置

    新建一个用户,让他只能看到某一个视图(View),怎么设置? 新建一个用户,让他只能看到某一个视图(View),怎么设置? 如果做不到“只能看到指定视图”,最好能做到“对指定表或视图只有查询的权限”. ...

  9. jquer WdatePicker 使用 手册

    1. 跨无限级框架显示 无论你把日期控件放在哪里,你都不需要担心会被外层的iframe所遮挡进而影响客户体验,因为My97日期控件是可以跨无限级框架显示的 示例2-7 跨无限级框架演示 可无限跨越框架 ...

  10. onResume

    比如做一个音乐播放程序,在播放过程中,突然有电话打进来了,这时系统自动调出电话,而你的音乐播放程序置于后台,触发了onPause方法.当你电话结束后,关闭电话,又自动回到音乐播放程序,此时,触发onR ...