使用 dotnetcore 连接到 mongo 数据库
Connection to mongo db using dotnetcore
我正在测试与 dotnet 核心兼容的新 MongoDB.Driver 的 c# 测试版,但我无法建立连接。我在端口 27017 下的 docker 容器上有一个 mongo 服务器 v3.3 运行ning,我可以通过 docker exec -it
和 GUI(Robomongo).
我在 project.json 中使用 "MongoDB.Driver": "2.3.0-beta1"
,我 运行 的代码如下:
public class Program
{
public static void Main(string[] args)
{
var client = new MongoClient("mongodb://localhost:27017");
var db = client.GetDatabase("newdatabase");
var collection = db.GetCollection<Person>("mycollection");
collection.InsertOne(new Person{Id = "1", Age = 32});
}
public class Person
{
public string Id{ get; set;}
public int Age{ get; set;}
}
}
我得到的异常是:
A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = WritableServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "Automatic", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", EndPoint: "Unspecified/localhost:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.PlatformNotSupportedException: This platform does not support connecting sockets to DNS endpoints via the instance Connect and ConnectAsync methods, due to the potential for a host name to map to multiple IP addresses and sockets becoming invalid for use after a failed connect attempt. Use the static ConnectAsync method, or provide to the instance methods the specific IPAddress desired.
at System.Net.Sockets.Socket.Connect(IPAddress[] addresses, Int32 port)
at System.Net.Sockets.Socket.Connect(String host, Int32 port)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.TcpStreamFactory.<ConnectAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.TcpStreamFactory.<CreateStreamAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of inner exception stack trace ---
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Servers.ServerMonitor.<HeartbeatAsync>d__27.MoveNext()" }] }.
是否有明显的我遗漏或配置错误的东西,或者这个驱动程序的使用还处于早期阶段?
实际上,如果我将本地主机更改为 127.0.0.1,它就可以工作。出于某种原因,它不喜欢这个名字(注意我使用的是 Docker 版本 1.12.0-beta21(内部版本:11019)
5a44e81a0513f32f5c49f7d2966570893451f32f 如果有帮助的话)。
在 Windows 上的 Docker-Desktop 中托管的 Kubernetes 集群中的 dotnet 核心应用程序遇到了同样的问题 运行。我尝试过基于 Debian 和 Alpine 的图像,但没有成功。
此外,这似乎不是 Docker 问题,因为来自 pod 的任何 nslookup hostname
都解析了正确的 IP 地址。
我发现的唯一解决方法是在初始化 Mongo 连接之前将主机名解析为 IP 地址,因此我最终使用实用方法:
private string GetMongoConnectionStringWithIps(string connectionString) {
var builder = new MongoUrlBuilder(connectionString);
var servers = new List<MongoServerAddress>();
foreach (var server in builder.Servers)
{
var address = Dns.GetHostAddresses(server.Host).FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
servers.Add(new MongoServerAddress(address.ToString(), server.Port));
}
builder.Servers = servers;
return builder.ToMongoUrl().ToString();
}
我正在测试与 dotnet 核心兼容的新 MongoDB.Driver 的 c# 测试版,但我无法建立连接。我在端口 27017 下的 docker 容器上有一个 mongo 服务器 v3.3 运行ning,我可以通过 docker exec -it
和 GUI(Robomongo).
我在 project.json 中使用 "MongoDB.Driver": "2.3.0-beta1"
,我 运行 的代码如下:
public class Program
{
public static void Main(string[] args)
{
var client = new MongoClient("mongodb://localhost:27017");
var db = client.GetDatabase("newdatabase");
var collection = db.GetCollection<Person>("mycollection");
collection.InsertOne(new Person{Id = "1", Age = 32});
}
public class Person
{
public string Id{ get; set;}
public int Age{ get; set;}
}
}
我得到的异常是:
A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = WritableServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "Automatic", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/localhost:27017" }", EndPoint: "Unspecified/localhost:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.PlatformNotSupportedException: This platform does not support connecting sockets to DNS endpoints via the instance Connect and ConnectAsync methods, due to the potential for a host name to map to multiple IP addresses and sockets becoming invalid for use after a failed connect attempt. Use the static ConnectAsync method, or provide to the instance methods the specific IPAddress desired.
at System.Net.Sockets.Socket.Connect(IPAddress[] addresses, Int32 port)
at System.Net.Sockets.Socket.Connect(String host, Int32 port)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.TcpStreamFactory.<ConnectAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.TcpStreamFactory.<CreateStreamAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of inner exception stack trace ---
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Servers.ServerMonitor.<HeartbeatAsync>d__27.MoveNext()" }] }.
是否有明显的我遗漏或配置错误的东西,或者这个驱动程序的使用还处于早期阶段?
实际上,如果我将本地主机更改为 127.0.0.1,它就可以工作。出于某种原因,它不喜欢这个名字(注意我使用的是 Docker 版本 1.12.0-beta21(内部版本:11019) 5a44e81a0513f32f5c49f7d2966570893451f32f 如果有帮助的话)。
在 Windows 上的 Docker-Desktop 中托管的 Kubernetes 集群中的 dotnet 核心应用程序遇到了同样的问题 运行。我尝试过基于 Debian 和 Alpine 的图像,但没有成功。
此外,这似乎不是 Docker 问题,因为来自 pod 的任何 nslookup hostname
都解析了正确的 IP 地址。
我发现的唯一解决方法是在初始化 Mongo 连接之前将主机名解析为 IP 地址,因此我最终使用实用方法:
private string GetMongoConnectionStringWithIps(string connectionString) {
var builder = new MongoUrlBuilder(connectionString);
var servers = new List<MongoServerAddress>();
foreach (var server in builder.Servers)
{
var address = Dns.GetHostAddresses(server.Host).FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
servers.Add(new MongoServerAddress(address.ToString(), server.Port));
}
builder.Servers = servers;
return builder.ToMongoUrl().ToString();
}