Search in sources :

Example 1 with Connection

use of com.alipay.remoting.Connection in project sofa-rpc by sofastack.

the class ReuseBoltClientConnectionManagerTest method testAll.

@Test
public void testAll() throws Exception {
    ReuseBoltClientConnectionManager manager = new ReuseBoltClientConnectionManager(false);
    Connection connection = manager.getConnection(null, null, null);
    Assert.assertNull(connection);
    connection = manager.getConnection(rpcClient, null, null);
    Assert.assertNull(connection);
    ClientTransportConfig wrongConfig = buildConfig(12224);
    connection = manager.getConnection(rpcClient, wrongConfig, null);
    Assert.assertNull(connection);
    // 连不上的端口
    Connection result = manager.getConnection(rpcClient, wrongConfig, buildUrl(wrongConfig));
    Assert.assertNull(result);
    // ok
    final ClientTransportConfig config = buildConfig(12222);
    connection = manager.getConnection(rpcClient, config, buildUrl(config));
    Assert.assertNotNull(connection);
    Assert.assertTrue(manager.urlConnectionMap.size() == 1);
    Assert.assertTrue(manager.connectionRefCounter.size() == 1);
    Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 1);
    // 同一个config去get,计数器不增加
    Connection connection1 = manager.getConnection(rpcClient, config, buildUrl(config));
    Assert.assertNotNull(connection1);
    Assert.assertTrue(manager.urlConnectionMap.size() == 1);
    Assert.assertTrue(manager.connectionRefCounter.size() == 1);
    Assert.assertTrue(connection == connection1);
    Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 1);
    Assert.assertTrue(manager.connectionRefCounter.get(connection1).get() == 1);
    // 相同地址的config去get,计数器加一
    final ClientTransportConfig config2 = buildConfig(12222);
    Connection connection2 = manager.getConnection(rpcClient, config2, buildUrl(config2));
    Assert.assertNotNull(connection2);
    Assert.assertTrue(manager.urlConnectionMap.size() == 2);
    Assert.assertTrue(manager.connectionRefCounter.size() == 1);
    Assert.assertTrue(connection1 == connection2);
    Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 2);
    Assert.assertTrue(manager.connectionRefCounter.get(connection2).get() == 2);
    // 不同地址的config去get,地址和计数器加1
    ClientTransportConfig config3 = buildConfig(12223);
    Connection connection3 = manager.getConnection(rpcClient, config3, buildUrl(config3));
    Assert.assertNotNull(connection3);
    Assert.assertFalse(connection == connection3);
    Assert.assertTrue(manager.urlConnectionMap.size() == 3);
    Assert.assertTrue(manager.connectionRefCounter.size() == 2);
    Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 2);
    Assert.assertTrue(manager.connectionRefCounter.get(connection3).get() == 1);
    // 非法关闭
    manager.closeConnection(null, null, null);
    Assert.assertTrue(manager.urlConnectionMap.size() == 3);
    manager.closeConnection(rpcClient, null, null);
    Assert.assertTrue(manager.urlConnectionMap.size() == 3);
    manager.closeConnection(rpcClient, config, null);
    Assert.assertTrue(manager.urlConnectionMap.size() == 3);
    // 正常关闭1
    manager.closeConnection(rpcClient, config, buildUrl(config));
    Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 1);
    // 重复关闭1
    manager.closeConnection(rpcClient, config, buildUrl(config));
    Assert.assertTrue(manager.urlConnectionMap.size() == 2);
    Assert.assertTrue(manager.connectionRefCounter.size() == 2);
    Assert.assertTrue(manager.connectionRefCounter.get(connection).get() == 1);
    // 正常关闭2
    manager.closeConnection(rpcClient, config2, buildUrl(config2));
    Assert.assertTrue(manager.urlConnectionMap.size() == 1);
    Assert.assertTrue(manager.connectionRefCounter.size() == 1);
    // 正常关闭3
    manager.closeConnection(rpcClient, config3, buildUrl(config3));
    Assert.assertTrue(manager.urlConnectionMap.size() == 0);
    Assert.assertTrue(manager.connectionRefCounter.size() == 0);
    // 检查泄漏
    manager.checkLeak();
    Assert.assertTrue(CommonUtils.isEmpty(manager.urlConnectionMap));
    Assert.assertTrue(CommonUtils.isEmpty(manager.connectionRefCounter));
}
Also used : Connection(com.alipay.remoting.Connection) ClientTransportConfig(com.alipay.sofa.rpc.transport.ClientTransportConfig) Test(org.junit.Test) ActivelyDestroyTest(com.alipay.sofa.rpc.test.ActivelyDestroyTest)

Example 2 with Connection

use of com.alipay.remoting.Connection in project sofa-rpc by sofastack.

the class ReuseBoltClientConnectionManagerTest method testConcurrentCreate.

@Test
public void testConcurrentCreate() throws Exception {
    final ReuseBoltClientConnectionManager manager = new ReuseBoltClientConnectionManager(false);
    final ClientTransportConfig config = buildConfig(12222);
    // 并发创建
    final CountDownLatch latch = new CountDownLatch(5);
    List<Thread> threads = new ArrayList<Thread>(5);
    final Url url = buildUrl(config);
    for (int i = 0; i < 5; i++) {
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Connection innerConnection = manager.getConnection(rpcClient, config, url);
                    System.out.println("url=" + url + ",connection=" + innerConnection);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    latch.countDown();
                }
            }
        }, "thread" + i);
        threads.add(thread);
    }
    for (Thread thread : threads) {
        thread.start();
    }
    latch.await(5000, TimeUnit.MILLISECONDS);
    Assert.assertEquals(1, manager.urlConnectionMap.size());
    Assert.assertEquals(1, manager.connectionRefCounter.size());
    Connection connection = manager.getConnection(rpcClient, config, url);
    Assert.assertNotNull(connection);
    final AtomicInteger atomicInteger = manager.connectionRefCounter.get(connection);
    Assert.assertEquals(1, atomicInteger.get());
    // 检查泄漏
    manager.checkLeak();
    Assert.assertTrue(CommonUtils.isEmpty(manager.urlConnectionMap));
    Assert.assertTrue(CommonUtils.isEmpty(manager.connectionRefCounter));
}
Also used : ArrayList(java.util.ArrayList) Connection(com.alipay.remoting.Connection) CountDownLatch(java.util.concurrent.CountDownLatch) Url(com.alipay.remoting.Url) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ClientTransportConfig(com.alipay.sofa.rpc.transport.ClientTransportConfig) Test(org.junit.Test) ActivelyDestroyTest(com.alipay.sofa.rpc.test.ActivelyDestroyTest)

Example 3 with Connection

use of com.alipay.remoting.Connection in project sofa-rpc by sofastack.

the class ReuseBoltClientConnectionManager method closeConnection.

/**
 * 关闭长连接
 *
 * @param rpcClient       bolt客户端
 * @param transportConfig 传输层配置
 * @param url             传输层地址
 */
@Override
public void closeConnection(RpcClient rpcClient, ClientTransportConfig transportConfig, Url url) {
    if (rpcClient == null || transportConfig == null || url == null) {
        return;
    }
    // 先删除
    Connection connection = urlConnectionMap.remove(transportConfig);
    if (connection == null) {
        return;
    }
    // 再判断是否需要关闭
    boolean needDestroy;
    AtomicInteger integer = connectionRefCounter.get(connection);
    if (integer == null) {
        needDestroy = true;
    } else {
        // 当前连接引用数
        int currentCount = integer.decrementAndGet();
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Client transport {} of {} , current ref count is: {}", url.toString(), NetUtils.channelToString(connection.getLocalAddress(), connection.getRemoteAddress()), currentCount);
        }
        if (currentCount <= 0) {
            // 此长连接无任何引用,可以销毁
            connectionRefCounter.remove(connection);
            needDestroy = true;
        } else {
            needDestroy = false;
        }
    }
    if (needDestroy) {
        rpcClient.closeStandaloneConnection(connection);
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Connection(com.alipay.remoting.Connection)

Example 4 with Connection

use of com.alipay.remoting.Connection in project sofa-rpc by sofastack.

the class ReuseBoltClientConnectionManager method getConnection.

/**
 * 通过配置获取长连接
 *
 * @param rpcClient       bolt客户端
 * @param transportConfig 传输层配置
 * @param url             传输层地址
 * @return 长连接
 */
@Override
public Connection getConnection(RpcClient rpcClient, ClientTransportConfig transportConfig, Url url) {
    if (rpcClient == null || transportConfig == null || url == null) {
        return null;
    }
    Connection connection = urlConnectionMap.get(transportConfig);
    if (connection != null && !connection.isFine()) {
        closeConnection(rpcClient, transportConfig, url);
        connection = null;
    }
    if (connection == null) {
        try {
            connection = rpcClient.getConnection(url, url.getConnectTimeout());
        } catch (Exception e) {
            LOGGER.warn("get connection failed in url," + url);
        }
        if (connection == null) {
            return null;
        }
        // 保存唯一长连接
        Connection oldConnection = urlConnectionMap.putIfAbsent(transportConfig, connection);
        if (oldConnection != null) {
            if (LOGGER.isWarnEnabled()) {
                LOGGER.warn("Multiple threads init ClientTransport with same key:" + url);
            }
            // only if new connection is not equals old connection,we can close it
            if (connection != oldConnection) {
                // 如果同时有人插入,则使用第一个
                rpcClient.closeStandaloneConnection(connection);
                connection = oldConnection;
            }
        } else {
            // 增加计数器
            AtomicInteger counter = connectionRefCounter.get(connection);
            if (counter == null) {
                counter = new AtomicInteger(0);
                AtomicInteger oldCounter = connectionRefCounter.putIfAbsent(connection, counter);
                if (oldCounter != null) {
                    counter = oldCounter;
                }
            }
            int currentCount = counter.incrementAndGet();
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Bolt client transport {} of {}, current ref count is: {}", url.toString(), NetUtils.channelToString(connection.getLocalAddress(), connection.getRemoteAddress()), currentCount);
            }
        }
    }
    return connection;
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Connection(com.alipay.remoting.Connection)

Aggregations

Connection (com.alipay.remoting.Connection)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 ActivelyDestroyTest (com.alipay.sofa.rpc.test.ActivelyDestroyTest)2 ClientTransportConfig (com.alipay.sofa.rpc.transport.ClientTransportConfig)2 Test (org.junit.Test)2 Url (com.alipay.remoting.Url)1 ArrayList (java.util.ArrayList)1 CountDownLatch (java.util.concurrent.CountDownLatch)1