我对 Azure 中的 WCF 主机有一个相当具体的问题。请耐心等待我描述情况。
我们有一个 WCF 主机托管在使用网络 TCP 绑定的 Azure 辅助角色中。我们有两个运行此工作者角色的实例来提供冗余。由于与我们的问题无关的原因,我们通过每小时更改配置设置来强制重启这些实例。由于升级域,一个实例在第二个实例之前重新启动,这意味着我们始终至少有一个实例在运行。
我们的客户端代码(也在 Azure 上运行,但我认为它在哪里并不重要)看起来与此非常相似(更改了函数名称以夸大其词):
public BrowseResults Browse(BrowseParameters parameters)
{
using (Proxy client = CreateProxyWithBindingsAndEndPoints())
{
return client.Browse(parameters);
}
}
private Proxy CreateProxyWithBindingsAndEndPoints()
{
var binding = new NetTcpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
binding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;
var epAddress = new EndpointAddress(
new Uri("http://myapp.cloudapp.net:1000/myservice"),
new DnsEndpointIdentity("my identity"),
new AddressHeaderCollection());
var client = new Proxy(binding, epAddress);
client.ClientCredentials.ClientCertificate.Certificate = GetClientCertificate();
return client;
}
我对此的期望是,每次我们调用这个 Browse 函数时,我们都会创建一个新的代理,一个新的通道和一个新的连接。
我们的问题发生在其中一个实例重新启动时System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state
出现错误。现在,对于每个重新启动的主机,我们只会得到其中一个错误,但这仍然是一个我们不能没有的错误。
我目前的工作假设是,WCF 客户端在引擎盖下的某处保持与不再存在的实例的连接,尽管事实上我读过的所有内容都表明它不应该存在。
除了捕获这个特定错误并重试之外,我还能做些什么来避免这个问题?是否有任何模式可以重试客户端调用?如果我重试,我怎样才能确保这个狡猾的连接真的被取消了?到目前为止,我的重试尝试并不是很成功。