dongwen3093 2019-09-03 20:04
浏览 103
已采纳

MongoDB Go驱动程序在本地主机上查找的时间不应该

I'm not a Go guy, just need to use a plugin written in Go and I'm having some trouble between plugin and MongoDB.

The error is:

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

My 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”

The plugin snippet that performs the connection:

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
", 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

I just can't realize why the mongo driver is looking on localhost if I'm setting the address of my mongoDB server.

EDIT 1

My db has replica set configured only to use change streams.

This is my RS configuration:

{
    "_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")
    }
}

Any help solving it appreciated. Thanks

  • 写回答

1条回答 默认 最新

  • dongyi7901 2019-09-06 02:17
    关注

    why the mongo driver is looking on localhost if I'm setting the address of my mongoDB server.

    When mongo-go-driver's client is connecting to a MongoDB deployment, it will perform Server Discovery and Monitoring to discovers one or more servers (MongoDB being a distributed database by nature). One of the early steps is to begin monitoring the topology by invoking isMaster command on all servers. Based on the output of isMaster the client will try to contact those servers. In the case of Replica Set (your case), the client strives to connect to the primary server (from isMaster.primary).

    However, the hostname address is not a Fully Qualified Domain Name (FQDN) to be resolvable from the client's machine. The client's machine trying to connect to localhost defined as the replica set primary, thus failed to make a connection. Also, this is why you're seeing a message status where current topology: Type: Unknown but State: Connected. It failed to discover the deployment topology even before able to select a server to execute the command (ping)

    You can solve this by setting resolvable hostnames for the value of the members field in the replica set configuration. In addition, when possible, use a logical DNS hostname instead of an ip address, as this avoids configuration changes due to ip address changes.

    You can change the replica set hostnames using rs.reconfig() i.e:

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

    In your case, where there's only one replica set member it's quite straight forward. However if you're in production mode and have more than one members you can follow the steps outlined in Change Hostnames in a Replica Set where there are two options:

    Having said all the explanation above, alternatively, as your replica set deployment is only one server (development mode) you can set the connection mode to direct via ClientOptions.SetDirect(). Which specifies whether the client should connect directly to a server instead of auto-discovering other servers in the cluster (although this means you have no redundancy) i.e.:

    opts := options.ClientOptions{ ConnectTimeout: &timeoutVariable}
    opts.SetDirect(true)
    opts.ApplyURI(addr)
    
    client, err := mongo.Connect(connect.TODO(), &opts)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入
  • ¥40 使用MATLAB解答线性代数问题
  • ¥15 COCOS的问题COCOS的问题
  • ¥15 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码
  • ¥50 随机森林与房贷信用风险模型