jdeis 分析
入口代码
JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), hnp.getPort(), 2000);
逐步跟进会初始化一个JedisFactory通过构造方法把后面需要的值提前赋值: 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) { super(poolConfig, new JedisFactory(host, port, connectionTimeout, soTimeout, password, database, clientName)); } 继续深入点入会初始化连接池: 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
GenericObjectPool是apache提供的对象池,需要的参数是PooledObjectFactory,jedis中传入JedisFactory, 有很多作用,比如连接池中没有对象时,可以调用makeObject方法创建一个连接对象 GenericObjectPool的构造方法: this.idleObjects = new LinkedBlockingDeque(config.getFairness()); 初始化一个队列存放连接 获取池中的对象是通过GenericObjectPool的borrowObject()方法
回到jedis获取连接
Jedis jedis = pool.getResource(); 获取一个jedis getResource: return internalPool.borrowObject(); 对应上面的GenericObjectPool public T borrowObject() throws Exception { return this.borrowObject(this.getMaxWaitMillis());//最大等待时间 } 没有连接的时候会去创建: p = (PooledObject)this.idleObjects.pollFirst(); if (p == null) { p = this.create();//会执行JedisFactory.makeObject方法,创建socket if (p != null) { create = true; } } validate = this.factory.validateObject(p);判断连接是否可用 (通过发送ping命令)
JedisFactory.makeObject 方法分析
public PooledObject<Jedis> makeObject() throws Exception { final HostAndPort hostAndPort = this.hostAndPort.get(); final Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort(), connectionTimeout, soTimeout, ssl, sslSocketFactory, sslParameters, hostnameVerifier); try { jedis.connect(); if (password != null) { jedis.auth(password); } if (database != 0) { jedis.select(database); } if (clientName != null) { jedis.clientSetname(clientName); } } catch (JedisException je) { jedis.close(); throw je; } return new DefaultPooledObject<Jedis>(jedis); } 构造BinaryJedis (BinaryClient extends Connection) public BinaryJedis(final String host, final int port, final int connectionTimeout, final int soTimeout, final boolean ssl, final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) { client = new Client(host, port, ssl, sslSocketFactory, sslParameters, hostnameVerifier); client.setConnectionTimeout(connectionTimeout); client.setSoTimeout(soTimeout); } 创建连接: public void connect() { if (!isConnected()) { super.connect(); if (password != null) { auth(password); getStatusCodeReply(); } if (db > 0) { select(db); getStatusCodeReply(); } } } Connection中的connect方法: 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 delivery of data socket.setSoLinger(true, 0); // Control calls close () method, // the underlying socket is closed // immediately // <-@wjw_add socket.connect(new InetSocketAddress(host, port), connectionTimeout); socket.setSoTimeout(soTimeout); if (ssl) { if (null == sslSocketFactory) { sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault(); } socket = sslSocketFactory.createSocket(socket, host, port, true); if (null != sslParameters) { ((SSLSocket) socket).setSSLParameters(sslParameters); } if ((null != hostnameVerifier) && (!hostnameVerifier.verify(host, ((SSLSocket) socket).getSession()))) { String message = String.format( "The connection to '%s' failed ssl/tls hostname verification.", host); throw new JedisConnectionException(message); } } outputStream = new RedisOutputStream(socket.getOutputStream()); inputStream = new RedisInputStream(socket.getInputStream()); } catch (IOException ex) { broken = true; throw new JedisConnectionException("Failed connecting to host " + host + ":" + port, ex); } } } 具体执行命令: jedis.set("foo", "bar"); public String set(final String key, final String value) { checkIsInMultiOrPipeline(); client.set(key, value); return client.getStatusCodeReply(); } connect(); Protocol.sendCommand(outputStream, cmd, args);
- 归还连接到池子
jedis.close(); pool.destroy(); internalPool.returnObject(resource); 归还资源到连接池