Joh*_*err 4 c# asp.net tcp azure
我们有pub/sub应用程序,涉及通过Azure Service Bus主题订阅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();
}
Run Code Online (Sandbox Code Playgroud)
我认为你所看到的是后台的接听电话.在幕后,接收呼叫都使用长轮询.这意味着他们呼叫服务总线端点并要求提供消息.Service Bus服务获取该请求,如果有消息,它将立即返回.如果它没有消息,它将保持连接打开一段时间以防消息到达.如果消息在该时间范围内到达,则将其返回给客户端.如果在时间帧结束时消息不可用,则会向客户端发送响应,指示没有消息(也就是您的null BrokeredMessage).如果您在没有重载的情况下调用Receive(就像您在此处所做的那样),它将立即发出另一个请求.此循环继续发生,直到收到消息.
因此,您看到的是客户端请求消息但在那里没有消息的次数.长轮询使其比Windows Azure存储队列更好,因为如果没有消息,它们将立即返回null结果.对于这两种技术,通常会对请求实施指数退避.有很多关于如何做到这一点的例子.这会减少您检查队列的频率,并可以减少您的交易次数.
回答你的问题:
是的,这是正常的预期行为.
不,这只是一笔交易.对于Service Bus,每次将消息放入队列并且每次请求消息时都会收取一笔交易(鉴于Recieve在后台多次拨打电话,这可能会有点不透明).请注意,文档指出您为每个空闲事务收取费用(意味着来自Receive调用的null结果).
同样,您可以实现退避方法,以便您不会经常访问队列.我最近听到的另一个建议是,如果你有一个没有看到大量流量的队列,你也可以在进入循环进行处理之前检查队列深度,看它是否> 0,如果你没有收到任何消息接听电话你可以回去看队列深度.我没有尝试过,如果你经常进行队列深度检查,你可能会受到限制.
如果这些是您的生产数字,那么您的订阅并不真正处理大量消息.在处理之前等待可以接受的时间可能是一个非常好的主意.比如,如果一条消息可以存在超过10分钟,那么创建一个退出方法,最终每10分钟检查一条消息,然后当它获得一个进程并立即再次检查时.
哦,有一个接收超载,需要超时,但我不是100%,这是服务器超时或本地超时.如果它是本地的,那么它仍然可以每隔X秒向服务进行一次调用.我认为这是基于在创建SubscriptionClient时在Messaging Factory设置上设置的OperationTimeout值.你必须测试一下.
| 归档时间: |
|
| 查看次数: |
290 次 |
| 最近记录: |