SimpleMongoDbFactory类已经失效,被SimpleMongoClientDbFactory替代
老版本的mongodbtemplate连接池的用法
spring:
  data:
    mongodb:
      address: 127.0.0.1:37017
      replica-set:
      database: xxx
      username: xxx
      password: xxxx
      # Configure spring.data.mongodbDB Pool
      min-connections-per-host: 10
      max-connections-per-host: 100
      threads-allowed-to-block-for-connection-multiplier: 5
      server-selection-timeout: 30000
      max-wait-time: 120000
      max-connection-idle-time: 0
      max-connection-life-time: 0
      connect-timeout: 10000
      socket-timeout: 0
      socket-keep-alive: false
      ssl-enabled: false
      ssl-invalid-host-name-allowed: false
      always-use-m-beans: false
      heartbeat-socket-timeout: 20000
      heartbeat-connect-timeout: 20000
      min-heartbeat-frequency: 500
      heartbeat-frequency: 10000
      local-threshold: 15
      authentication-database: admin- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
import java.util.List;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Data
@Component
//@PropertySource(value = "classpath:mongo-pool.properties")
@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoSettingsProperties {
 
    private List<String> address;
    private String replicaSet;
    private String database;
    private String username;
    private String password;
    private Integer minConnectionsPerHost = 0;
    private Integer maxConnectionsPerHost = 100;
    private Integer threadsAllowedToBlockForConnectionMultiplier = 5;
    private Integer serverSelectionTimeout = 30000;
    private Integer maxWaitTime = 120000;
    private Integer maxConnectionIdleTime = 0;
    private Integer maxConnectionLifeTime = 0;
    private Integer connectTimeout = 10000;
    private Integer socketTimeout = 0;
    private Boolean socketKeepAlive = false;
    private Boolean sslEnabled = false;
    private Boolean sslInvalidHostNameAllowed = false;
    private Boolean alwaysUseMBeans = false;
    private Integer heartbeatConnectTimeout = 20000;
    private Integer heartbeatSocketTimeout = 20000;
    private Integer minHeartbeatFrequency = 500;
    private Integer heartbeatFrequency = 10000;
    private Integer localThreshold = 15;
    private String authenticationDatabase;
 
 
}- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
@Configuration
public class MongoConfig {
    // 覆盖默认的MongoDbFactory
    @Bean
    public MongoDbFactory mongoDbFactory(MongoSettingsProperties mongoSettingsProperties) {
        // 客户端配置(连接数、副本集群验证)
        MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
        builder.connectionsPerHost(mongoSettingsProperties.getMaxConnectionsPerHost());
        builder.minConnectionsPerHost(mongoSettingsProperties.getMinConnectionsPerHost());
        if (mongoSettingsProperties.getReplicaSet() != null) {
            builder.requiredReplicaSetName(mongoSettingsProperties.getReplicaSet());
        }
        builder.threadsAllowedToBlockForConnectionMultiplier(
                mongoSettingsProperties.getThreadsAllowedToBlockForConnectionMultiplier());
        builder.serverSelectionTimeout(mongoSettingsProperties.getServerSelectionTimeout());
        builder.maxWaitTime(mongoSettingsProperties.getMaxWaitTime());
        builder.maxConnectionIdleTime(mongoSettingsProperties.getMaxConnectionIdleTime());
        builder.maxConnectionLifeTime(mongoSettingsProperties.getMaxConnectionLifeTime());
        builder.connectTimeout(mongoSettingsProperties.getConnectTimeout());
        builder.socketTimeout(mongoSettingsProperties.getSocketTimeout());
        builder.sslEnabled(mongoSettingsProperties.getSslEnabled());
        builder.sslInvalidHostNameAllowed(mongoSettingsProperties.getSslInvalidHostNameAllowed());
        builder.alwaysUseMBeans(mongoSettingsProperties.getAlwaysUseMBeans());
        builder.heartbeatFrequency(mongoSettingsProperties.getHeartbeatFrequency());
        builder.minHeartbeatFrequency(mongoSettingsProperties.getMinHeartbeatFrequency());
        builder.heartbeatConnectTimeout(mongoSettingsProperties.getHeartbeatConnectTimeout());
        builder.heartbeatSocketTimeout(mongoSettingsProperties.getHeartbeatSocketTimeout());
        builder.localThreshold(mongoSettingsProperties.getLocalThreshold());
        
        MongoClientOptions mongoClientOptions = builder.build();
        // MongoDB地址列表
        List<ServerAddress> serverAddresses = new ArrayList<>();
        for (String address : mongoSettingsProperties.getAddress()) {
            String[] hostAndPort = address.split(":");
            String host = hostAndPort[0];
            Integer port = Integer.parseInt(hostAndPort[1]);
            ServerAddress serverAddress = new ServerAddress(host, port);
            serverAddresses.add(serverAddress);
        }
        System.out.println("serverAddresses:" + serverAddresses.toString());
        // 连接认证
        //List<MongoCredential> mongoCredentialList = new ArrayList<>();
        // 创建客户端和Factory
        MongoClient mongoClient =null;
        if (mongoSettingsProperties.getUsername() != null) {
            MongoCredential mongoCredential= MongoCredential.createScramSha1Credential(
                            mongoSettingsProperties.getUsername(),
                            mongoSettingsProperties.getAuthenticationDatabase() != null ? mongoSettingsProperties
                                    .getAuthenticationDatabase() : mongoSettingsProperties.getDatabase(),
                            mongoSettingsProperties.getPassword().toCharArray());
            mongoClient= new MongoClient(serverAddresses,mongoCredential, mongoClientOptions);
        }
        else{
            mongoClient= new MongoClient(serverAddresses, mongoClientOptions);
        }
        MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient,mongoSettingsProperties.getDatabase());
        return mongoDbFactory;
    }
}- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.

  
  
springboot2.2.0升级过程
MongoDB Driver:使用正确的姿势连接复制集
MongoDB Driver:使用正确的姿势连接复制集
MongoDB复制集(Replica Set)通过存储多份数据副本来保证数据的高可靠,通过自动的主备切换机制来保证服务的高可用。但需要注意的时,连接副本集的姿势如果不对,服务高可用将不复存在。

使用复制集时你需要知道的
MongoDB复制集里Primary节点是不固定的,当遇到复制集轮转升级、Primary宕机、网络分区等场景时,复制集可能会选举出一个新的Primary,而原来的Primary则会降级为Secondary,即发生主备切换。
总而言之,MongoDB复制集里Primary节点是不固定的,不固定的,不固定的,重要的事情说3遍。
当连接复制集时,如果直接指定Primary的地址来连接,当时可能可以正确读写数据的,但一旦复制集发生主备切换,你连接的Primary会降级为Secondary,你将无法继续执行写操作,这将严重影响到你的线上服务。
所以生产环境千万不要直连Primary,千万不要直连Primary,千万不要直连Primary。
说了这么多,到底该如何连接复制集?
正确连接复制集的姿势
要正确连接复制集,需要先了解下MongoDB的Connection String URI,所有官方的driver都支持以Connection String的方式来连接MongoDB。
下面就是Connection String包含的主要内容
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]- mongodb:// 前缀,代表这是一个Connection String
- username:password@ 如果启用了鉴权,需要指定用户密码
- hostX:portX 复制集成员的ip:port信息,多个成员以逗号分割
- /database 鉴权时,用户帐号所属的数据库
- ?options 指定额外的连接选项
以连接AliCloudDB for MongoDB为例,当你购买阿里云MongoDB复制集时,就会得到复制集的名称、以及复制集成员的地址信息。

为了方便用户使用,控制台上也生成了连接复制集的Connection String及通过Mongo Shell连接到命令。

例如通过java来连接,更多的DEMO
MongoClientURI connectionString = new MongoClientURI("mongodb://root:****@dds-bp114e3f1fc441342.mongodb.rds.aliyuncs.com:3717,dds-bp114e3f1fc441341.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=mgset-677201"); // ****替换为root密码
MongoClient client = new MongoClient(connectionString);
MongoDatabase database = client.getDatabase("mydb");
MongoCollection collection = database.getCollection("mycoll");通过正确的Connection String来连接MongoDB复制集时,客户端会自动检测复制集的主备关系,当主备关系发生变化时,自动将写切换到新的主上,以保证服务的高可用。
常用连接参数
如何实现读写分离?
在options里添加readPreference=secondaryPreferred即可实现,读请求优先到Secondary节点,从而实现读写分离的功能,更多读选项参考Read preferences
如何限制连接数?
在options里添加maxPoolSize=xx即可将客户端连接池限制在xx以内。
如何保证数据写入到大多数节点后才返回?
在options里添加w= majority即可保证写请求成功写入大多数节点才向客户端确认,更多写选项参考Write Concern
作者简介
张友东,阿里巴巴技术专家,主要关注分布式存储、Nosql数据库等技术领域,先后参与TFS(淘宝分布式文件系统)、AliCloudDB for Redis等项目,目前主要从事AlidCloud For MongoDB的研发工作,致力于让开发者用上最好的MongoDB云服务。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号