package com.alibaba.doris.client.pool; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.doris.client.net.Connection; import com.alibaba.doris.client.net.ConnectionFactory; import com.alibaba.doris.client.net.exception.ClientConnectionException; public class ConnectionPool { private List<Connection> connectionHold; private AtomicInteger counter = new AtomicInteger(0); private String ip; private int port; public ConnectionPool(String ip, int port, int poolSize) { this.ip = ip; this.port = port; connectionHold = new ArrayList<Connection>(poolSize); for (int i = 0; i < poolSize; i++) { connectionHold.add(makeConnection(ip, port)); } } public Connection getConnection() { int index = Math.abs(counter.incrementAndGet()); // to skip Integer.MIN_VALUE; -2147483648 abs=-2147483648 if (index < 0) { index = 0; } index = (int) ((index) % connectionHold.size()); Connection c = connectionHold.get(index); if (false == checkConnection(c)) { synchronized (this) { c = connectionHold.get(index); if (!c.isConnected()) { // 如果老的connection无法重新建立连接,则关闭老连接 closeConnection(c); // 新建一个connection c = makeConnection(ip, port); if (checkConnection(c)) { connectionHold.set(index, c); } else { throw new ClientConnectionException(" Connecting remote server failed. The remote data server:" + ip + ":" + port); } } } } return c; } /** * 延迟建立连接,只有当连接真正使用到的时候才开始建立; * * @param connection * @return */ private boolean checkConnection(Connection connection) { synchronized (connection) { if (!connection.isConnected()) { return openConnection(connection); // if (!bResult) { // closeConnection(connection); // } } } return true; } private boolean openConnection(Connection connection) { try { connection.open(); } catch (Exception ignore) { logger.error("Open connection failed. ", ignore); return false; } return true; } private boolean closeConnection(Connection connection) { try { connection.close(); } catch (Exception ignore) { logger.error("Close connection failed. ", ignore); return false; } return true; } public void closeAll() { for (Connection c : connectionHold) { closeConnection(c); } } private Connection makeConnection(String ip, int port) { ConnectionFactory factory = ConnectionFactory.getInstance(); InetSocketAddress remoteAddress = new InetSocketAddress(ip, port); Connection connection = factory.getConnection(remoteAddress); return connection; } private static final Logger logger = LoggerFactory.getLogger(ConnectionPool.class); }