jedis源码分析(二)-JedisPool连接池实现

上一章节我们通过jedis学习了实现存放机制,本章节我们通过jedisPool的操作理解连接池的应用,jedisPool的源码实现。
jedisPool连接池示例
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisPoolUtil {

    private volatile JedisPool pool;
    private Jedis jedis;
    private final String host;
    private final int port;
    private String password;

    public JedisPoolUtil(final String host, final int port) {
        this.host = host;
        this.port = port;
        initPool();
    }

    public JedisPoolUtil(final String host, final int port, final String password) {
        this.host = host;
        this.port = port;
        this.password = password;
        initPool();
    }

    public JedisPool initPool() {
        if (pool == null) {
            if (password != null) {
                JedisPoolConfig config = new JedisPoolConfig();
                config.setMaxIdle(100);
                config.setMaxWaitMillis(1000);
                // 设置空间连接
                config.setMaxIdle(10);
                pool = new JedisPool(config, host, port, 2000, password);
            } else {
                pool = new JedisPool(host, port);
            }
            System.out.println("连接池创建成功");
        }
        return pool;
    }

    public Jedis initJedis() {
        if(jedis==null) {
            jedis = pool.getResource();
        }
        System.out.println("jedis创建成功");
        return jedis;
    }

    public String set(String key, String value) {
        if (jedis == null) {
            jedis = initJedis();
        }
        String result = jedis.set(key, value);
        if ("OK".equals(result)) {
            jedis.close();
        }
        return result;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            JedisPoolUtil jedisPoolUtil = new JedisPoolUtil("127.0.0.1", 4100);
            System.out.println(jedisPoolUtil.set("test" + i, "value" + i));
        }
    }

}

使用jedisPool连接池,实例化jedisPool对象,jedisPool类提供了很多构造方法,可以根据自己的需要去选择构造方法,
  public JedisPool(String host , int port ) {
    this ( new GenericObjectPoolConfig(), host , port , Protocol. DEFAULT_TIMEOUT , null ,
        Protocol. DEFAULT_DATABASE , null );
  }
  public JedisPool ( final GenericObjectPoolConfig poolConfig , final String host , int port ,
      final int connectionTimeout , final int soTimeout , final String password , final int database ,
      final String clientName , final boolean ssl , final SSLSocketFactory sslSocketFactory ,
      final SSLParameters sslParameters , final HostnameVerifier hostnameVerifier ) {
    super ( poolConfig , new JedisFactory( host , port , connectionTimeout , soTimeout , password ,
        database , clientName , ssl , sslSocketFactory , sslParameters , hostnameVerifier ));
  }
  public JedisPool( final GenericObjectPoolConfig poolConfig , final URI uri , final int timeout ,
      final SSLSocketFactory sslSocketFactory , final SSLParameters sslParameters ,
      final HostnameVerifier hostnameVerifier ) {
    this ( poolConfig , uri , timeout , timeout , sslSocketFactory , sslParameters , hostnameVerifier );
  }
  public JedisPool( final GenericObjectPoolConfig poolConfig , final URI uri ,
      final int connectionTimeout , final int soTimeout ) {
    super ( poolConfig , new JedisFactory( uri , connectionTimeout , soTimeout , null , false ,
        null , null , null ));
  }
  public JedisPool( final GenericObjectPoolConfig poolConfig , final URI uri ,
      final int connectionTimeout , final int soTimeout , final SSLSocketFactory sslSocketFactory ,
      final SSLParameters sslParameters , final HostnameVerifier hostnameVerifier ) {
    super ( poolConfig , new JedisFactory( uri , connectionTimeout , soTimeout , null ,
        ( uri .getScheme() != null && uri .getScheme().equals( "rediss" )), sslSocketFactory ,
        sslParameters , hostnameVerifier ));
  }
这里实例化了一个实现了
org.apache.commons.pool2.PooledObjectFactory<Jedis>接口类的JedisFactory工厂类对象,该所有对象的创建销毁、激活和有效性验证都在JedisFactory工厂类中进行,
poolObjectFactory提供了五个接口方法:
public interface PooledObjectFactory<T> {
  PooledObject<T> makeObject() throws Exception;// 创建对象的方法
  void destroyObject(PooledObject<T> p ) throws Exception;// 销毁对象的方法。
  boolean validateObject(PooledObject<T> p );  // 校验对象有消息的方法。
  void activateObject(PooledObject<T> p ) throws Exception;// 激活对象的方法
  void passivateObject(PooledObject<T> p ) throws Exception;// 钝化对象的方法。 返回到空闲对象实例池
}

由于jedisPool继承了 Pool<Jedis>,Pool实现了 Closeable接口,最终委托了pool的实例化方法,调用了Pool类中的initPoll方法,在initPool方法中new了一个 GenericObjectPool方法,该方法是 org . apache . commons . pool2 . impl . GenericObjectPool .GenericObjectPool中的连接池实现方法
public Pool ( final GenericObjectPoolConfig poolConfig , PooledObjectFactory<T> factory ) {
    initPool( poolConfig , factory );
  }

  public void initPool( final GenericObjectPoolConfig poolConfig , PooledObjectFactory<T> factory ) {
    if ( this . internalPool != null ) {
      try {
        closeInternalPool();
      } catch (Exception e ) {
      }
    }
    this . internalPool = new GenericObjectPool <T>( factory , poolConfig );
  }
GenericObjectPool方法中有两个参数:一个 GenericObjectPoolConfig配置项分装类,一个是 PooledObjectFactory工厂类
获取到连接池后从连接池中获取jedis连接对象
  @Override
  public Jedis getResource () {
    Jedis jedis = super .getResource();
    jedis .setDataSource( this );
    return jedis ;
  }

  public T getResource () {
    try {
      return internalPool .borrowObject();
    } catch (NoSuchElementException nse ) {
      throw new JedisException( "Could not get a resource from the pool" , nse );
    } catch (Exception e ) {
      throw new JedisConnectionException( "Could not get a resource from the pool" , e );
    }
  }
对于jedis Pool只能进行单实例的链接操作,但是对于数据量大的时候,单实例不能满足需求. 这个时候就需要对实例进行“分片”。Jedis也是提供了分片的支持,后面也会总结一个jedis分片的实现.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值