解决:com.mongodb.MongoSocketOpenException: Exception opening socket

背景

springboot项目启动时,报错

com.mongodb.MongoSocketOpenException: Exception opening socket
	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70) ~[mongodb-driver-core-3.11.2.jar:na]
	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:128) ~[mongodb-driver-core-3.11.2.jar:na]
	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117) ~[mongodb-driver-core-3.11.2.jar:na]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]
Caused by: java.net.ConnectException: Connection refused: connect
	at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[na:1.8.0_181]
	at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) ~[na:1.8.0_181]
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_181]
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_181]
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_181]
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.8.0_181]
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_181]
	at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_181]
	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:64) ~[mongodb-driver-core-3.11.2.jar:na]
	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:79) ~[mongodb-driver-core-3.11.2.jar:na]
	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:65) ~[mongodb-driver-core-3.11.2.jar:na]
	... 3 common frames omitted

并且用工具能够连接mongodb,已经排除是mongodb不能连接的问题

原因

项目中配置了自定义的MongoClient

java 复制代码
	@Bean
    public MongoDatabase mongoDatabase() {
        String host = mongodbProperties.getHost();
        Integer port = mongodbProperties.getPort();
 
        MongoClientOptions.Builder options = new MongoClientOptions.Builder();
        options.connectionsPerHost(mongodbProperties.getPoolSize());
        options.threadsAllowedToBlockForConnectionMultiplier(mongodbProperties.getBlockSize());
        options.build();
 
        MongoClient mongoClient = null;
        ServerAddress serverAddress = new ServerAddress(mongodbProperties.getHost(), mongodbProperties.getPort());
        List<ServerAddress> seeds = new ArrayList<>();
        seeds.add(serverAddress);
        String userName = mongodbProperties.getUserName();
        String password = mongodbProperties.getPassword();
        if (StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(password)){
 
            MongoCredential credentials = MongoCredential.createCredential(userName, mongodbProperties.getDatabase(), password.toCharArray());
            List<MongoCredential> credentialsList = new ArrayList<>();
            credentialsList.add(credentials);
            mongoClient = new MongoClient(seeds, credentialsList);
        }else {
            mongoClient = new MongoClient(host, port);
        }
 
       return mongoClient.getDatabase(mongodbProperties.getDatabase());
    }

而springboot在启动时会自动实例化一个MongoClient

源码如下:

java 复制代码
/*
 * Copyright 2012-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package org.springframework.boot.autoconfigure.mongo;
 
import com.mongodb.MongoClientURI;
 
import org.springframework.boot.context.properties.ConfigurationProperties;
 
/**
 * Configuration properties for Mongo.
 *
 * @author Dave Syer
 * @author Phillip Webb
 * @author Josh Long
 * @author Andy Wilkinson
 * @author Eddú Meléndez
 * @author Stephane Nicoll
 * @author Nasko Vasilev
 * @author Mark Paluch
 * @author Artsiom Yudovin
 * @since 1.0.0
 */
@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties {
 
	/**
	 * Default port used when the configured port is {@code null}.
	 */
	public static final int DEFAULT_PORT = 27017;
 
	/**
	 * Default URI used when the configured URI is {@code null}.
	 */
	public static final String DEFAULT_URI = "mongodb://localhost/test";
 
	/**
	 * Mongo server host. Cannot be set with URI.
	 */
	private String host;
 
	/**
	 * Mongo server port. Cannot be set with URI.
	 */
	private Integer port = null;
 
	/**
	 * Mongo database URI. Cannot be set with host, port and credentials.
	 */
	private String uri;
 
	/**
	 * Database name.
	 */
	private String database;
 
	/**
	 * Authentication database name.
	 */
	private String authenticationDatabase;
 
	/**
	 * GridFS database name.
	 */
	private String gridFsDatabase;
 
	/**
	 * Login user of the mongo server. Cannot be set with URI.
	 */
 
	private String username;
 
	/**
	 * Login password of the mongo server. Cannot be set with URI.
	 */
	private char[] password;
 
	/**
	 * Fully qualified name of the FieldNamingStrategy to use.
	 */
	private Class<?> fieldNamingStrategy;
 
	/**
	 * Whether to enable auto-index creation.
	 */
	private Boolean autoIndexCreation;
 
	public String getHost() {
		return this.host;
	}
 
	public void setHost(String host) {
		this.host = host;
	}
 
	public String getDatabase() {
		return this.database;
	}
 
	public void setDatabase(String database) {
		this.database = database;
	}
 
	public String getAuthenticationDatabase() {
		return this.authenticationDatabase;
	}
 
	public void setAuthenticationDatabase(String authenticationDatabase) {
		this.authenticationDatabase = authenticationDatabase;
	}
 
	public String getUsername() {
		return this.username;
	}
 
	public void setUsername(String username) {
		this.username = username;
	}
 
	public char[] getPassword() {
		return this.password;
	}
 
	public void setPassword(char[] password) {
		this.password = password;
	}
 
	public Class<?> getFieldNamingStrategy() {
		return this.fieldNamingStrategy;
	}
 
	public void setFieldNamingStrategy(Class<?> fieldNamingStrategy) {
		this.fieldNamingStrategy = fieldNamingStrategy;
	}
 
	public String getUri() {
		return this.uri;
	}
 
	public String determineUri() {
		return (this.uri != null) ? this.uri : DEFAULT_URI;
	}
 
	public void setUri(String uri) {
		this.uri = uri;
	}
 
	public Integer getPort() {
		return this.port;
	}
 
	public void setPort(Integer port) {
		this.port = port;
	}
 
	public String getGridFsDatabase() {
		return this.gridFsDatabase;
	}
 
	public void setGridFsDatabase(String gridFsDatabase) {
		this.gridFsDatabase = gridFsDatabase;
	}
 
	public String getMongoClientDatabase() {
		if (this.database != null) {
			return this.database;
		}
		return new MongoClientURI(determineUri()).getDatabase();
	}
 
	public Boolean isAutoIndexCreation() {
		return this.autoIndexCreation;
	}
 
	public void setAutoIndexCreation(Boolean autoIndexCreation) {
		this.autoIndexCreation = autoIndexCreation;
	}
 
}

解决方法

禁用SpringBoot对Mongo的自动配置,以免和自定义的配置冲突,在SpringBoot启动类上加上:

java 复制代码
@SpringBootApplication(exclude = MongoAutoConfiguration.class)

由此可见,在任何springboot项目中,如果自定义了MongoClient且交与了springboot管理,都需要排除掉springboot对mongodb的自动配置

相关推荐
虾球xz27 分钟前
游戏引擎学习第147天
数据库·学习·游戏引擎
╰つ゛木槿1 小时前
Spring Boot 调用DeepSeek API的详细教程
java·spring boot·后端·deepseek
向上的车轮1 小时前
什么是时序数据库?有哪些时序数据库?常见的运用场景有哪些?
数据库·时序数据库
hhw1991122 小时前
c#面试题整理6
java·开发语言·c#
程序视点2 小时前
SpringBoot配置入门
java·spring boot·spring
岱宗夫up3 小时前
【Python】Django 中的算法应用与实现
数据库·python·opencv·django·sqlite
比花花解语3 小时前
使用数据库和缓存的时候,是如何解决数据不一致的问题的?
数据库·缓存·数据一致性
YGGP3 小时前
Redis篇:基础知识总结与基于长期主义的内容更新
数据库·redis·缓存
Benaso3 小时前
Java,Golang,Rust 泛型的大体对比小记
java·golang·rust
程序员清风3 小时前
什么时候会考虑用联合索引?如果只有一个条件查就没有建联合索引的必要了么?
java·后端·面试