来自mongoc(C)驱动程序的MongoDB Atlas连接间歇性失败,并显示'找不到合适的服务器'

问题描述 投票:0回答:1

我正在使用MongoDB C驱动程序(1.9.2)连接到我的Atlas群集(使用AWS的M5)。我的请求通常会成功,但是大约一半时间会出现此错误。我在两次请求之间等待的时间越长,请求成功的频率就越高。

我总是能够创建mongoc_client_t,但是当请求失败时,放置,插入或读取操作会收到此错误;

2019-12-30 23:10:50 :: dropCollection():mongoc_collection_drop()失败的代码(13053):::找不到合适的服务器: serverSelectionTimeoutMS已过期:[无法从服务器接收长度头。在“ xxxxx-shard-00-01-xxxxx.mongodb.net:27017”上调用ismaster。[无法从服务器接收长度标头。在“ xxxxx-shard-00-00-xxxxx.mongodb.net:27017”上调用ismaster

这是我的(简体)代码;我尝试使用客户端池,然后切换到'serverSelectionTryOnce = false

'-他们都在超时后得到错误。
    #include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <mongoc.h>
#include <bson.h>
#include <bcon.h>

#define ERROR -1
#define GOOD   0

typedef struct _MongoContext
{
    mongoc_uri_t*           uri;
    mongoc_client_t*        client;
    mongoc_database_t*      database;
    mongoc_collection_t*    collection;
    bson_error_t            error;
    char*                   uriStr;
} MongoContext;

static const char* DEFAULT_URI = "mongodb+srv://<user>:<psswd>@<host>.mongodb.net/test?retryWrites=true&w=majority&serverSelectionTryOnce=false";

int getMongoContext(MongoContext* mctx, const char* dbname, const char* collname)
{
    bson_error_t  error;

    mctx->uriStr = strdup(DEFAULT_URI);

    mctx->uri = mongoc_uri_new_with_error(mctx->uriStr, &error);                               
    if(!mctx->uri) {
        fprintf(stderr, "getMongoContext(): Unable to parse URI(%s)\n(%s)", mctx->uriStr, error.message);
        return ERROR;
    }

//    mongoc_client_pool_t *pool = mongoc_client_pool_new(mctx->uri);
//    mongoc_client_pool_set_appname(pool, "my-mongo");
//    mongoc_client_pool_set_error_api(pool, MONGOC_ERROR_API_VERSION_2);
//    mctx->client = mongoc_client_pool_pop(pool);

    mctx->client = mongoc_client_new_from_uri(mctx->uri);                                      
    if(!mctx->client) {
        fprintf(stderr, "getMongoContext(): mongoc_client_new_from_uri() failed(%s)", error.message);
       return ERROR;
    }

    mongoc_client_set_appname(mctx->client, "my-mongo");                                       

    mctx->database   = mongoc_client_get_database(mctx->client, dbname);
    if(mctx->database == NULL) {
        fprintf(stderr, "getMongoContext(): invalid database(%s)", dbname);
        return ERROR;
    }

    mctx->collection = mongoc_client_get_collection(mctx->client, dbname, collname);
    if(mctx->collection == NULL) {
        fprintf(stderr, "getMongoContext(): invalid collection(%s)", collname);
    }

    char* ptr = strchr(mctx->uriStr, '@');
    fprintf(stderr, "getMongoContext(): connection made for host(%s), db(%s), collection(%s)\n", (ptr+1), dbname, collname);

   return GOOD;
}

void closeMongoContext(MongoContext* mctx)
{
    mongoc_collection_destroy(mctx->collection);
    mongoc_database_destroy(mctx->database);
    mongoc_uri_destroy(mctx->uri);
    mongoc_client_destroy(mctx->client);
    mongoc_cleanup();

    free(mctx->uriStr);
}

/**
 * read the collection in the given MongoContext
 */
int readCollection(MongoContext* mctx)
{
    mongoc_cursor_t*    cursor;
    const bson_t*       doc;
    char*               str;
    bson_t* query = bson_new();
    cursor = mongoc_collection_find_with_opts(mctx->collection, query, NULL, NULL);

    if(cursor == NULL) {
        fprintf(stderr, "readCollection(): Unable to retrieve a cursor for collection(%s)",
               mongoc_collection_get_name(mctx->collection));
        return ERROR;
    }

    while(mongoc_cursor_next(cursor, &doc)) {
       str = bson_as_canonical_extended_json(doc, NULL);
       printf("%s\n", str);
       bson_free(str);
    }
    bson_destroy(query);
    mongoc_cursor_destroy(cursor);

    return GOOD;
}

int insertIntoCollection(MongoContext* mctx, const char* jsondata)
{
    bson_t* doc;
    bson_t  reply;
    bson_error_t error;

    doc = bson_new_from_json((const uint8_t*)jsondata, -1, &error);
    if(!doc) {
       fprintf(stderr, "insertIntoCollection(): bson_new_from_json() failed (%s)\n", error.message);
       return ERROR;
    }

    fprintf(stderr, "insertIntoCollection(): insert into collection(%s)\n", mongoc_collection_get_name(mctx->collection));
    bool b = mongoc_collection_insert_one(mctx->collection, doc, NULL, &reply, &error);

    if(!b) {
        fprintf(stderr, "insertIntoCollection(): mongoc_collection_insert_one() failed (%s)\n", error.message);
    }
    bson_destroy(doc);

    return GOOD;
}

int dropCollection(MongoContext* mctx)
{
    bson_error_t error;

    bool rval = mongoc_collection_drop(mctx->collection, &error);                              

    if(!rval) {
        fprintf(stderr, "dropCollection(): mongoc_collection_drop() failed code(%d)::%s", error.code, error.message);
        fprintf(stderr, "dropCollection(): mongoc_collection_drop() failed on collection(%s) for(%s)",
           mongoc_collection_get_name(mctx->collection), mctx->uriStr);
        return (error.code == 26) ? GOOD : ERROR;                                               
    }

    return GOOD;
}

int main(int argc, char* argv[])
{
    mongoc_init();
    MongoContext mctx = {0};
    getMongoContext(&mctx, "my-db", "my-collection");

    if(dropCollection(&mctx) == ERROR) {
        exit(1);
    }
    printf("collection dropped...\n");

    if(insertIntoCollection(&mctx, "{ \"hello\" : \"world\" }") == ERROR) {
        exit(1);
    }
    printf("inserted into collection...\n");

    if(readCollection(&mctx) == ERROR) {
        exit(1);
    }

    closeMongoContext(&mctx);
}

我正在使用MongoDB C驱动程序(1.9.2)连接到我的Atlas群集(使用AWS的M5)。我的请求通常会成功,但是大约一半时间会出现此错误。我在请求之间等待的时间越长,更多...

mongodb database-connection
1个回答
0
投票

就我而言,这是一个版本问题。我必须升级我的C驱动程序版本才能与服务器兼容。

© www.soinside.com 2019 - 2024. All rights reserved.