redis客户端Jedis源码分析系列——连接池的创建过程
2015-11-01 00:00
711 查看
摘要: 本文对jedis源码进行分析,阐述了jedis实现原理和实现细节
一、Jedis介绍
Jedis 是 Redis 官方首选的 Java 客户端开发包。借助该开发包我们可以通过创建单个redis客户端实例来访问redis数据库,同时它也提供了连接池的实现。Jedis开发包中连接池是利用apachec开发的对象池框架commons-pool实现的,所以要想使用Jedis的连接池功能必须要导入commons-pool包。
二、一个使用连接池的小例子(Jedis-2.1.0+commons-pool-1.6)
三、连接池创建过程
上面例子连接池初始化代码如下;
连接池一些配置信息如池中最大活跃数量、最大空闲数量等等被存储在JedisPoolConfig对象中。JedisPoolConfig继承commons-pool包中的Config类,是一个比较纯碎的javabean,不做过多阐述。
JedisPool继承commons-pool包中的Pool类,其初始化的过程是调用父类Pool类的构造器完成的。
Jedis把JedisFactory传工厂类给了父类的构造器,JedisFactory继承BasePoolableObjectFactory抽象类(BasePoolableObjectFactory实现了PoolableObjectFactory接口),重写了其中的makeObject方法。
makeObject方法提供了创建Jedis实例的功能,commons-pool在初始化池的时候调用我们传入的工厂类makeObject方法来创建要放入缓存池中的对象,这个地方用到了抽象工厂模式这样的设计思想。JedisFactory的makeObject方法做了这几件事:
(1)创建Jedis实例
(2)连接redis服务器
(3)如果redis服务器需要密码则向服务器提供密码
(4)如果指定数据库不是默认的0,则选择指定的数据库
下面是单个Jedis实例的构造很简单,目标就是要创建Client客户端实例保存到成员属性中,Client间接继承了Connection,Jedis的构造仅仅是把从Connection继承而来的三个属性主机地址、端口号和连接超时时间进行赋值:
Jedis实例创建完之后利用Socket套接字和redis服务器进行连接,这个过程是在Connection类中进行的,建立连接之后将输入流和输出流保存到成员对象中,这样以后就可以向redis服务器发送命令,代码如下:
这样redis连接池就完成了初始化的工作。
一、Jedis介绍
Jedis 是 Redis 官方首选的 Java 客户端开发包。借助该开发包我们可以通过创建单个redis客户端实例来访问redis数据库,同时它也提供了连接池的实现。Jedis开发包中连接池是利用apachec开发的对象池框架commons-pool实现的,所以要想使用Jedis的连接池功能必须要导入commons-pool包。
二、一个使用连接池的小例子(Jedis-2.1.0+commons-pool-1.6)
package com.fsun.framework.cache.redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class RedisManager { //Redis服务器IP private static String ADDR = ""; //Redis的端口号 private static int PORT = 6379; //访问密码 private static String AUTH = "admin"; //可用连接实例的最大数目,默认值为8; //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。 private static int MAX_ACTIVE = 1024; //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。 private static int MAX_IDLE = 200; //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException; private static int MAX_WAIT = 10000; private static int TIMEOUT = 10000; //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的; private static boolean TEST_ON_BORROW = true; private static JedisPool jedisPool; /** * 初始化Redis连接池 */ static { try { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxActive(MAX_ACTIVE); config.setMaxIdle(MAX_IDLE); config.setMaxWait(MAX_WAIT); config.setMaxWait(MAX_WAIT); config.setTestOnBorrow(TEST_ON_BORROW); jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH); } catch (Exception e) { e.printStackTrace(); } } /** * 获取Jedis实例 * @return */ public static Jedis getJedis() { try { if (jedisPool != null) { Jedis resource = jedisPool.getResource(); return resource; } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; } } /** * 释放jedis资源 * @param jedis */ public static void returnResource(final Jedis jedis) { if (jedis != null) { jedisPool.returnResource(jedis); } } }
三、连接池创建过程
上面例子连接池初始化代码如下;
JedisPoolConfig config = new JedisPoolConfig(); config.setMaxActive(MAX_ACTIVE); config.setMaxIdle(MAX_IDLE); config.setMaxWait(MAX_WAIT); config.setMaxWait(MAX_WAIT); config.setTestOnBorrow(TEST_ON_BORROW); jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
连接池一些配置信息如池中最大活跃数量、最大空闲数量等等被存储在JedisPoolConfig对象中。JedisPoolConfig继承commons-pool包中的Config类,是一个比较纯碎的javabean,不做过多阐述。
JedisPool继承commons-pool包中的Pool类,其初始化的过程是调用父类Pool类的构造器完成的。
public abstract class Pool<T> { private final GenericObjectPool internalPool; public Pool(final GenericObjectPool.Config poolConfig, PoolableObjectFactory factory) { this.internalPool = new GenericObjectPool(factory, poolConfig); }
Jedis把JedisFactory传工厂类给了父类的构造器,JedisFactory继承BasePoolableObjectFactory抽象类(BasePoolableObjectFactory实现了PoolableObjectFactory接口),重写了其中的makeObject方法。
public Object makeObject() throws Exception { final Jedis jedis = new Jedis(this.host, this.port, this.timeout); jedis.connect(); if (null != this.password) { jedis.auth(this.password); } if( database != 0 ) { jedis.select(database); } return jedis; }
makeObject方法提供了创建Jedis实例的功能,commons-pool在初始化池的时候调用我们传入的工厂类makeObject方法来创建要放入缓存池中的对象,这个地方用到了抽象工厂模式这样的设计思想。JedisFactory的makeObject方法做了这几件事:
(1)创建Jedis实例
(2)连接redis服务器
(3)如果redis服务器需要密码则向服务器提供密码
(4)如果指定数据库不是默认的0,则选择指定的数据库
下面是单个Jedis实例的构造很简单,目标就是要创建Client客户端实例保存到成员属性中,Client间接继承了Connection,Jedis的构造仅仅是把从Connection继承而来的三个属性主机地址、端口号和连接超时时间进行赋值:
public Connection(final String host, final int port) { super(); this.host = host; this.port = port; }
Jedis实例创建完之后利用Socket套接字和redis服务器进行连接,这个过程是在Connection类中进行的,建立连接之后将输入流和输出流保存到成员对象中,这样以后就可以向redis服务器发送命令,代码如下:
public void connect() { if (!isConnected()) { try { socket = new Socket(); //->@wjw_add socket.setReuseAddress(true); socket.setKeepAlive(true); //Will monitor the TCP connection is valid socket.setTcpNoDelay(true); //Socket buffer Whetherclosed, to ensure timely deliver//y of data socket.setSoLinger(true,0); //Control calls close () method, the underlying socket //is closed immediately //<-@wjw_add socket.connect(new InetSocketAddress(host, port), timeout); socket.setSoTimeout(timeout); outputStream = new RedisOutputStream(socket.getOutputStream()); inputStream = new RedisInputStream(socket.getInputStream()); } catch (IOException ex) { throw new JedisConnectionException(ex); } } }
这样redis连接池就完成了初始化的工作。
相关文章推荐
- Jedis出现connection timeout问题解决方法(JedisPool连接池使用实例)
- 理解Javascript_06_理解对象的创建过程
- Tomcat Session 共享 方法
- spring集成redis cluster
- jedis 连接池使用流程图
- jedis使用过程中遇到的异常
- reids使用
- spring-data-redis 使用过程中需要注意的一点
- Storm-Jedis-Redis自制测试程序(仅作分享与记录)
- Jedis connection refused
- Jedis connection refused
- Windows搭建本地Lua开发环境
- redis缓存配置(spring + maven)
- Jedis 最简单的例子分析
- Linux下Redis环境搭建教程&Jedis简单使用教程
- 实战 Redis 缓存(初级篇)
- 使用Redis的脚本功能实现Redis中数据简单查询
- Redis整合Spring
- 急求大婶指导redis Could not get a resource from the pool 异常
- Windows NoSql Redis 安装