我们有pub / sub应用程序,涉及通过Azure Service Bus主题订阅Web角色发布者的外部客户端.我们当前的结算周期表示我们已发送/接收了> 25K消息,而我们的信息中心表示我们已发送< 100.我们正在调查我们的实施并检查我们的假设,以便了解这种差异. 作为调查的一部分,我们在客户端计算机上收集了客户端< =>服务总线流量的wireshark捕获.我们注意到了一种我们尚未见过的常规沟通模式,并且希望更好地理解.如果总线上没有任何活动,则每50秒进行一次以下交换:
>客户端将~200B推送到服务总线.
> 10s后,服务总线将~800B推送到客户端.客户端注册空消息的接收(通过断点确定).
>客户端立即响应〜1000B到服务总线.
一些相关信息:
>当我们的Web角色没有主动将数据推送到服务总线时,就会发生这种情况.
>从Web角色收到合法消息后,上述模式将不会再发生,直到完整的50秒过去.
>客户端和服务器都通过TCP连接到sb://namespace.servicebus.windows.net.
>我们的应用程序消息是<64 KB
问题
>我们看到的常规3分组消息交换负责什么?它是某种保持活力吗?
> 3个数据包中的每个数据包都算作单独的可计费消息吗?
>此行为是可配置还是以其他方式记录?
编辑:
这是接收消息的代码:
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();
}
解决方法:
我认为你所看到的是后台的接听电话.在幕后,接收呼叫都使用长轮询.这意味着他们呼叫服务总线端点并要求提供消息. Service Bus服务获取该请求,如果有消息,它将立即返回.如果它没有消息,它将保持连接打开一段时间以防消息到达.如果消息在该时间范围内到达,则将其返回给客户端.如果在时间帧结束时消息不可用,则会向客户端发送响应,指示没有消息存在(也就是您的null BrokeredMessage).如果您在没有重载的情况下调用Receive(就像您在此处所做的那样),它将立即发出另一个请求.此循环继续发生,直到收到消息.
因此,您看到的是客户端请求消息但在那里没有消息的次数.长轮询使其比Windows Azure存储队列更好,因为如果没有消息,它们将立即返回null结果.对于这两种技术,通常会对请求实施指数退避.有很多关于如何做到这一点的例子.这会减少您检查队列的频率,并可以减少您的交易次数.
回答你的问题:
>是的,这是正常的预期行为.
>不,这只是一笔交易.对于Service Bus,每次将消息放入队列并且每次请求消息时都会收取一笔交易(鉴于Recieve在后台多次拨打电话,这可能会有点不透明).请注意,文档指出您为每个空闲事务收取费用(意味着来自Receive调用的null结果).
>同样,您可以实施退避方法,以便您不会经常访问队列.我最近听到的另一个建议是,如果你有一个没有看到大量流量的队列,你也可以检查队列深度,看看它是否是>在进入循环进行处理之前为0,如果从接收呼叫中没有收到任何消息,您可以返回查看队列深度.我没有尝试过,如果你经常进行队列深度检查,你可能会受到限制.
如果这些是您的生产数字,那么您的订阅并不真正处理大量消息.在处理之前等待可以接受的时间可能是一个非常好的主意.比如,如果一条消息可以存在超过10分钟,那么创建一个退出方法,最终每10分钟检查一条消息,然后当它获得一个进程并立即再次检查时.
哦,有一个接收超载,需要超时,但我不是100%,这是服务器超时或本地超时.如果它是本地的,那么它仍然可以每隔X秒向服务进行一次调用.我认为这是基于在创建SubscriptionClient时在Messaging Factory设置上设置的OperationTimeout值.你必须测试一下.
原文地址:https://codeday.me/bug/20190612/1227965.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。