从 Azure 事件中心获取事件后,我是否应该将它们放入队列中?

Should I put my events inside a queue after getting them from Azure Event Hub?

我目前正在开发一个托管在 Azure 上并使用 Azure 事件中心的应用程序。基本上,我从 Web API 向事件中心发送消息(或者我应该说,事件),并且我有两个侦听器:

我目前正在使用 EventProcessorHost 库从我的工作者角色内的事件中心检索我的事件。

我正在尝试寻找一些关于如何使用事件中心的最佳实践(使用事件中心比使用服务总线队列要难一些,即流式处理与消息消费),我发现有人说 从我的事件中心.

检索 EventData 事件后,我不应该做很多处理

具体来说:

Keep in mind you want to keep whatever it is you're doing relatively fast - i.e. don't try to do many processes from here - that's what consumer groups are for.

The author of this article added a queue between the Event Hub and the worker role (it's not clear from the comments if it's really required or not).

所以问题是:我是否应该在事件中心 之后直接执行所有处理工作(即在 IEventProcessor 实现的 ProcessEventsAsnyc 方法中), 还是我应该在事件中心和处理内容之间使用队列

任何有关如何正确使用来自事件中心的事件的建议都将不胜感激,文档目前有点……缺失。

这属于问题的类别,一旦 EventProcessorHost 的源可用,答案就会更加明显,我听说这将会发生。

简短的回答是您不需要使用队列;但是,我会保持 ProcessEventsAsync 到 return 任务所需的时间相对较短。

虽然这条建议听起来很像 first article 的建议,但关键区别在于它是 return 执行任务的时间,而不是完成任务的时间。我的假设是在用于 EventProcessorHost 的线程上调用 ProcessEventsAsync 用于其他目的。在这种情况下,您需要快速 return 以便其他工作可以继续进行;这项工作可能正在为另一个分区调用 ProcessEventsAsync(但如果不进行调试我们就不知道我还没有发现有必要这样做或在可用时阅读代码)。

我通过从 ProcessEventsAsync 传递整个 IEnumerable,在每个分区的单独线程上进行处理。这与从 IEnumerable 中取出所有项目并将它们放入队列以供处理线程使用形成对比。另一个线程在完成消息处理后完成由 ProcessEventsAsync 编辑的任务 return。 (我实际上为我的处理线程提供了一个 IEnumerable,它通过将块链接在一起并在需要时在调用 MoveNext 时完成任务来隐藏 ProcessEventsAsync 的详细信息)。

简而言之:在 ProcessEventsAsync 中,将工作移交给另一个线程,您已经拥有并知道如何与之通信的线程,或者使用 TPL 启动新任务。

将所有消息放入 ProcessEventsAsync 内部的队列并不是 不好的,它只是将事件块传递给另一个线程的最有效方式。

如果您决定将事件放入队列(或者在您的处理代码中有一个下游队列)并完成该批次的任务,您应该确保限制您的 code/queue 以避免 运行 在 EventHub 为您提供项目的速度比您的代码由于流量高峰而处理它们的速度更快的情况下内存不足。

Java EventHub 用户注意事项 2016-10-27: 由于这引起了我的注意,this description describing how onEvents is called, while onEvents 变慢不会是悲剧,因为它在每个分区的线程上,它的速度 似乎 会影响下一批的速度已收到。因此,取决于您对延迟的关心程度,这里的延迟对于您的场景来说可能相对重要。