Does ServiceBusReceiver use a pull or a push communication model when talking to Azure Service Bus?

huangapple go评论73阅读模式
英文:

Does ServiceBusReceiver use a pull or a push communication model when talking to Azure Service Bus?

问题

调用和等待 ServiceBusReceiver.ReceiveMessageAsync()ServiceBusReceiver.ReceiveMessageAsync(TimeSpan.FromMinutes(10)) 时,幕后究竟发生了什么?

是:

a.) ServiceBusReceiver 从 Azure Service Bus 进行(长时间)轮询,还是

b.) Azure Service Bus 以某种方式向 ServiceBusReceiver 推送通知?

我尝试查看了 源代码,但没有取得多大进展,因为使用了一个名为 InnerReceiver 的类,我在代码库中找不到。

英文:

Just out of curiosity: What exactly happens behind the scenes when we call and await ServiceBusReceiver.ReceiveMessageAsync() or ServiceBusReceiver.ReceiveMessageAsync(TimeSpan.FromMinutes(10))?

Does

a.) the ServiceBusReceiver (long-)poll Azure Service Bus or does

b.) Azure Service Bus send somehow push notifications to the ServiceBusReceiver?

I tried to look into the source code, but didn't get far, because some class InnerReceiver is used that I couldn't find in the code base.

答案1

得分: 6

在ServiceBus SDK层面上,它是一个拉取通信模型,只是为了更好地处理传入消息的确认。

但在幕后,Azure服务总线SDK使用了高级消息队列协议1.0,它不使用长轮询,而是在相同的AmqpConnection上使用AmqpLinks将数据从发送方发送到接收方,接收方将传入的消息保存到内存缓冲区中。

您可以在这里了解更多信息,或者观看Microsoft关于AMQP 1.0协议的视频系列。

所以看起来对于“幕后究竟发生了什么”的答案既不是A也不是B,消息被推送到ReceivingAmqpLink(到内存缓冲区),然后ServiceBusReceiver从中拉取。

我希望这个答案能结束这个讨论,大家都会很高兴 Does ServiceBusReceiver use a pull or a push communication model when talking to Azure Service Bus?

源代码:

Azure.Messaging.ServiceBus

Azure.Amqp

ServiceBusReceiver 包装了 AmqpReceiver

包装了 AmqpReceiverReceiveMessagesAsync

AmqpReceiver 构造函数中创建 ReceivingAmqpLink

在可能的情况下在相同连接上打开 ReceivingAmqpLink

ReceivingAmqpLink 的缓冲区中缓存消息

将消息从缓冲区拉入 ReceiveAsyncResult

创建 ReceiveAsyncResult 的公共异步函数

AmqpReceiver.ReceiveMessagesAsync 上调用那个“公共异步函数”

英文:

FINAL EDIT

On the ServiceBus Sdk level it is a pull communication model, just to better handle confirmation of incoming messages.

But behind the scenes azure service bus sdk uses Advanced Message Queuing Protocol 1.0 which doesn't long poll, it uses AmqpLinks on the same AmqpConnection to send data from a sender to a receiver, and the receiver saves the incoming messages to an in-memory buffer on receiving them.

You can read more about it here
or See this video series from Microsoft about the AMQP 1.0 protocol.

So it seems that the answer to "What exactly happens behind the scenes" is neither A nor B, Messages are being pushed to the ReceivingAmqpLink (to an in-memory buffer), which then the ServiceBusReceiver pulls from.

I hope this answer will close this discussion, and everyone will be happy Does ServiceBusReceiver use a pull or a push communication model when talking to Azure Service Bus?

The source codes:

Azure.Messaging.ServiceBus

Azure.Amqp

ServiceBusReceiver wraps the AmqpReceiver

wrapping the ReceiveMessagesAsync of the AmqpReceiver

Creating the ReceivingAmqpLink in the constructor of the AmqpReceiver

Opening the ReceivingAmqpLink on the same connection if possible

Caching the messages on the ReceivingAmqpLink's buffer

Pulling the messages from the buffer into the ReceiveAsyncResult

The public async function that creates the ReceiveAsyncResult

Calling the that "public async function" on AmqpReceiver.ReceiveMessagesAsync

答案2

得分: 2

I think @Ethen.S answer is not correct. Moreover neither (a) nor (b) from original question are true:

You might want to take a look at Azure.Messaging.ServiceBus.ServiceBusProcessor (use StartProcessingAsync method as an entry point for investigation) source to better understand the dichotomy there. It exposes an event that you subscribe to and handle the messages "reactively", but it still does a sequence of the ReceiveMessageAsync for you. What might look "push" model from the consumer perspective might still rely on "poll" model behind the scenes.

Please also note that there is a concept of Message Prefetching which can optimize some of the consumption scenarios, but it has its caveats to be considered as well (see https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-prefetch?tabs=dotnet#why-is-prefetch-not-the-default-option). It is still the same polling strategy, but with an additional client-level buffer on top.

UPDATE. I dug deeper into that to capture what happens on wire.

I've used sslsplit in order to make MITM attack to capture TLS-protected AMQP connection decrypted data. Test application setup is simple:

  • Receiver is doing ReceiveMessageAsync in a loop
  • After some time sender sends a message (two times)

In summary, this is indeed neither "poll" nor "push" as definitions are rather vague. What we can say for sure is that:

  • it uses persistent TCP connection
  • receival is controlled by the Client side using "Link Credit" (via the "flow" performative)
  • when the client is idle waiting for messages once in about 30 seconds empty AMQP message is sent
  • Service Bus has a mechanism to notify the receiver efficiently if there are enough "Link Credit."

I've put test code and test harness here: https://github.com/gubenkoved/amqp-test.

Below is the capture results, I've colored sender/receiver TCP streams as red/green.

Does ServiceBusReceiver use a pull or a push communication model when talking to Azure Service Bus?

英文:

I think @Ethen.S answer is not correct. Moreover neither (a) nor (b) from original question are true:

You might want to take a look at Azure.Messaging.ServiceBus.ServiceBusProcessor (use StartProcessingAsync method as an entry point for investigation) source to better understand the dichotomy there. It exposes an event that you subscribe to and handle the messages "reactively", but it still does a sequence of the ReceiveMessageAsync for you. What might look "push" model from the consumer perspective might still rely on "poll" model behind the scenes.

Please also note that there is a concept of Message Prefetching which can optimise some of the consumption scenarios, but it has its caveats to be considered as well (see https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-prefetch?tabs=dotnet#why-is-prefetch-not-the-default-option). It is still the same polling strategy, but with an additional client-level buffer on top.

UPDATE. I dug deeper into that to capture what happens on wire.

I've used sslsplit in order to make MITM attack to capture TLS-protected AMQP connection decrypted data. Test application setup is simple:

  • Receiver is doing ReceiveMessageAsync in a loop
  • After some time sender sends a message (two times)

In summary, this is indeed neither "poll" nor "push" as definitions are rather vague. What we can say for sure is that:

  • it uses persistent TCP connection
  • receival is controlled by the Client side using "Link Credit" (via the "flow" performative)
  • when client is idle waiting for messages once in about 30 seconds empty AMQP message is sent
  • Service Bus has mechanism to notify the receiver efficiently if there are enough "Link Credit"

I've put test code and test harness here: https://github.com/gubenkoved/amqp-test.

Below is the capture results, I've colored sender/receiver TCP streams as red/green.

Does ServiceBusReceiver use a pull or a push communication model when talking to Azure Service Bus?

答案3

得分: 1

根据此部分的Azure应用架构指南,Azure Service Bus消费者在与Azure Service Bus通信时使用轮询模型:

拉取模型

Service Bus队列的消费者不断轮询Service Bus,以检查是否有新的消息可用。客户端SDK和Azure Functions触发器用于抽象该模型。当有新消息可用时,将调用消费者的回调函数,并将消息发送给消费者。

由于ServiceBusReceiver是这样的消费者,它可能使用轮询。

英文:

According to this section of the Azure Application Architecture Guide, Azure Service Bus consumers use a poll model when talking to Azure Service Bus:

> Pull model
>
> A consumer of a Service Bus queue constantly polls Service Bus to check if new messages are available. The client SDKs and Azure Functions trigger for Service Bus abstract that model. When a new message is available, the consumer's callback is invoked and the message is sent to the consumer.

Since ServiceBusReceiver is such a consumer, it probably uses polling.

huangapple
  • 本文由 发表于 2023年3月1日 16:44:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75601341.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定