特定のポートでデータベース サーバーに接続するために、10gen Mongo C# ドライバー ( github ) を使用する ASP MVC アプリがあります。これを 3 つのワーカー プロセスを持つ IIS 7.0 Web ガーデンに展開しました。数分ごとに負荷がかかると、次の例外がスローされ、ユーザーに 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 - Only one usage of each socket address (protocol/network address/port) is通常許可される
しかし、利用可能なソケットの最大数を増やして TIME_WAIT 値を減らしても、問題は影響を受けませんでした。
最近、Mongo ドライバーが接続プーリングを行っていても、各ワーカー プロセスには独自のプールがあることに気付きました。これらのプールは、連携してシステムをソケット不足で実行しているか、同じソケット アドレスを同時に使用しようとしています。後者の条件は、例外が示唆するものとまったく同じであり、サイトが単一のプロセスに展開されている場合は問題が発生しないため、可能性が高いようです。しかし、Web ガーデンの外では、パフォーマンスの低下は非常に顕著であり、プロセスがクラッシュした場合、リサイクルの遅延は容認できません。とはいえ、ユーザーが 500 の応答を受け取ることも同様に容認できません。
私は次のことを検討しました:
- すべてのデータアクセス呼び出しを try/retry-n-times/fail 構造でラップします (醜く、単なる悪い習慣です)。
- マルチプロセスからマルチマシンへの移行 (現在のユーザー負荷では高価で不要)
質問:
- これらのワーカー プロセスがアドレス/ポートを適切に共有する方法はありますか?
- 各ワーカープロセスの発信接続が異なるローカルポートを使用して同じリモートポートに接続できるような、ある種の「ポートトリガー」(正しい用語ではないことは確かです) を行う方法はありますか? リモート マシンは、同じポートで複数の着信接続を問題なく処理できます。
- ソケットが不足していると思われる場合は、プロセスごとにソケット接続の数を制限して、65536 個のソケットを共有できるようにする方法はありますか。