关键参数:


config.setMaxTotal(5);             config.setMaxIdle(2);             config.setMinIdle(1);             config.setMaxWaitMillis(1500);



最大连接数

空闲连接超过maxidle,直接销毁

空闲连接不超过maxidle,等待一定时间后销毁至minidle

连接达到5,再申请一个连接,等待1.5秒未果后,抛出异常


实践代码:


config.setMaxTotal(50);             config.setMaxIdle(20);             config.setMinIdle(10);             config.setMaxWaitMillis(1500);




for(int i=0; i< 51; ++i) {             try {                 Jedis jedis = RedisPoolUtil.getConn();                 jedis.set("test", "test");                 // 故意不归还                 //    RedisPoolUtil.closeConn(jedis);             } catch (Exception e) {                 e.printStackTrace();             }         }



redis 连接池 实践_redis

(原来有14个连接其它项目)


同时超出的1个报异常:

[INFO] 2018-12-22 16:48:26 446 [com.jds.WxEnterprise.common.RedisPoolUtil] [main] (RedisPoolUtil.java:43) -> redis线程池被成功初始化

redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool

    at redis.clients.util.Pool.getResource(Pool.java:51)

    at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)

    at com.jds.WxEnterprise.common.RedisPoolUtil.getConn(RedisPoolUtil.java:62)

    at com.jds.WxEnterprise.service.RedisService.calInRedis(RedisService.java:28)

    at com.jds.WxEnterprise.WxEnterpriseDataServer.main(WxEnterpriseDataServer.java:60)

Caused by: java.util.NoSuchElementException: Timeout waiting for idle object

    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:448)

    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:362)

    at redis.clients.util.Pool.getResource(Pool.java:49)

    ... 4 more




环境:jdk1.7    redis3.2.8


所需jar包:jedis-2.9.0.jar     commons-pool2-2.3


Jedis连接池使用步骤如下:

1->获取Jedis实例需要从JedisPool中获取;

2->用完Jedis实例需要返还给JedisPool;

3->如果Jedis在使用过程中出错,则也需要还给JedisPool;


=================连接池参数配置文件redis.properties================


    #*****************jedis连接参数设置*********************

    #redis服务器ip

    redis.ip=169.254.130.122

    #redis服务器端口号

    redis.port=6379

    #redis访问密码

    redis.passWord=test123

    #与服务器建立连接的超时时间

    redis.timeout=3000

    #************************jedis池参数设置*******************

    #jedis的最大活跃连接数

    jedis.pool.maxActive=100

    #jedis最大空闲连接数

    jedis.pool.maxIdle=50

    #jedis池没有连接对象返回时,等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。

    #如果超过等待时间,则直接抛出JedisConnectionException

    jedis.pool.maxWait=1500

    #从池中获取连接的时候,是否进行有效检查

    jedis.pool.testOnBorrow=true

    #归还连接的时候,是否进行有效检查

    jedis.pool.testOnReturn=true


=================Redis连接池工具类RedisPoolUtil================


    package com.wx.utils;


    import java.util.Properties;

    import redis.clients.jedis.Jedis;

    import redis.clients.jedis.JedisPool;

    import redis.clients.jedis.JedisPoolConfig;


    /**

     * Redis连接池工具类

     */

    public class RedisPoolUtil {

        private static JedisPool jedisPool = null;

        private static String redisConfigFile = "redis.properties";

        //把redis连接对象放到本地线程中

        private static ThreadLocal<Jedis> local=new ThreadLocal<Jedis>();


        //不允许通过new创建该类的实例

        private RedisPoolUtil() {

        }


        /**

         * 初始化Redis连接池

         */

        public static void initialPool() {

            try {

                Properties props = new Properties();

                //加载连接池配置文件

                props.load(RedisPoolUtil.class.getClassLoader().getResourceAsStream(redisConfigFile));

                // 创建jedis池配置实例

                JedisPoolConfig config = new JedisPoolConfig();

                // 设置池配置项值

                config.setMaxTotal(Integer.valueOf(props.getProperty("jedis.pool.maxActive")));

                config.setMaxIdle(Integer.valueOf(props.getProperty("jedis.pool.maxIdle")));

                config.setMaxWaitMillis(Long.valueOf(props.getProperty("jedis.pool.maxWait")));

                config.setTestOnBorrow(Boolean.valueOf(props.getProperty("jedis.pool.testOnBorrow")));

                config.setTestOnReturn(Boolean.valueOf(props.getProperty("jedis.pool.testOnReturn")));

                // 根据配置实例化jedis池

                jedisPool = new JedisPool(config, props.getProperty("redis.ip"),

                        Integer.valueOf(props.getProperty("redis.port")),

                        Integer.valueOf(props.getProperty("redis.timeout")),

                        props.getProperty("redis.passWord"));

                System.out.println("线程池被成功初始化");

            } catch (Exception e) {

                e.printStackTrace();

            }

        }


        /**

         * 获得连接

         * @return Jedis

         */

        public static Jedis getConn() {

            //Redis对象

            Jedis jedis =local.get();

            if(jedis==null){

                if (jedisPool == null) {    

                    initialPool();  

                }

                jedis = jedisPool.getResource();

                local.set(jedis);

            }

            return jedis;  

        }


        //新版本用close归还连接

        public static void closeConn(){

            //从本地线程中获取

            Jedis jedis =local.get();

            if(jedis!=null){

                jedis.close();

            }

            local.set(null);

        }


        //关闭池

        public static void closePool(){

            if(jedisPool!=null){

                jedisPool.close();

            }

        }

    }



============线程测试类============


    package com.wx.test;


    import java.text.SimpleDateFormat;

    import java.util.Date;

    import com.wx.utils.RedisPoolUtil;

    import redis.clients.jedis.Jedis;


    public class TestPool {

        public static void main(String[] args) {

            //初始化连接池

            RedisPoolUtil.initialPool();

            //启动1000个线程

            for (int i = 0; i < 1000; i++) {            

                ClientThread t = new ClientThread(i);  

                t.start();  

            }

        }  

    }

    //线程类

    class ClientThread extends Thread {  

        int i = 0;  

        public ClientThread(int i) {  

            this.i = i;  

        }  

        public void run() {  

            Jedis jedis=RedisPoolUtil.getConn();

            Date date = new Date();  

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");  

            String time = sdf.format(date);  

            jedis.set("key"+i, time);

            try {

                //每次睡眠一个随机时间

                Thread.sleep((int)(Math.random()*5000));

                String foo = jedis.get("key"+i);        

                System.out.println("【输出>>>>】key:" + foo + " 第:"+i+"个线程");

            } catch (InterruptedException e) {

                e.printStackTrace();

            }finally {

                RedisPoolUtil.closeConn();

            }

        }  

    }  


运行过程中,去服务器看连接数


    127.0.0.1:6379> info clients

    # Clients

    connected_clients:102

    client_longest_output_list:0

    client_biggest_input_buf:0

    blocked_clients:0

    127.0.0.1:6379> info clients

    # Clients

    connected_clients:70

    client_longest_output_list:0

    client_biggest_input_buf:0

    blocked_clients:0

    127.0.0.1:6379> info clients

    # Clients

    connected_clients:53

    client_longest_output_list:0

    client_biggest_input_buf:0

    blocked_clients:0

    127.0.0.1:6379> info clients

    # Clients

    connected_clients:2

    client_longest_output_list:0

    client_biggest_input_buf:0

    blocked_clients:0

    127.0.0.1:6379> info clients

    # Clients

    connected_clients:2

    client_longest_output_list:0

    client_biggest_input_buf:0

    blocked_clients:0

    127.0.0.1:6379>


可以看出连接池中最大100个活跃连接迅速被占满,(最开始102个是因为我单独启动了两个连接)


然后连接用完了,迅速归还连接


java端的运行结果



可以看出有超时没拿到连接的报错!


ok,测试成功!

---------------------  

作者:御前两把刀刀  


版权声明:本文为博主原创文章,转载请附上博文链接!