C# Azure服务总线用户是否定期打电话回家?

C# Azure服务总线用户是否定期打电话回家?,c#,asp.net,azure,tcp,C#,Asp.net,Azure,Tcp,我们有一个发布/订阅应用程序,它涉及一个外部客户机通过Azure服务总线主题订阅Web角色发布者。我们当前的计费周期表明我们发送/接收了>25K条消息,而我们的仪表板表明我们发送了我想您看到的是后台的接收呼叫。在幕后,接收呼叫都使用长轮询。这意味着他们呼叫服务总线端点并请求消息。服务总线服务收到该请求,如果它有一条消息,它将立即返回该消息。如果没有消息,它将保持连接打开一段时间,以防消息到达。如果消息在该时间范围内到达,它将返回给客户端。如果消息在时间范围结束时不可用,则会向客户端发送一个响应,

我们有一个发布/订阅应用程序,它涉及一个外部客户机通过Azure服务总线主题订阅Web角色发布者。我们当前的计费周期表明我们发送/接收了>25K条消息,而我们的仪表板表明我们发送了我想您看到的是后台的接收呼叫。在幕后,接收呼叫都使用长轮询。这意味着他们呼叫服务总线端点并请求消息。服务总线服务收到该请求,如果它有一条消息,它将立即返回该消息。如果没有消息,它将保持连接打开一段时间,以防消息到达。如果消息在该时间范围内到达,它将返回给客户端。如果消息在时间范围结束时不可用,则会向客户端发送一个响应,指示没有消息(也称为空代理消息)。如果您在没有重载的情况下调用Receive(就像您在这里所做的那样),它将立即发出另一个请求。此循环继续发生,直到收到消息

因此,您看到的是客户端请求消息但没有消息的次数。长轮询使其比Windows Azure存储队列更好,因为如果没有消息,它们将立即返回空结果。对于这两种技术,实现请求的指数回退是很常见的。有很多关于如何做到这一点的例子。这减少了您需要检查队列的频率,并可以减少事务计数

回答您的问题:

  • 是的,这是正常的预期行为

  • 不,这只是一笔交易。对于Service Bus,每次将消息放入队列和每次请求消息时,您都会收到一笔交易的费用(考虑到Receive在后台多次调用,这可能有点不透明)。请注意,文档指出,每个空闲事务都会收取费用(表示接收呼叫的结果为空)

  • 同样,您可以实现一种退避方法,这样您就不会频繁地排队了。我最近听到的另一个建议是,如果您的队列没有看到大量的流量,您也可以在进入循环进行处理之前检查队列深度,看看它是否>0,如果您没有收到来自接收呼叫的消息,您可以返回到观察队列深度。我还没有试过,我想如果你太频繁地进行队列深度检查,你可能会被限制

  • 如果这些是您的生产编号,那么您的订阅并没有真正处理大量消息。在可接受的等待时间内制定一个回退政策,以便在处理之前等待,这可能是一个非常好的主意。比如,如果一条消息被搁置超过10分钟是可以的,那么创建一种退避方法,最终只需每隔10分钟检查一条消息,然后当它收到一条消息时,处理它并立即再次检查


    哦,有一个接收过载需要超时,但我不是100%服务器超时或本地超时。如果它是本地的,那么它仍然可能每X秒呼叫一次服务。我认为这是基于创建SubscriptionClient时在消息传递工厂设置上设置的OperationTimeout值。您必须对此进行测试。

    您使用什么代码来接收消息?具体来说,您是在使用OnMessage,还是在自己的呼叫中使用循环来接收?如果您使用的是Receive,那么您使用的重载是什么?我在问题中添加了我们的Receive代码。谢谢这是一个极好的回答,谢谢!带有
    serverWaitTime
    ReceiveAsync()
    重载似乎充当服务器端超时。如果我将其设置为15秒,那么模式每15秒重复一次,从服务器发送空消息开始。也谢谢你对退避政策的思考。我们的应用程序需要立即通知很少发生的事件,所以据我所知,我应该坚持使用长轮询机制?
        private void Listen()
        {
            _subscriptionClient.ReceiveAsync().ContinueWith(MessageReceived);
        }
    
        private void MessageReceived(Task<BrokeredMessage> task)
        {
            if (task.Status != TaskStatus.Faulted && task.Result != null)
            {
                task.Result.CompleteAsync();
                // Do some things...
            }
            Listen();
        }