Azure WCF主机在一个实例重新启动时导致通信错误

时间:2010-10-13 23:55:50

标签: wcf azure nettcpbinding

我对Azure中的WCF主机有一个相当具体的问题。在描述情况时,请耐心等待。

我们使用网络TCP绑定托管了WCF主机和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客户端正在某个地方保持打开与不再存在的实例的连接,尽管我读过的所有内容都表明它不应该存在。

除了捕获此特定错误并重试之外,我有什么办法可以避免此问题吗?是否有重试客户端呼叫的模式?如果我重试,我怎么能确保这个狡猾的连接真的被废除了?到目前为止,我的重试尝试并不是很成功。

1 个答案:

答案 0 :(得分:0)

经过相当多的调查后,问题似乎不在于客户端,而在于服务器。 worker角色正在OnRun中启动WCF主机。问题是,当工作者角色进入OnRun事件时,它已经向负载均衡器发出信号,表明它已准备好接收网络流量。看到主持人还没有真正开始,它还没准备好。

解决方案是将启动WCF主机的代码移动到OnStart方法。

我们还创建了一些非常好的WCF客户端重试代码。现在我们似乎不需要。