3 votes

Le pilote MongoDB Go cherche sur localhost alors qu'il ne devrait pas le faire

Je ne suis pas un fan de Go, j'ai juste besoin d'utiliser un plugin écrit en Go et j'ai quelques problèmes entre le plugin et MongoDB.

L'erreur est :

server selection error: server selection timeout
current topology: Type: Unknown
Servers:
Addr: localhost:27017, Type: Unknown, State: Connected, Avergage RTT: 0, Last error: dial tcp 127.0.0.1:27017: connect: connection refused
exit status 1

Ma configuration :

time=“2019-09-03T16:29:35Z” level=debug msg=“Host: ip-XXX-XX-XX-XXX.sa-east-1.compute.internal”
time=“2019-09-03T16:29:35Z” level=debug msg=“Port: 27017”
time=“2019-09-03T16:29:35Z” level=debug msg=“Username: user”
time=“2019-09-03T16:29:35Z” level=debug msg=“Password: user123*”
time=“2019-09-03T16:29:35Z” level=debug msg=“DBName: dbBackend”

Le snippet du plugin qui effectue la connexion :

addr := fmt.Sprintf("mongodb://%s:%s", m.Host, m.Port)

to := 60 * time.Second
opts := options.ClientOptions{
    ConnectTimeout: &to,
}

opts.ApplyURI(addr)

if m.Username != "" && m.Password != "" {
    opts.Auth = &options.Credential{
        AuthSource:  m.DBName,
        Username:    m.Username,
        Password:    m.Password,
        PasswordSet: true,
    }
}

client, err := mongo.Connect(context.TODO(), &opts)

if err != nil {
    return m, errors.Errorf("couldn't start mongo backend. error: %s\n", err)
}

err1 := client.Ping(context.TODO(), nil)

if err1 != nil {    
    log.Fatal(err1) // error happens here
} 

log.Debugf("MONGO CONNECTED")

m.Conn = client

return m, nil

Je n'arrive pas à comprendre pourquoi le pilote mongo cherche sur localhost si je définis l'adresse de mon serveur mongoDB.

EDIT 1

Ma base de données a un jeu de répliques configuré uniquement pour utiliser les flux de changement.

Voici ma configuration RS :

{
    "_id" : "rs0",
    "version" : 69559,
    "protocolVersion" : 1,
    "writeConcernMajorityJournalDefault" : true,
    "members" : [
        {
            "_id" : 0,
            "host" : "localhost:27017",
            "arbiterOnly" : false,
            "buildIndexes" : true,
            "hidden" : false,
            "priority" : 1,
            "tags" : {

            },
            "slaveDelay" : 0,
            "votes" : 1
        }
    ],
    "settings" : {
        "chainingAllowed" : true,
        "heartbeatIntervalMillis" : 2000,
        "heartbeatTimeoutSecs" : 10,
        "electionTimeoutMillis" : 10000,
        "catchUpTimeoutMillis" : -1,
        "catchUpTakeoverDelayMillis" : 30000,
        "getLastErrorModes" : {

        },
        "getLastErrorDefaults" : {
            "w" : 1,
            "wtimeout" : 0
        },
        "replicaSetId" : ObjectId("5cf684c3c0db3f53727d1bb4")
    }
}

Toute aide pour résoudre ce problème sera appréciée. Merci

5voto

Wan Bachtiar Points 7757

pourquoi le pilote mongo cherche sur localhost si je définis l'adresse de mon serveur mongoDB.

Lorsque mongo-go-driver Si le client de l'entreprise se connecte à un déploiement MongoDB, il effectuera les opérations suivantes Découverte et surveillance des serveurs pour découvrir un ou plusieurs serveurs (MongoDB étant une base de données distribuée par nature). L'une des premières étapes consiste à commencer à surveiller la topologie en invoquant la commande Commande isMaster sur tous les serveurs. Basé sur la sortie de isMaster le client va essayer de contacter ces serveurs. Dans le cas de Jeu de répliques (votre cas), le client s'efforce de se connecter au serveur primaire (à partir de isMaster.primary ).

Cependant, l'adresse du nom d'hôte n'est pas un Nom de domaine entièrement qualifié (FQDN) doit être résoluble depuis la machine du client. La machine du client essaie de se connecter à localhost défini comme le primaire de l'ensemble de répliques, a donc échoué à établir une connexion. Aussi, c'est pourquoi vous voyez un statut de message où current topology: Type: Unknown pero State: Connected . Il n'a pas réussi à découvrir la topologie du déploiement avant même de pouvoir sélectionner un serveur pour exécuter la commande ( ping )

Vous pouvez résoudre ce problème en définissant des noms d'hôtes résolubles pour la valeur du champ members dans la configuration du replica set. En outre, lorsque cela est possible, utilisez un nom d'hôte DNS logique au lieu d'une adresse IP, car cela évite les modifications de configuration dues aux changements d'adresse IP.

Vous pouvez changer les noms d'hôtes des ensembles de répliques en utilisant rs.reconfig() c'est-à-dire

cfg = rs.conf()
cfg.members[1].host = "<RESOLVABLE HOSTNAME>:<PORT NUMBER>"
rs.reconfig(cfg)

Dans votre cas, où il n'y a qu'un seul membre de l'ensemble de répliques, c'est assez simple. Cependant, si vous êtes en mode production et que vous avez plusieurs membres, vous pouvez suivre les étapes décrites dans le document Changer les noms d'hôtes dans un ensemble de répliques où il y a deux options :

Ayant dit toutes les explications ci-dessus, alternativement, comme le déploiement de votre ensemble de répliques est un seul serveur (mode développement), vous pouvez définir le mode de connexion sur direct via ClientOptions.SetDirect() . Ce qui spécifie si le client doit se connecter directement à un serveur au lieu de découvrir automatiquement d'autres serveurs dans le cluster (bien que cela signifie que vous n'avez pas de redondance), c'est-à-dire :

opts := options.ClientOptions{ ConnectTimeout: &timeoutVariable}
opts.SetDirect(true)
opts.ApplyURI(addr)

client, err := mongo.Connect(connect.TODO(), &opts)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X