MongoDB连接导致System.Net.Sockets.SocketException

4
我有几个运行相同asp.net mvc web应用程序的Web服务器,连接到一个mongodb服务器。其中一个Web服务器不断抛出SocketException异常,即使我重新启动IIS。其他服务器工作正常。这不是第一次出现异常。几周前,另一个Web服务器也遇到了同样的问题,而当时其他服务器是正常工作的。错误信息如下:
“由于系统缺乏足够的缓冲区空间或队列已满,无法对套接字执行操作。”

现在我只能重启服务器来临时解决这个问题。我通过修改 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort 为65534 来确保Web服务器的动态端口范围正确设置。现在我怀疑这是否是C# mongodb驱动程序的一个bug。我查看了驱动程序的源代码,特别是 MongoCursorEnumerator.cs,连接被释放的地方。类MongoCursorEnumerator<TDocument>实现了IDisposable并在其Dispose方法中正确释放了连接。但它没有析构函数(finalizer),这保证在GC中调用Dispose

现在我确保项目中所有与连接相关的代码都被正确包装在using块中。在这种情况下,缺少析构函数/终结器会导致SocketException吗?如果不是,那么这个异常的可能原因是什么?

更多信息:ASP.NET MVC 3,Windows Server 2008 R2,Mongo DB 2.0,Mongo Db Driver for C# 1.5

更新

最新版本的MongoDB C#驱动程序已解决此问题。


MongoCursorEnumerator<T> 实现了 IEnumerable 接口,这意味着编译器会在 finally 块中发出对其 dispose 方法的调用。假设它在 foreach 循环中使用,就不需要终结器。如果手动使用枚举器,则有可能不会调用 dispose。 - Christopher Currens
@ChristopherCurrens:我个人也认为dispose方法一定会被调用。这个异常确实很奇怪。 - Cheng Chen
2个回答

0

这个错误的一个可能原因(来自Windows操作系统)是当TCP/IP连接快速打开和关闭时。

你的代码中是否任何地方调用了Disconnect?这将导致所有套接字被关闭,然后会开启新的套接字来替换它们。


我大约有1%的概率(每秒约10次写入)会遇到这个错误 - 对于这个问题,一些try/catch/retry代码是常见建议吗? - Mark Gibaud

0
升级到2.12或更高版本的mongodb驱动程序将允许您捕获此异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接