- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我们的发布/订阅应用程序涉及外部客户端通过 Azure 服务总线主题订阅 Web 角色发布者。我们当前的计费周期表明我们已发送/接收了 >25K 条消息,而我们的仪表板表明我们已发送了 <100 条消息。我们正在调查我们的实现情况并检查我们的假设,以了解差异。
作为调查的一部分,我们收集了客户端计算机上客户端<=>服务总线流量的wireshark捕获。我们注意到一种没有记录的常规沟通模式,希望更好地理解。当总线上没有任何事件时,以下交换每 50 秒发生一次:
一些相关信息:
问题
编辑:
这是接收消息的代码:
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();
}
最佳答案
我认为您看到的是后台的 Receive 调用。在幕后,接收调用都使用长轮询。这意味着他们调用服务总线端点并请求消息。服务总线服务收到该请求,如果有消息,它将立即返回。如果没有消息,它将保持连接打开一段时间,以防消息到达。如果消息在该时间范围内到达,它将被返回给客户端。如果在时间范围结束时消息不可用,则会向客户端发送响应,表明那里没有消息(也称为空 BrokeredMessage)。如果您在没有重载的情况下调用 Receive(就像您在此处所做的那样),它将立即发出另一个请求。这个循环持续发生,直到收到消息。
因此,您看到的是客户端请求消息但实际上没有消息的次数。长轮询比 Windows Azure 存储队列更好,因为如果没有消息,它们将立即返回空结果。对于这两种技术,通常都会对请求实现指数退避。有很多关于如何做到这一点的例子。这减少了您检查队列的频率,并可以减少您的交易数量。
回答您的问题:
是的,这是正常的预期行为。
不,这只是一笔交易。对于服务总线,每次将消息放入队列以及每次请求消息时,都会向您收取一笔事务费用(考虑到 Recieve 在后台多次调用,这可能有点不透明)。请注意,文档指出您需要为每笔空闲事务付费(这意味着 Receive 调用的结果为空)。
同样,您可以实现退避方法,这样您就不会经常排队。我最近听到的另一个建议是,如果您有一个没有看到大量流量的队列,您还可以在进入循环进行处理之前检查队列深度,看看它是否> 0,以及是否没有收到任何消息返回接到电话后,您可以返回查看队列深度。我没有尝试过,如果您过于频繁地进行队列深度检查,我认为您可能会受到限制。
如果这些是您的生产编号,那么您的订阅并没有真正处理大量消息。在处理之前制定一个可以接受的等待时间的退避策略可能是一个非常好的主意。比如,如果一条消息可以停留超过 10 分钟,那么就创建一种退避方法,最终每 10 分钟检查一次消息,然后当它收到一条消息时处理它并立即再次检查。
哦,有一个接收过载需要超时,但我不是 100% 那是服务器超时或本地超时。如果它是本地的,那么它仍然可能每 X 秒对服务进行一次调用。我认为这是基于创建 SubscriptionClient 时在消息工厂设置中设置的 OperationTimeout 值。您必须对此进行测试。
关于c# - Azure 服务总线订阅者定期给家里打电话?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18598449/
我是一名优秀的程序员,十分优秀!