MongoDb连接池源码追踪

1. 先来看构建MongoClient使用的参数

MongoClientOptions.Builder optionsBuilder = builder()
                .applicationName(applicationName)
                .maxConnectionIdleTime(config.getMaxConnectionIdleTime() == 0 ?
                        MAX_CONNECTION_IDLE_TIME : config.getMaxConnectionIdleTime())
                .connectionsPerHost(config.getConnectionsPerHost() == 0 ?
                        MAX_MONGO_CONNECTION_PER_HOST : config.getConnectionsPerHost())
                .threadsAllowedToBlockForConnectionMultiplier(config.getThreadsAllowedToBlockForConnectionMultiplier() == 0 ?
                        CONNECTION_MULTIPLIER : config.getThreadsAllowedToBlockForConnectionMultiplier())
                // 鎻愰珮闃熷垪闀垮害
                .maxWaitTime(config.getMaxWaitTime() == 0 ?
                        TIME_OUT : config.getMaxWaitTime())
                .connectTimeout(config.getConnectTimeout() == 0 ?
                        TIME_OUT : config.getConnectTimeout())
                .socketTimeout(config.getSocketTimeout() == 0 ?
                        TIME_OUT : config.getSocketTimeout())
                .serverSelectionTimeout(config.getServerSelectionTimeout() == 0 ?
                        TIME_OUT : config.getServerSelectionTimeout())
                .socketKeepAlive(true)
                .addServerListener(new MongoServerListener())
                .addCommandListener(new MongoClientListener());
        List<MongoCredential> credentials = MongoCredentialPropertyUtils.getCredentials(config.getCredentials());
        if (!config.isStandalone()) {
            optionsBuilder.readPreference(readPreferenceEnum.getReadPreference());
        }
        List<String> servers = config.getServers();
        MongoClient client;
        if (!config.isStandalone()) {
            List<ServerAddress> addresses = asList(
                    servers.stream()
                            .map(server -> {
                                if (server.contains(":")) {
                                    String[] hosts = server.split(":");
                                    return new ServerAddress(hosts[0], Integer.parseInt(hosts[1]));
                                }
                                return new ServerAddress(server);
                            }).toArray(ServerAddress[]::new));
            if (CollectionUtils.isNotEmpty(credentials)) {
                client = new MongoClient(addresses, credentials, optionsBuilder.build());
            } else {
                client = new MongoClient(addresses, optionsBuilder.build());
            }
        } else {
            if (CollectionUtils.isNotEmpty(credentials)) {
                client = new MongoClient(new ServerAddress(servers.get(0)), credentials, optionsBuilder.build());
            } else {
                client = new MongoClient(new ServerAddress(servers.get(0)), optionsBuilder.build());
            }
        }
        client.listDatabaseNames();

2.MongoClientOptions类

我们重点看一下MongoClientOptions及MongoClientOptions.Builder中与连接池相关的部分

如果我们要对连接池做一些监控,需要在外层注册JMXConnectionPoolListener到connectionPoolListeners里

        ConnectionPoolSettings.Builder connectionPoolSettingsBuilder = ConnectionPoolSettings.builder()
                .minSize(getMinConnectionsPerHost())
                .maxSize(getConnectionsPerHost())
                .maxWaitQueueSize(getThreadsAllowedToBlockForConnectionMultiplier() * getConnectionsPerHost())
                .maxWaitTime(getMaxWaitTime(), MILLISECONDS)
                .maxConnectionIdleTime(getMaxConnectionIdleTime(), MILLISECONDS)
                .maxConnectionLifeTime(getMaxConnectionLifeTime(), MILLISECONDS);

        for (ConnectionPoolListener connectionPoolListener : builder.connectionPoolListeners) {
            connectionPoolSettingsBuilder.addConnectionPoolListener(connectionPoolListener);
        }

3.JMXConnectionPoolListener

我们来看看JMXConnectionPoolListener这个类做了什么

public class JMXConnectionPoolListener implements ConnectionPoolListener {
    private final ConcurrentMap<ServerId, ConnectionPoolStatistics> map =
        new ConcurrentHashMap<ServerId, ConnectionPoolStatistics>();

    @Override
    public void connectionPoolOpened(final ConnectionPoolOpenedEvent event) {
        ConnectionPoolStatistics statistics = new ConnectionPoolStatistics(event);
        map.put(event.getServerId(), statistics);
        MBeanServerFactory.getMBeanServer().registerMBean(statistics, getMBeanObjectName(event.getServerId()));
    }

    @Override
    public void connectionPoolClosed(final ConnectionPoolClosedEvent event) {
        map.remove(event.getServerId());
        MBeanServerFactory.getMBeanServer().unregisterMBean(getMBeanObjectName(event.getServerId()));
    }

    @Override
    public void connectionCheckedOut(final ConnectionCheckedOutEvent event) {
        ConnectionPoolStatistics statistics = getStatistics(event.getConnectionId());
        if (statistics != null) {
            statistics.connectionCheckedOut(event);
        }
    }

    @Override
    public void connectionCheckedIn(final ConnectionCheckedInEvent event) {
        ConnectionPoolStatistics statistics = getStatistics(event.getConnectionId());
        if (statistics != null) {
            statistics.connectionCheckedIn(event);
        }
    }

    @Override
    public void waitQueueEntered(final ConnectionPoolWaitQueueEnteredEvent event) {
        ConnectionPoolListener statistics = getStatistics(event.getServerId());
        if (statistics != null) {
            statistics.waitQueueEntered(event);
        }
    }

    @Override
    public void waitQueueExited(final ConnectionPoolWaitQueueExitedEvent event) {
        ConnectionPoolListener statistics = getStatistics(event.getServerId());
        if (statistics != null) {
            statistics.waitQueueExited(event);
        }
    }

    @Override
    public void connectionAdded(final ConnectionAddedEvent event) {
        ConnectionPoolStatistics statistics = getStatistics(event.getConnectionId());
        if (statistics != null) {
            statistics.connectionAdded(event);
        }
    }

    @Override
    public void connectionRemoved(final ConnectionRemovedEvent event) {
        ConnectionPoolStatistics statistics = getStatistics(event.getConnectionId());
        if (statistics != null) {
            statistics.connectionRemoved(event);
        }
    }

    String getMBeanObjectName(final ServerId serverId) {
        String name = format("org.mongodb.driver:type=ConnectionPool,clusterId=%s,host=%s,port=%s",
                             ensureValidValue(serverId.getClusterId().getValue()),
                             ensureValidValue(serverId.getAddress().getHost()),
                             serverId.getAddress().getPort());
        if (serverId.getClusterId().getDescription() != null) {
            name = format("%s,description=%s", name, ensureValidValue(serverId.getClusterId().getDescription()));
        }
        return name;
    }

    // for unit test
    ConnectionPoolStatisticsMBean getMBean(final ServerId serverId) {
        return getStatistics(serverId);
    }

    private ConnectionPoolStatistics getStatistics(final ConnectionId connectionId) {
        return getStatistics(connectionId.getServerId());
    }

    private ConnectionPoolStatistics getStatistics(final ServerId serverId) {
        return map.get(serverId);
    }

    private String ensureValidValue(final String value) {
        if (containsQuotableCharacter(value)) {
            return ObjectName.quote(value);
        } else {
            return v
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值