好吧,我有一个多路径vm在M1 mac上运行。它正在托管一个ubuntu服务器。在这个ubuntu服务器上,我安装了go、gin和其他一些相关技术。然后我到了蒙戈。
我首先用sudo docker network create mongoCluster
创建复制集
然后我旋转三个节点:
sudo docker run -d -p 27017:27017 --name mongo1 --network mongoCluster -e MONGODB_INITDB_ROOT_USERNAME=myuser -e MONGODB_INITDB_ROOT_PASSWORD=mypassword -e MONGO_INITDB_DATABASE=task mongo:latest mongod --replSet myReplicaSet --bind_ip localhost,mongo1
sudo docker run -d -p 27018:27017 --name mongo2 --network mongoCluster mongo:latest mongod --replSet myReplicaSet --bind_ip localhost,mongo2
sudo docker run -d -p 27019:27017 --name mongo3 --network mongoCluster mongo:latest mongod --replSet myReplicaSet --bind_ip localhost,mongo3
然后我用初始化复制集
sudo docker exec -it mongo1 mongosh --eval "rs.initiate({
_id: "myReplicaSet",
members: [
{_id: 0, host: "mongo1"},
{_id: 1, host: "mongo2"},
{_id: 2, host: "mongo3"}
]
})"
运行sudo docker exec -it mongo2 mongosh --eval "rs.status()"
向我展示了将mongo1作为PRIMARY 的所有设置都是正确的
到目前为止一切都很好!
然后我启动我的应用程序,并与uri建立连接:mongodb://myuser:mypassword@localhost:27017/?retryWrites=true&w=majority
Mongo抛出一个错误Failed to ping cluster
,但它随后报告它已连接然后它抛出这个:
Could not create Task: server selection error: context deadline exceeded, current topology: { Type: ReplicaSetNoPrimary, Servers: [{ Addr: mongo1:27017, Type: Unknown, Last error: connection() error occurred during connection handshake: dial tcp: lookup mongo1: Temporary failure in name resolution }, { Addr: mongo2:27017, Type: Unknown, Last error: connection() error occurred during connection handshake: dial tcp: lookup mongo2: Temporary failure in name resolution }, { Addr: mongo3:27017, Type: Unknown, Last error: connection() error occurred during connection handshake: dial tcp: lookup mongo3: Temporary failure in name resolution }, ] }
所以看起来各个节点看不到彼此我已经搜索谷歌有一段时间了,但似乎没有什么能解决我的特定问题
为了解决这个问题,我甚至把钱花在了一个培训课程上,但没有。请帮忙!
这里有一些问题。
首先,MONGODB_INITDB_ROOT_USERNAME
和MONGODB_INITDB_ROOT_PASSWORD
是错误的。它们应该是MONGO_INITDB_ROOT_USERNAME
和MONGO_INITDB_ROOT_USERNAME
。
问题是mongo1
将在启动后不久崩溃,因为它需要secret.key
。检查日志,您会看到错误。解决这个问题是另一个问题。
我建议先在没有身份验证的情况下尝试。以下是行之有效的方法:
你错过的步骤:
echo 127.0.0.1 mongo1 >> /etc/hosts
数据库启动脚本:
#!/bin/bash
docker container rm -f mongo1 mongo2 mongo3
docker run -d -p 27017:27017 --name mongo1 --network mongoCluster mongo:latest mongod --replSet myReplicaSet --bind_ip_all
docker run -d -p 27018:27017 --name mongo2 --network mongoCluster mongo:latest mongod --replSet myReplicaSet --bind_ip_all
docker run -d -p 27019:27017 --name mongo3 --network mongoCluster mongo:latest mongod --replSet myReplicaSet --bind_ip_all
docker exec -it mongo1 mongosh --eval "rs.initiate({
_id: "myReplicaSet",
members: [
{_id: 0, host: "mongo1"},
{_id: 1, host: "mongo2"},
{_id: 2, host: "mongo3"}
]
})"
go中的测试程序:
package main
import (
"context"
"fmt"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
)
const uri = "mongodb://mongo1:27017/task?replicaSet=myReplicaSet&retryWrites=true&w=majority"
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
if err != nil {
panic(err)
}
defer func() {
if err = client.Disconnect(ctx); err != nil {
panic(err)
}
}()
if err := client.Ping(ctx, readpref.Primary()); err != nil {
panic(err)
}
fmt.Println("Successfully connected and pinged")
}
运行这个,你应该会得到一个成功的回应:
> go run ./main.go
Successfully connected and pinged
此外,我认为您不需要映射主机上的所有复制副本端口。这应该会让东西更干净。