
com.taobao.tair.comm.TairClientFactory Maven / Gradle / Ivy
/**
* (C) 2007-2010 Taobao Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
package com.taobao.tair.comm;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ConnectFuture;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.ThreadModel;
import org.apache.mina.transport.socket.nio.SocketConnector;
import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
import com.taobao.tair.etc.TairClientException;
import com.taobao.tair.etc.TairUtil;
import com.taobao.tair.packet.PacketStreamer;
public class TairClientFactory {
private static final Log LOGGER = LogFactory.getLog(TairClientFactory.class);
private static final int processorCount = Runtime.getRuntime()
.availableProcessors() + 1;
private static final String CONNECTOR_THREADNAME = "TAIRCLIENT";
private static final ThreadFactory CONNECTOR_TFACTORY = new NamedThreadFactory(
CONNECTOR_THREADNAME);
private static final TairClientFactory factory = new TairClientFactory();
private static final int MIN_CONN_TIMEOUT = 1000;
private final SocketConnector ioConnector;
private final ConcurrentHashMap> clients = new ConcurrentHashMap>();
private TairClientFactory() {
ioConnector = new SocketConnector(processorCount, Executors
.newCachedThreadPool(CONNECTOR_TFACTORY));
}
public static TairClientFactory getInstance() {
return factory;
}
public TairClient get(final String targetUrl, final int connectionTimeout, final PacketStreamer pstreamer)
throws TairClientException {
String key = targetUrl;
if (clients.containsKey(key)) {
try {
TairClient client = clients.get(key).get();
long now = System.currentTimeMillis();
//超时的client关闭掉重新建立
//目前先写死为300秒过期
if (now - client.getLastPacketTime() > 300000) {
//关闭连接
LOGGER.warn("回收超时的连接," + client.toString());
removeClient(key);
client.close(true);
} else {
return client;
}
} catch (Exception e) {
removeClient(key);
throw new TairClientException(
"get tair connection error,targetAddress is "
+ targetUrl, e);
}
}
//real connect
{
FutureTask task = new FutureTask(
new Callable() {
public TairClient call() throws Exception {
return createClient(targetUrl, connectionTimeout, pstreamer);
}
});
FutureTask existTask = clients.putIfAbsent(key, task);
if (existTask == null) {
existTask = task;
task.run();
}
try {
return existTask.get();
} catch (Exception e) {
removeClient(key);
throw new TairClientException(
"get tair connection error,targetAddress is "
+ targetUrl, e);
}
}
}
protected void removeClient(String key) {
clients.remove(key);
}
private TairClient createClient(String targetUrl, int connectionTimeout, PacketStreamer pstreamer)
throws Exception {
SocketConnectorConfig cfg = new SocketConnectorConfig();
cfg.setThreadModel(ThreadModel.MANUAL);
if (connectionTimeout < MIN_CONN_TIMEOUT)
connectionTimeout = MIN_CONN_TIMEOUT;
cfg.setConnectTimeout((int) connectionTimeout / 1000);
cfg.getSessionConfig().setTcpNoDelay(true);
cfg.getFilterChain().addLast("objectserialize",
new TairProtocolCodecFilter(pstreamer));
String address = TairUtil.getHost(targetUrl);
int port = TairUtil.getPort(targetUrl);
SocketAddress targetAddress = new InetSocketAddress(address, port);
TairClientProcessor processor = new TairClientProcessor();
ConnectFuture connectFuture = ioConnector.connect(targetAddress, null,
processor, cfg);
connectFuture.join();
IoSession ioSession = connectFuture.getSession();
if ((ioSession == null) || (!ioSession.isConnected())) {
throw new Exception(
"create tair connection error,targetaddress is "
+ targetUrl);
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("create tair connection success,targetaddress is "
+ targetUrl);
}
TairClient client = new TairClient(ioSession,targetUrl);
processor.setClient(client);
processor.setFactory(this, targetUrl);
return client;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy