我目前正在开发一个托管在Azure上的应用程序,该应用程序使用Azure事件中心。基本上,我从Web API向Event Hub发送消息(或者应该说是事件),我有两个侦听器:
- 用于实时分析的流分析任务
- 一个标准的工作者角色,根据接收到的事件计算一些内容,然后将它们存储到Azure SQL数据库中(这是一个lambda架构)
我目前正在使用EventProcessorHost库从我的工作角色内的事件中心检索我的事件。
我正在努力寻找一些关于如何使用事件中心的最佳实践(使用事件中心比使用服务总线队列有点困难,即流媒体与消息消费),我发现有些人说从我的事件中心检索EventData
事件后,我不应该做太多处理。
具体而言:
- http://blogs.msdn.com/b/servicebus/archive/2015/01/16/event-processor-host-best-practices-part-1.aspx
记住,无论你在做什么,你都想保持相对快速——也就是说,不要试图从这里进行许多流程——这就是为什么消费者群体支持。
- http://blogs.msdn.com/b/musings_on_alm_and_software_development_processes/archive/2014/09/03/azure-event-hubs-queues-and-workers.aspx
本文作者在事件中心和工人角色(从评论中不清楚是否真的需要是否)。
所以问题是:我应该直接在事件中心之后(即在我的IEventProcessor
实现的ProcessEventsAsnyc
方法内部)执行所有处理工作,还是应该在事件中心和处理工作之间使用队列?
任何关于如何正确使用事件中心事件的建议都将不胜感激,文档目前有点。。。丢失的
这属于一类问题,一旦EventProcessorHost的源代码可用,其答案将更加明显,我被告知这将发生。
简单的答案是,您不需要使用队列;然而,我会将ProcessEventsAsync返回Task所花费的时间保持得相对较短。
虽然这个建议听起来很像第一篇文章中的建议,但关键的区别在于,现在是返回Task的时间,而不是Task完成的时间。我的假设是,ProcessEventsAsync是在用于其他目的的EventProcessorHost的线程上调用的。在这种情况下,你需要迅速返回,以便其他工作可以继续;这项工作可能是为另一个分区调用ProcessEventsAsync(但如果没有调试,我们就不会知道——我觉得没有必要这样做,或者在可用时读取代码)。
我通过传递ProcessEventsAsync中的整个IEnumerable,在每个分区的一个单独线程上进行处理。这与从IEnumerable中取出所有项目并将它们放入队列以供处理线程使用形成对比。另一个线程在处理完消息后完成ProcessEventsAsync返回的Task。(实际上,我给我的处理线程提供了一个IEnumerable,它通过将块链接在一起并在调用MoveNext时完成任务来隐藏ProcessEventsAsync的详细信息)。
简而言之:在ProcessEventsAsync中,将工作移交给另一个线程,要么是你已经掌握的、知道如何与之通信的线程,要么与TPL启动一个新任务。
将所有消息放入ProcessEventsAsync内部的队列中并不是坏事它只是不是将事件块传递给另一个线程的最有效方法。
如果您决定将事件放入队列(或者在处理代码的下游有一个队列)并完成批处理任务,则应确保限制代码/队列中未完成的项目数量,以避免在EventHub为您提供项目的速度快于您的代码因为流量激增而处理项目的速度时内存不足。
Java EventHub用户注意事项2016-10-27:由于我注意到了这一点,有这样的描述描述了onEvents是如何被调用的,而onEvents速度慢并不是悲剧,因为它是在每个分区的线程上,它的速度会影响接收下一批的速度。因此,取决于您对延迟的关注程度,这里的延迟非常快对您的场景来说可能相对重要。