我们有一个托管在中的WCF主机和使用net 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;
}
我的期望是,我们正在创建一个新的代理,每次调用这个浏览函数时都会有一个新的通道和一个新的连接。
当其中一个实例重新启动时,就会出现问题
System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state
错误。现在,对于每个重新启动的主机,我们只会得到其中一个错误,但这仍然是一个我们无法避免的错误。
我目前的工作假设是,在幕后的某个地方,WCF客户机正在打开一个与不再存在的实例的连接,尽管我读到的所有内容都说它不应该存在。
除了捕获这个特定错误并重试之外,还有什么可以避免这个问题的吗?有什么模式可以重试客户端调用吗?如果我真的要重试,我怎么能确保这个不可靠的连接真的被破坏了呢?到目前为止,我的尝试还不是很成功。