为了账号安全,请及时绑定邮箱和手机立即绑定

MongoDB Go驱动程序在不应该的时候寻找本地主机

MongoDB Go驱动程序在不应该的时候寻找本地主机

Go
拉风的咖菲猫 2023-07-17 17:09:50
我不是 Go 人,只需要使用用 Go 编写的插件,我在插件和 MongoDB 之间遇到了一些麻烦。错误是:server selection error: server selection timeoutcurrent topology: Type: UnknownServers:Addr: localhost:27017, Type: Unknown, State: Connected, Avergage RTT: 0, Last error: dial tcp 127.0.0.1:27017: connect: connection refusedexit status 1我的配置: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”执行连接的插件代码段:addr := fmt.Sprintf("mongodb://%s:%s", m.Host, m.Port)to := 60 * time.Secondopts := 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 = clientreturn m, nil如果我正在设置 mongoDB 服务器的地址,我只是无法意识到为什么 mongo 驱动程序会在本地主机上查找。
查看完整描述

1 回答

?
哔哔one

TA贡献1854条经验 获得超8个赞

为什么 mongo 驱动程序在 localhost 上寻找,如果我正在设置 mongoDB 服务器的地址。

当mongo-go-driver的客户端连接到MongoDB部署时,它将执行服务器发现和监控以发现一个或多个服务器(MongoDB本质上是一个分布式数据库)。早期步骤之一是通过在所有服务器上调用 isMaster 命令来开始监视拓扑。根据isMaster的输出,客户端将尝试联系这些服务器。对于副本集(您的情况),客户端会努力连接到主服务器(从 isMaster.primary)。

但是,主机名地址不是可从客户端计算机解析的完全限定域名 (FQDN)。客户端的计算机尝试连接到定义为副本集的主副本集,因此无法建立连接。此外,这就是为什么您会看到消息状态,其中 但是 .即使在能够选择要执行命令的服务器 (localhostcurrent topology: Type: UnknownState: Connectedping)

您可以通过为副本集配置中的成员字段的值设置可解析的主机名来解决此问题。此外,如果可能,请使用逻辑 DNS 主机名而不是 IP 地址,因为这可以避免由于 IP 地址更改而导致的配置更改。

您可以使用 rs.reconfig() 更改副本集主机名,即:

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

在您的情况下,只有一个副本集成员,这很简单。但是,如果您处于生产模式并且有多个成员,则可以按照更改副本集中的主机名中概述的步骤进行操作,其中有两个选项:

  • 在不中断可用性的情况下更改主机名

  • 同时更改主机名(一次性)

说了上面的所有解释, 或者,由于副本集部署只有一台服务器(开发模式),因此可以通过 ClientOptions.SetDirect() 将连接模式设置为它指定客户端是否应直接连接到服务器,而不是自动发现群集中的其他服务器(尽管这意味着您没有冗余),即:direct

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

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


查看完整回答
反对 回复 2023-07-17
  • 1 回答
  • 0 关注
  • 137 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信