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. Linux命令-文件搜索命令:locate

    实际上是在分区表上搜索文件,比find命令速度更快 locate inittab 查找名称包含inittab的所有信息(快速搜索,实际上它是搜索linux资料库,区别于find在某一个磁盘分区或者某一 ...

  2. Spring boot 配置 swagger

    1.maven配置包 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --> <dep ...

  3. 站点下的robots

    面试某软,被面试官问道:你做爬虫.知不知道非常多站点下都有个robots文件? 答曰:不知. 于是面试官给我演示了一遍~ 遂卒.首战慘败. 下来查了维基百科.基本了解robots.https://zh ...

  4. C# Directory类的操作

    Directory类位于System.IO 命名空间.Directory类提供了在目录和子目录中进行创建移动和列举操作的静态方法.此外,你还可以访问和操作各种各样的目录属性,例如创建或最后一次修改时间 ...

  5. Spring Cloud(五):熔断监控Hystrix Dashboard和Turbine

    Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数 ...

  6. 【Android】15.4 例15-2--Notification基本用法

    分类:C#.Android.VS2015: 创建日期:2016-02-29 一.简介 上一节介绍了通知(Notification)相关的基本内容.这一节先用一个简单示例演示创建和发布本地通知的基本用法 ...

  7. python学习之winreg模块

    winreg模块将Windows注册表API暴露给了python. 常见方法和属性 winreg.OpenKey(key,sub_key,reserved = ,access = KEY_READ) ...

  8. prompt() 方法

    定义和用法 prompt() 方法用于显示可提示用户进行输入的对话框. 语法 prompt(text,defaultText) 参数 描述 text 可选.要在对话框中显示的纯文本(而不是 HTML ...

  9. [转]软件测试 Top 120 Blog (博客)

    [转]软件测试 Top 120 Blog (博客) 2015-06-08 转自:    软件测试 Top 120 Blog (博客) # Site Author Memo DevelopSense M ...

  10. js 树菜单 ztree

    http://www.ztree.me/v3/api.php 官网 api js /** <div id="menuContent" class="menuCont ...