创建配置文件
server_info=192.168.28.121:8989
#设置后进先出的池策略
lifo=true
#允许最大活动对象数
maxTotal=1500
#允许最大空闲对象数
maxIdle=500
#允许最大等待时间毫秒数
maxWait=30000
#被空闲对象回收器回收前在池中保持空闲状态的最小时间毫秒数
minEvictableIdleTimeMillis=1800000
#允许最小空闲对象数
minIdle=50
#设定在进行后台对象清理时,每次检查对象数
numTestsPerEvictionRun=1
#指明是否在从池中取出对象前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.
testOnBorrow =false
#指明是否在归还到池中前进行检验
testOnReturn =false
#指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
testWhileIdle=true
#在空闲连接回收器线程运行期间休眠的时间毫秒数. 如果设置为非正数,则不运行空闲连接回收器线程
testOnCreate=false
timeBetweenEvictionRunsMillis=10000
#当池中对象用完时,请求新的对象所要执行的动作
whenExhaustedAction=1
连接池实现
import java.net.Socket;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import cn.guagua.mobile.common.PropertyFactory;
/**
* 连接池工厂
* @author admin
*
*/
public class ConnectionPoolFactory {
private GenericObjectPool<Socket> pool = null;
private static ConnectionPoolFactory instance = null;
public static ConnectionPoolFactory getInstance() {
if(instance == null) {
synchronized (ConnectionPoolFactory.class) {
if(instance == null) {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxIdle(Integer.parseInt(PropertyFactory.get("maxIdle")));
config.setMaxWaitMillis(Integer.parseInt(PropertyFactory.get("maxWait")));
config.setMinEvictableIdleTimeMillis(Integer.parseInt(PropertyFactory.get("minEvictableIdleTimeMillis")));
config.setMinIdle(Integer.parseInt(PropertyFactory.get("minIdle")));
config.setTestOnBorrow(Boolean.valueOf(PropertyFactory.get("testOnBorrow")));
config.setTestOnCreate(Boolean.valueOf(PropertyFactory.get("testOnCreate")));
config.setTestOnReturn(Boolean.valueOf(PropertyFactory.get("testOnReturn")));
config.setTestWhileIdle(Boolean.valueOf(PropertyFactory.get("testWhileIdle")));
config.setTimeBetweenEvictionRunsMillis(Integer.parseInt(PropertyFactory.get("timeBetweenEvictionRunsMillis")));
config.setMaxTotal(Integer.parseInt(PropertyFactory.get("maxTotal")));
config.setNumTestsPerEvictionRun(Integer.parseInt(PropertyFactory.get("numTestsPerEvictionRun")));
config.setLifo(Boolean.valueOf(PropertyFactory.get("lifo")));
String hosts = PropertyFactory.get("server_info");
instance = new ConnectionPoolFactory(config, hosts);
}
}
}
return instance;
}
private ConnectionPoolFactory(GenericObjectPoolConfig config, String hosts){
SocketConnectionFactory factory = new SocketConnectionFactory(hosts);
pool = new GenericObjectPool<Socket>(factory,config);
}
public Socket getConnection() throws Exception {
return pool.borrowObject();
}
public void releaseConnection(Socket socket){
try {
pool.returnObject(socket);
} catch(Throwable e) {
if(socket != null){
try{
socket.close();
}catch(Exception ex){
e.printStackTrace();
}
}
}
}
}
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.log4j.Logger;
import cn.guagua.mobile.common.protobuf.keepalive.LoginProxyRequest;
import cn.guagua.mobile.common.protobuf.keepalive.LoginProxyResponse;
/**
* Socket连接创建工厂
* @author admin
*
*/
public class SocketConnectionFactory extends BasePooledObjectFactory<Socket> {
private static final Logger logger = Logger.getLogger(SocketConnectionFactory.class);
private List<InetSocketAddress> socketAddress = null;
private final AtomicLong atomicLongCount;
public SocketConnectionFactory(String hosts) {
socketAddress = new ArrayList<InetSocketAddress>();
String[] hostsAdd = hosts.split(";");
if(hostsAdd.length > 0) {
for(String tmpHost : hostsAdd) {
String[] dataStrings = tmpHost.split(":");
InetSocketAddress address = new InetSocketAddress(dataStrings[0], Integer.parseInt(dataStrings[1]));
socketAddress.add(address);
}
}
atomicLongCount = new AtomicLong();
}
public static void main(String[] args) {
SocketConnectionFactory factory = new SocketConnectionFactory("127.0.0.1:8080;192.168.28.133:9090;192.168.21.122:8989;192.168.11.121:6666;192.168.43.221:9999");
for(int i=0; i<50; ++i) {
factory.getSocketAddress();
}
}
private InetSocketAddress getSocketAddress() {
int index = (int) (atomicLongCount.getAndIncrement() % socketAddress.size());
logger.info("调用C服务器地址:" + socketAddress.get(index).getHostName());
return socketAddress.get(index);
}
@Override
public void destroyObject(PooledObject<Socket> p) throws Exception {
Socket socket = p.getObject();
logger.info("销毁Socket:" + socket);
if(socket != null) {
socket.close();
}
}
@Override
public boolean validateObject(PooledObject<Socket> p) {
Socket socket = p.getObject();
if(socket != null) {
if(!socket.isConnected()) {
return false;
}
if(socket.isClosed()) {
return false;
}
//发送心跳
LoginProxyRequest proxyRequest = null;
LoginProxyResponse proxyResponse = null;
try {
proxyRequest = new LoginProxyRequest(socket.getOutputStream());
proxyRequest.send(proxyRequest.pack());
proxyResponse = new LoginProxyResponse(socket.getInputStream());
proxyResponse.unpack(proxyResponse.readIn());
return proxyResponse.isAlive();
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
return false;
}
@Override
public Socket create() throws Exception {
Socket socket = new Socket();
socket.connect(getSocketAddress());
return socket;
}
@Override
public PooledObject<Socket> wrap(Socket obj) {
return new DefaultPooledObject<Socket>(obj);
}
}