如何设置冗余的MongoDB模板?

时间:2019-07-26 01:48:26

标签: java spring mongodb spring-boot spring-data

我有一个带有两个冗余MongoS路由器主机的MongoDB。使用org.springframework.data.mongo创建MongoTemplate和MongoClient时,我只能添加一个主机。如果正在使用的主机发生故障,则不会将故障转移到备用路由器主机。

我最初引用的是https://dzone.com/articles/multiple-mongodb-connectors-with-spring-boot,但是用例有两个完全不同的存储库,在我的情况下是一个带有双路由器的单个数据库。

在下面的代码中,我们想添加冗余的第二台主机,以防第一台主机在运行时失败。

public class MongoConfiguration extends AbstractMongoConfiguration {

    @Value("${mongo.database}")
    private String databaseName;

    @Value("${mongo.host}")
    private String host;

    @Value("${mongo.readFromSecondary}")
    private String readFromSecondary;

    @Value("${mongo.port}")
    private int port;

    @VaultKey("vault.mongo_username")
    private String username;

    @VaultKey("vault.mongo_password")
    private String password;

    @Override
    protected String getDatabaseName() {
        return databaseName;
    }

    @Override
    @Primary
    public MongoClient mongoClient() {
        final ServerAddress serverAddress = new ServerAddress(host, port);
        final MongoCredential credential = MongoCredential.createCredential(username, 
            getDatabaseName(), password.toCharArray());
        return new MongoClient(serverAddress, credential,
            MongoClientOptions.builder().build());
    }

    @Override
    @Primary
    @Bean(name = "mongoTemplate")
    public MongoTemplate mongoTemplate() throws Exception {
        final MongoTemplate template = super.mongoTemplate();
        if (this.readFromSecondary != null && Boolean.valueOf(this.readFromSecondary)) {
            template.setReadPreference(ReadPreference.secondary());
        }

        return template;
    }
}

当前,在启动时,将在配置文件中加载到主机的连接而不会出现错误,我们希望在备用主机中进行轮换。

1 个答案:

答案 0 :(得分:1)

您可以通过两种方式实现这一目标:

1。多个Mongo客户端或多个服务器地址(主机):

具有内部连接池的MongoDB客户端。对于大多数应用程序,您应该为整个JVM使用一个MongoClient实例。

以下是等效的,所有这些都连接到在默认端口上运行的本地数据库:

MongoClient mongoClient1 = new MongoClient();
MongoClient mongoClient1 = new MongoClient("localhost");
MongoClient mongoClient2 = new MongoClient("localhost", 27017);
MongoClient mongoClient4 = new MongoClient(new ServerAddress("localhost"));
MongoClient mongoClient5 = new MongoClient(new ServerAddress("localhost"), 
    new MongoClientOptions.Builder().build());

您可以通过将ServerAddress列表传递给MongoClient构造函数来使用Java驱动程序连接到副本集。例如:

MongoClient mongoClient = new MongoClient(Arrays.asList(
   new ServerAddress("localhost", 27017),
   new ServerAddress("localhost", 27018),
   new ServerAddress("localhost", 27019)));

您可以使用相同的构造函数连接到分片群集。 MongoClient将自动检测服务器是副本集成员列表还是mongos服务器列表。

默认情况下,所有读和写操作都将在主数据库上进行,但可以通过更改读取首选项来从辅助数据库读取:

mongoClient.setReadPreference(ReadPreference.secondaryPreferred());

默认情况下,所有写操作将等待服务器的确认,因为默认写关注点为WriteConcern.ACKNOWLEDGED

2。使用多个Mongo连接器和多个Mongo模板:

首先创建以下@ConfigurationProperties类。

@ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {
    private MongoProperties primary = new MongoProperties();
    private MongoProperties secondary = new MongoProperties();
}

然后在application.yml

中添加以下属性
mongodb:
  primary:
    host: localhost
    port: 27017
    database: second
  secondary:
    host: localhost
    port: 27017
    database: second

现在,有必要在上一步中创建MongoTemplate来绑定给定的配置。

@EnableConfigurationProperties(MultipleMongoProperties.class)
public class MultipleMongoConfig {

    private final MultipleMongoProperties mongoProperties;

    @Primary
    @Bean(name = "primaryMongoTemplate")
    public MongoTemplate primaryMongoTemplate() throws Exception {
        return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
    }

    @Bean(name = "secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate() throws Exception {
        return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
    }

    @Bean
    @Primary
    public MongoDbFactory primaryFactory(final MongoProperties mongo) throws Exception {
        return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
                mongo.getDatabase());
    }

    @Bean
    public MongoDbFactory secondaryFactory(final MongoProperties mongo) throws Exception {
        return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
                mongo.getDatabase());
    }

}

使用上述配置,您将能够基于我们在本指南前面提供的自定义配置属性中拥有两个不同的MongoTemplate。

在上一步中,我们创建了两个MongoTemplates,primaryMongoTemplatesecondaryMongoTemplate

更多详细信息:https://blog.marcosbarbero.com/multiple-mongodb-connectors-in-spring-boot/