天天看點

Spring Boot中使用MongoDB的連接配接池配置

因為今天開發遇到了性能問題,可能與MongoDB的連接配接有關,是以稍稍深入看了一下,正好搜到原來有人寫過這篇相關的内容,是以轉載過來。回頭有時間可以寫個擴充到SpringForAll裡,主體思路還是一樣的。感謝這位美女程式媛的文章!

https://blog.didispace.com/spring-boot-mongodb-connection-pool/#%E8%AF%B4%E6%98%8E 說明

Spring Boot中通過依賴

spring-boot-starter-data-mongodb

,來實作

spring-data-mongodb

的自動配置。

但是預設情況下,Spring Boot 中,并沒有像使用MySQL或者Redis一樣,提供了連接配接池配置的功能。是以,我們需要自行重寫

MongoDbFactory

,實作MongoDB用戶端連接配接的參數配置擴充。

需要說明的是,MongoDB的用戶端本身就是一個連接配接池,是以,我們隻需要配置用戶端即可。

https://blog.didispace.com/spring-boot-mongodb-connection-pool/#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6 配置檔案

為了統一Spring Boot的配置,我們要将重寫的配置也配置到

application.yml

中,字首為

spring.data.mongodb.custom

下(字首可自己随意配置):

spring:
  data:
    mongodb:
      custom:
        hosts:
          - 10.0.5.1
          - 10.0.5.1
        ports:
          - 27017
          - 27018
        replica-set: mgset-3590061
        username: jancee
        password: abc123
        database: jancee
        authentication-database: admin
        connections-per-host: 20
        min-connections-per-host: 20      

該配置例子中,配置了副本集,其中包含了主機

10.0.5.1:27017

10.0.5.1:27018

,其它配置與Spring Boot的标準配置類似,另外,

connections-per-host

為用戶端的連接配接數,

in-connections-per-host

為用戶端最小連接配接數。

https://blog.didispace.com/spring-boot-mongodb-connection-pool/#%E5%B0%86%E9%85%8D%E7%BD%AE%E5%8C%85%E8%A3%85%E6%88%90%E7%B1%BB 将配置包裝成類

為友善調用和可讀性,将上述配置包裝成一個配置實體類,

MongoConfig.java

代碼如下:

package com.feidiao.jancee.fdiot.api.config.mongo;      
import org.hibernate.validator.constraints.NotBlank;      
import org.hibernate.validator.constraints.NotEmpty;      
import org.springframework.stereotype.Component;      
import org.springframework.validation.annotation.Validated;      
import java.util.List;      
@Component      
@Validated      
public class MongoSettingsProperties {      
@NotBlank      
private String database;      
@NotEmpty      
private List<String> hosts;      
@NotEmpty      
private List<Integer> ports;      
private String replicaSet;      
private String username;      
private String password;      
private String authenticationDatabase;      
private Integer minConnectionsPerHost = 10;      
private Integer connectionsPerHost = 2;      
public MongoSettingsProperties() {      
}      
public String getDatabase() {      
return database;      
}      
public void setDatabase(String database) {      
this.database = database;      
}      
public List<String> getHosts() {      
return hosts;      
}      
public void setHosts(List<String> hosts) {      
this.hosts = hosts;      
}      
public List<Integer> getPorts() {      
return ports;      
}      
public void setPorts(List<Integer> ports) {      
this.ports = ports;      
}      
public String getReplicaSet() {      
return replicaSet;      
}      
public void setReplicaSet(String replicaSet) {      
this.replicaSet = replicaSet;      
}      
public String getUsername() {      
return username;      
}      
public void setUsername(String username) {      
this.username = username;      
}      
public String getPassword() {      
return password;      
}      
public void setPassword(String password) {      
this.password = password;      
}      
public String getAuthenticationDatabase() {      
return authenticationDatabase;      
}      
public void setAuthenticationDatabase(String authenticationDatabase) {      
this.authenticationDatabase = authenticationDatabase;      
}      
public Integer getMinConnectionsPerHost() {      
return minConnectionsPerHost;      
}      
public void setMinConnectionsPerHost(Integer minConnectionsPerHost) {      
this.minConnectionsPerHost = minConnectionsPerHost;      
}      
public Integer getConnectionsPerHost() {      
return connectionsPerHost;      
}      
public void setConnectionsPerHost(Integer connectionsPerHost)     {      
this.connectionsPerHost = connectionsPerHost;      
}      
}      
package com.feidiao.jancee.fdiot.api.config.mongo;

import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import java.util.List;

@Component
@Validated
public class MongoSettingsProperties {

    @NotBlank
    private String database;

    @NotEmpty
    private List<String> hosts;

    @NotEmpty
    private List<Integer> ports;

    private String replicaSet;
    private String username;
    private String password;
    private String authenticationDatabase;
    private Integer minConnectionsPerHost = 10;
    private Integer connectionsPerHost = 2;

    public MongoSettingsProperties() {

    }

    public String getDatabase() {
        return database;
    }

    public void setDatabase(String database) {
        this.database = database;
    }

    public List<String> getHosts() {
        return hosts;
    }

    public void setHosts(List<String> hosts) {
        this.hosts = hosts;
    }

    public List<Integer> getPorts() {
        return ports;
    }

    public void setPorts(List<Integer> ports) {
        this.ports = ports;
    }

    public String getReplicaSet() {
        return replicaSet;
    }

    public void setReplicaSet(String replicaSet) {
        this.replicaSet = replicaSet;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAuthenticationDatabase() {
        return authenticationDatabase;
    }

    public void setAuthenticationDatabase(String authenticationDatabase) {
        this.authenticationDatabase = authenticationDatabase;
    }

    public Integer getMinConnectionsPerHost() {
        return minConnectionsPerHost;
    }

    public void setMinConnectionsPerHost(Integer minConnectionsPerHost) {
        this.minConnectionsPerHost = minConnectionsPerHost;
    }

    public Integer getConnectionsPerHost() {
        return connectionsPerHost;
    }

    public void setConnectionsPerHost(Integer connectionsPerHost)     {
        this.connectionsPerHost = connectionsPerHost;
    }
}      

覆寫MongoDbFactory

接下來,就是覆寫Spring Boot原有的

MongoDbFactory

Bean,建立檔案

MongoConfig.java

,代碼如下:

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class MongoConfig {


    // 注入配置實體
    @Autowired
    private MongoSettingsProperties mongoSettingsProperties;
    @Bean
    @ConfigurationProperties(
            prefix = "spring.data.mongodb.custom")
    MongoSettingsProperties mongoSettingsProperties() {
        return new MongoSettingsProperties();
    }

    // 覆寫預設的MongoDbFactory
    @Bean
    MongoDbFactory mongoDbFactory() {
        //用戶端配置(連接配接數、副本叢集驗證)
        MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
        builder.connectionsPerHost(mongoSettingsProperties.getConnectionsPerHost());
        builder.minConnectionsPerHost(mongoSettingsProperties.getMinConnectionsPerHost());
        if (mongoSettingsProperties.getReplicaSet() != null) {
            builder.requiredReplicaSetName(mongoSettingsProperties.getReplicaSet());
        }
        MongoClientOptions mongoClientOptions = builder.build();

        // MongoDB位址清單
        List<ServerAddress> serverAddresses = new ArrayList<>();
        for (String host : mongoSettingsProperties.getHosts()) {
            Integer index = mongoSettingsProperties.getHosts().indexOf(host);
            Integer port = mongoSettingsProperties.getPorts().get(index);

            ServerAddress serverAddress = new ServerAddress(host, port);
            serverAddresses.add(serverAddress);
        }
        System.out.println("serverAddresses:" + serverAddresses.toString());

        // 連接配接認證
        List<MongoCredential> mongoCredentialList = new ArrayList<>();
        if (mongoSettingsProperties.getUsername() != null) {
            mongoCredentialList.add(MongoCredential.createScramSha1Credential(
                    mongoSettingsProperties.getUsername(),
                    mongoSettingsProperties.getAuthenticationDatabase() != null ? mongoSettingsProperties.getAuthenticationDatabase() : mongoSettingsProperties.getDatabase(),
                    mongoSettingsProperties.getPassword().toCharArray()));
        }
        System.out.println("mongoCredentialList:" + mongoCredentialList.toString());

        //建立用戶端和Factory
        MongoClient mongoClient = new MongoClient(serverAddresses, mongoCredentialList, mongoClientOptions);
        MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient, mongoSettingsProperties.getDatabase());

        return mongoDbFactory;
    }
}      

在這裡,實作了MongoDB連接配接時,前面配置的參數的設定,按照自己的實際情況,可以在

new SimpleMongoDbFactory

時,增加修改自己需要的配置參數。

至此,就完成了全部配置,運作測試即可。