连接池Commons Pool2的使用

客户端这边,如果每次都临时建立一个新的连接,那么连接的开销非常大。

业内常用的连接池组件是 Commons Pool2---版本 2.4.2

==================具体代码如下:[http://commons.apache.org/proper/commons-pool/examples.html]

package service.pool;

 

import org.apache.commons.pool2.BasePooledObjectFactory;

import org.apache.commons.pool2.PooledObject;

import org.apache.commons.pool2.impl.DefaultPooledObject;

import org.apache.thrift.transport.TSocket;

 

public class MyPoolFactory extends BasePooledObjectFactory<TSocket> {

 

private String ip;

private int port;

 

public MyPoolFactory(String stringint i) {

ip = string;

port = i;

}

 

@Override

public TSocket create() throws Exception {

// 初始化一个对象

TSocket ts = new TSocket(ipport);

ts.open();

return ts;

}

 

@Override

public PooledObject<TSocket> wrap(TSocket ts) {

// 默认操作

return new DefaultPooledObject<TSocket>(ts);

}

 

/// 下面是5个生命周期

//makeObject默认

@Override

public void destroyObject(PooledObject<TSocket> pthrows Exception {

TSocket ts = p.getObject();

ts.close();

}

 

@Override

public boolean validateObject(PooledObject<TSocket> p) {

TSocket ts = p.getObject();

return ts.isOpen();

这里其实有一个bug http://zhidao.baidu.com/link?url=YEK1sMh5-QEgLfDmkJGLv05KiEzS6AmFyoRC37aTpL13lxYAYsfmp8nwPX6oVQztZx_LtvDljlzO2r6rYLYVD2EO-n69sN-6Uo0cfZNGPie

通过发送紧急数据解决此问题,Thrift服务器端不要开启对应的设置,经过测试OK.

 

然后,后来又想到,我自己写一个MyTSocket 继承TSocket,然后一旦业务线程拿到连接池给我的一个MyTSocket(注意:此时可能socket无效)

然后业务线程使用过程中发现有异常,则设置MyTSocket的一个属性为false,连接池检测时兼顾这个属性就可以了。

 

最后发现这个还不能彻底解决问题,jedis采用的是业务探测:ping-pong,这个是redis自己的协议

对于其它的服务器怎么办?我们查了百度,采用的办法是:

 

@Override

public boolean validateObject(PooledObject<MyTSocket> p) {

MyTSocket t = p.getObject();

Socket s = t.getSocket();

boolean closed = s.isClosed();

boolean connected = s.isConnected();

boolean outputShutdown = s.isOutputShutdown();

boolean inputShutdown = s.isInputShutdown();

boolean urgentFlag = false;

try {

s.sendUrgentData(0xFF); //在这里

urgentFlag = true; //测试OK, http://cuisuqiang.iteye.com/blog/1453632

http://blog.csdn.net/vigarbuaa/article/details/7066352

catch (IOException e) {

}

return urgentFlag && connected && !closed && !inputShutdown && !outputShutdown && t.isAlive();

}

 

 

}

 

@Override

public void activateObject(PooledObject<TSocket> pthrows Exception {

// 返回给调用方时,做一些额外的操作

}

 

/**

 * When an object is returned to the pool, clear the buffer.

 */

@Override

public void passivateObject(PooledObject<TSocket> tSocket) {

// 返回到pool时,做一些额外的操作

}

 

}

 

============================

具体使用时

// 设置传输通道,对于非阻塞服务,需要使用TFramedTransport,它将数据分块发送

GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();

 

poolConfig.setBlockWhenExhausted(true);

poolConfig.setMaxWaitMillis(100);

 

poolConfig.setLifo(false);

poolConfig.setMaxIdle(50); 最大空闲连接数

poolConfig.setMinIdle(50);// 最小空闲连接数

poolConfig.setMaxTotal(100);// 整个池的最大值,最大连接数

 

poolConfig.setTestOnBorrow(true);

poolConfig.setTestOnCreate(true);

poolConfig.setTestOnReturn(true);

poolConfig.setTestWhileIdle(false);

 

GenericObjectPool pools = new GenericObjectPool<TSocket>(new MyPoolFactory("127.0.0.1", 7911),poolConfig);

// 具体使用代码

TSocket ts = (TSocket) pools.borrowObject();

 pools.returnObject(ts);

转载于:https://my.oschina.net/qiangzigege/blog/517541

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值