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