我已经使用Docker创建了一个MongoDB副本集,并且可以使用控制台或Robo3T进行访问并运行任何查询。
容器如下所示:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES efe6ae03323d mongo "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:30001->27017/tcp mongo1 57d2701c8a43 mongo "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:30002->27017/tcp mongo2 7553966b9ff5 mongo "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:30003->27017/tcp mongo3
当我尝试使用mongo-go-driver ping时,问题是一个错误(我尝试使用1.0.0和1.0.2版)
// Create MongoDB client client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:30001")) if err != nil { t.Fatalf("Exit error: %v", err) } ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() err = client.Connect(ctx) if err != nil { t.Fatalf("Exit error: %v", err) } ctx, cancel = context.WithTimeout(context.Background(), time.Minute) defer cancel() // Ping err = client.Ping(ctx, readpref.Primary()) if err != nil { t.Fatalf("Exit error Ping: %v", err) }
Ping调用引发的错误如下:
Ping
Exit error Ping: server selection error: server selection timeout current topology: Type: ReplicaSetNoPrimary Servers: Addr: mongo2:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo2: no such host Addr: mongo3:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo3: no such host Addr: mongo1:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo1: no such host
谢谢大家的支持!
这是由于无法hostname从Docker主机解决的。在Docker中,实例mongo1,,mongo2和mongo3可通过这些名称访问。但是,无法从Docker主机访问这些名称。这行很明显:
hostname
mongo1
mongo2
mongo3
Addr: mongo2:27017, Type: Unknown, State: Connected, Average RTT: 0, Last error: dial tcp: lookup mongo2: no such host
MongoDB驱动程序将尝试server discovery从给定的副本集成员开始;它将找到副本集中的所有其他节点(通过rs.conf)。这里的问题是副本集设置为name mongo<N>,驱动程序(在Docker主机中运行)无法解析这些名称。您可以通过尝试mongo1从Docker主机ping来确认这一点。
server discovery
mongo<N>
您可以尝试从另一个与副本集共享同一Docker网络的Docker实例运行该应用程序。或者,这样修改Docker网络以允许使用可解析的主机名。
更新:
关于您为什么使用mongo shell或PyMongo起作用的评论。
这是由于连接模式不同所致。当指定单个节点时,即mongodb://node1:27017在shell或PyMongo中,不会进行服务器发现。相反,它将尝试连接到该单个节点(而不是作为副本集的一部分)。要注意的是,您需要连接到副本集的主节点进行写入(您必须知道哪个)。如果要作为副本集进行连接,则必须定义副本集名称。
mongodb://node1:27017
与相比mongo-go- driver,默认情况下,它将执行服务器发现并尝试作为副本集进行连接。如果要作为单个节点进行连接,则需要connect=direct在连接URI中指定。另请参见直接连接示例
mongo-go- driver
connect=direct