簡體   English   中英

UncategorizedMongoDbException:命令失敗,錯誤 10107(NotMaster):服務器上的“非主控”

[英]UncategorizedMongoDbException: Command failed with error 10107 (NotMaster): 'not master' on server

我在執行 MongoDB 事務功能的集成測試用例時遇到以下異常。

org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 10107 (NotMaster): 'not master' on server localhost:60876. The full response is {"operationTime": {"$timestamp": {"t": 1615104939, "i": 1}}, "ok": 0.0, "errmsg": "not master", "code": 10107, "codeName": "NotMaster", "$gleStats": {"lastOpTime": {"$timestamp": {"t": 1615104939, "i": 1}}, "electionId": {"$oid": "7fffffff0000000000000001"}}, "lastCommittedOpTime": {"$timestamp": {"t": 0, "i": 0}}, "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1615104939, "i": 2}}, "signature": {"hash": {"$binary": {"base64": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "subType": "00"}}, "keyId": 0}}}; nested exception is com.mongodb.MongoNotPrimaryException: Command failed with error 10107 (NotMaster): 'not master' on server localhost:60876. The full response is {"operationTime": {"$timestamp": {"t": 1615104939, "i": 1}}, "ok": 0.0, "errmsg": "not master", "code": 10107, "codeName": "NotMaster", "$gleStats": {"lastOpTime": {"$timestamp": {"t": 1615104939, "i": 1}}, "electionId": {"$oid": "7fffffff0000000000000001"}}, "lastCommittedOpTime": {"$timestamp": {"t": 0, "i": 0}}, "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1615104939, "i": 2}}, "signature": {"hash": {"$binary": {"base64": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "subType": "00"}}, "keyId": 0}}}
    at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:133)
    at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2874)
    at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:568)
    at org.springframework.data.mongodb.core.MongoTemplate.saveDocument(MongoTemplate.java:1485)
    at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:1421)
    at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1363)
....................
Caused by: com.mongodb.MongoNotPrimaryException: Command failed with error 10107 (NotMaster): 'not master' on server localhost:60876. The full response is {"operationTime": {"$timestamp": {"t": 1615104939, "i": 1}}, "ok": 0.0, "errmsg": "not master", "code": 10107, "codeName": "NotMaster", "$gleStats": {"lastOpTime": {"$timestamp": {"t": 1615104939, "i": 1}}, "electionId": {"$oid": "7fffffff0000000000000001"}}, "lastCommittedOpTime": {"$timestamp": {"t": 0, "i": 0}}, "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1615104939, "i": 2}}, "signature": {"hash": {"$binary": {"base64": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "subType": "00"}}, "keyId": 0}}}
    at com.mongodb.internal.connection.ProtocolHelper.createSpecialException(ProtocolHelper.java:244)
    at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:171)
    at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:302)

我的測試 class 有以下方法。

@Test
   @Order(1)
   void testUpdateValidationsById() {
       MyEntity entity = new MyEntity();
       entity.setId("6030a6e1b32d1f70b4ce8039");
       entity.setAttributeType("IP Address, FQDN");
       entity.setCategory("NTP");
       entity.setCategoryLabel("NTP");
       entity.setTrueMsgDetails("It is true");
       entity.setFalseMsgDetails("It is false");
       entity.setCorevalidation("Core Validation");

       ResponseEntity<?> re = controller.updateValidationsById(entity);
       boolean flag = re.getStatusCode().is2xxSuccessful();
       assertEquals(true, flag);
   }

我的測試配置 class 看起來像這樣。

@Profile("test")
@ActiveProfiles("test")
@TestConfiguration
public class TestMongoDBConfig implements InitializingBean, DisposableBean {

    private MongodExecutable executable;
    private String replicaSetName = "rs0";
    private int mongoDBPort = 27021;

    @Override
    public void afterPropertiesSet() throws Exception {
        mongoDBPort = Network.getFreeServerPort();
        IMongoCmdOptions cmdOptions = new MongoCmdOptionsBuilder().useNoPrealloc(false).useSmallFiles(false)
                .master(false).verbose(false).useNoJournal(false).syncDelay(0).build();

//      IMongodConfig mongodConfig = new MongodConfigBuilder().version(Version.Main.PRODUCTION)
        IMongodConfig mongodConfig = new MongodConfigBuilder().version(Version.Main.V4_0)
//              .net(new Net(27023, Network.localhostIsIPv6()))
                .net(new Net(mongoDBPort, Network.localhostIsIPv6()))
                .replication(new Storage(null, replicaSetName, 5000)).configServer(true).cmdOptions(cmdOptions)
                .build();

        MongodStarter starter = MongodStarter.getDefaultInstance();
        executable = starter.prepare(mongodConfig);
        executable.start();
    }

    
    @Bean(name = "test1")
    public MongoClient mongoClient() {
        ConnectionString cs = new ConnectionString("mongodb://localhost:" + mongoDBPort + "/");
        MongoClient mongoClient = MongoClients.create(cs);
        System.out.println("--------------------------------------");
        System.out.println("Mongo Selected ort : " + mongoDBPort);
        System.out.println("MongoClient : " + mongoClient);
        System.out.println("--------------------------------------");
        mongoClient.getDatabase("admin").runCommand(new Document("replSetInitiate", new Document()));
        return mongoClient;
    }

    /**
     * Destroy.
     *
     * @throws Exception the exception
     */
    @Override
    public void destroy() throws Exception {
        executable.stop();
    }
}

由於沒有解決方案,我將發布我的解決方案,請記住,這種情況發生在僅具有副本集的嵌入式 mongo db(flapdoodle 版本 3.0.0)以及以下 java 和 spring mongo 驅動程序:

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>2.2.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.11.3</version>
        </dependency>

我們使用的解決方案是以下忙等待:

    private void waitUntilReplicaReady() throws InterruptedException {
        Document document = getRaplicaStatus();
        while (isReplicaInitializing(document)) {
            document = getRaplicaStatus();
            TimeUnit.MILLISECONDS.sleep(100);
        }
    }

    private boolean isReplicaInitializing(Document document) {
        return document.get("lastStableCheckpointTimestamp", BsonTimestamp.class).getTime() == 0;
    }

    private Document getRaplicaStatus() {
        return getDatabase("admin").runCommand(new BasicDBObject("replSetGetStatus", "1"));
    }

雖然沒有設置lastStableCheckpointTimestamp時間,但我們繼續進行池化,當設置了lastStableCheckpointTimestamp時,我們允許程序前進(填充大約需要 2 秒)

在連接字符串中添加讀取首選項已解決上述問題

mongodb://userName:Password@mongodb0.example.com:27017?ReadPreference=primary

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM