3

我有一个托管在 IIS 7 上的 WCF 服务,它成功运行了一段时间,然后无法与其他网络位置通信(我怀疑没有可用于连接到外部世界的 TCP 端口)

申请背景:

我的系统对大型媒体文件进行转码(这需要时间)。我有一个集中托管的 WCF 服务,它位于服务器 A 上 - 这将被称为“中央 WCF 服务”。然后,我有许多客户端服务,它们对不同服务器上的媒体文件进行实际转码:B、C、D、E、F 等等 - 这将被称为“客户端处理器服务”。中央 WCF 服务管理发送“转码作业”以进行处理的客户端处理器服务。这些客户端处理器服务中的每一个都是自托管的 WCF 服务,它们基本上执行长时间运行的过程,并由中央 WCF 服务检查作业进度百分比进行轮询。因此,中央 WCF 服务打开了与这些客户端的大量连接,以轮询他们的工作进度,

中央 WCF 服务存储客户端处理器服务的地址字符串列表。下面描述了用于轮询每个客户端的代码(精简版):

public ClientProcessorClient getClientByaddress(string address)
{
    Binding bidning = new NetTcpBinding(SecurityMode.None);
    return new ClientProcessorClient(bidning, new EndpointAddress(address));
}

public void pollJobs()
{
    foreach (string clientAddress in clients)
    {
        ClientProcessorClient client = getClientByaddress(clientAddress);
        int progress = client.GetProgress();
        client.Close();
        // Do stuff with progress
    }
}

当它破裂时会发生什么:

我可以向中央 WCF 服务提交许多转码作业,它会将作业提交给客户端,成功更新进度等。在处理了大约一个小时后,托管中央 WCF 服务的服务器停止正常工作。Insufficient winsock resources available to complete socket connection initiation.尝试联系客户端 WCF服务时,中央 WCF 服务会引发错误。客户端 WCF 服务都可以从我的本地计算机上运行的 WCF 测试客户端 ping 通。我还注意到,在这种状态下,服务器无法查看网络文件资源 - 我已经远程登录并尝试找到网络连接的存储文件夹,但无法连接。但是,我可以调用该服务器,例如,我可以打开 WCF 测试客户端并连接到中央 WCF 服务并调用它的 ping 方法。通信允许从服务器输入但不允许输出。

几个兴趣点:

在故障状态下,可以建立到服务器的连接,但不能从服务器建立。

我的每个服务(中央 WCF 服务和客户端处理器服务)都是单例实例。

中央 WCF 服务托管在 IIS 7 中,应用程序池回收已禁用

不幸的是,命名管道不是一个选项(客户端和服务器在不同的机器上)

我的想法/问题

所有迹象都指向服务器耗尽 TCP 套接字。我ClientProcessorClient是否正确设置了 WCF ?我是否妥善处理了它们?我需要将它们包装在using声明中吗?有人知道我如何调试/诊断问题发生的位置吗?

谢谢

4

1 回答 1

1

无论好坏,Microsoft 决定实现 WCF 服务代理逻辑(ClientBase 或直接来自 ChannelFactory)以允许在 Close() 方法中引发异常。我相信所有 Dispose() 方法都是调用 Close() 但我从未尝试查看源代码。如果代理处于故障状态,则必须调用 Abort() 来释放资源(例如 TCP 会话)。

这意味着 WCF 服务代理在对 Close() 或 Abort() 的调用成功完成之前不会释放资源。查看此博客文章,了解正确关闭代理实例的一个选项。

于 2012-04-12T13:00:19.487 回答