1

我有一个 ASP MVC 应用程序,它使用 10gen Mongo C# 驱动程序 ( github ) 连接到特定端口上的数据库服务器。我已将其部署在具有 3 个工作进程的 IIS 7.0 网络花园中。每隔几分钟,在负载下,就会抛出以下异常,并向用户返回 500:

Only one usage of each socket address (protocol/network address/port) is normally permitted <database-ip>:<database-port>

Stack Trace:    

   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at System.Net.Sockets.TcpClient.Connect(IPEndPoint remoteEP)
   at MongoDB.Driver.Internal.MongoConnection.Open() in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Internal\MongoConnection.cs:line 266
   at MongoDB.Driver.Internal.MongoConnection.GetNetworkStream() in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Internal\MongoConnection.cs:line 409
   at MongoDB.Driver.Internal.MongoConnection.SendMessage(MongoRequestMessage message, SafeMode safeMode) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Internal\MongoConnection.cs:line 377
   at MongoDB.Driver.Internal.MongoConnection.RunCommand(String collectionName, QueryFlags queryFlags, CommandDocument command) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Internal\MongoConnection.cs:line 296
   at MongoDB.Driver.Internal.MongoConnection.Authenticate(String databaseName, MongoCredentials credentials) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Internal\MongoConnection.cs:line 98
   at MongoDB.Driver.Internal.MongoConnection.CheckAuthentication(MongoDatabase database) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Internal\MongoConnection.cs:line 195
   at MongoDB.Driver.MongoServerInstance.AcquireConnection(MongoDatabase database) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoServerInstance.cs:line 185
   at MongoDB.Driver.MongoServer.AcquireConnection(MongoDatabase database, Boolean slaveOk) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoServer.cs:line 893
   at MongoDB.Driver.MongoCursorEnumerator`1.AcquireConnection() in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoCursorEnumerator.cs:line 184
   at MongoDB.Driver.MongoCursorEnumerator`1.GetFirst() in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoCursorEnumerator.cs:line 194
   at MongoDB.Driver.MongoCursorEnumerator`1.MoveNext() in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoCursorEnumerator.cs:line 126
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
   at MongoDB.Driver.MongoCollection.FindOneAs[TDocument](IMongoQuery query) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoCollection.cs:line 493
   at MongoDB.Driver.MongoCollection.FindOneByIdAs[TDocument](BsonValue id) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoCollection.cs:line 529
   at MongoDB.Driver.MongoCollection`1.FindOneById(BsonValue id) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Core\MongoCollection.cs:line 1462

我花了很多时间在谷歌上搜索这个异常并且几乎说服自己我的套接字用完了,如 WCF 中所述:System.Net.SocketException - 每个套接字地址(协议/网络地址/端口)只有一种用法是通常允许

但是这个问题不受我增加可用套接字的最大数量和减少 TIME_WAIT 值的影响。

我最近突然想到,即使 Mongo 驱动程序执行连接池,每个工作进程都有自己的池。这些池要么一起工作以使系统脱离套接字,要么只是试图同时使用相同的套接字地址。后一种情况似乎更有可能,因为这正是异常所暗示的,并且当站点部署到单个进程时问题不会发生。但是在网络花园之外,性能下降非常明显,如果进程崩溃,回收延迟是不可接受的。也就是说,获得 500 条回复的用户同样是不可接受的。

我考虑了以下几点:

  1. 将所有数据访问调用包装在一个 try/retry-n-times/fail 结构中(丑陋而简单的坏习惯)
  2. 过渡到多机而不是多进程(在当前用户负载下昂贵且不必要)

问题:

  1. 有什么方法可以让这些工作进程优雅地共享地址/端口?
  2. 有没有办法进行某种“端口触发”(我敢肯定,这不是正确的术语),每个工作进程的传出连接可以使用不同的本地端口连接到同一个远程端口?远程机器可以在同一个端口上处理多个传入连接,而不会出现问题。
  3. 如果您认为我的套接字用完了,有没有办法限制每个进程的套接字连接数,以便它们可以共享 65536 个套接字。
4

0 回答 0