将事件从Azure事件中心管道传输到Azure服务总线

时间:2020-05-30 18:21:10

标签: azure azureservicebus azure-eventhub distributed-system

我正在收听事件中心的各种事件。

  1. 每个事件都是高价值的,不能错过。
  2. 事件根据设备ID进行分区。
  3. 来自一个设备ID的事件是稀疏的,并且不是很频繁(每几dasy发生几个事件)。它仅响应于很少的用户操作而发生。
  4. 设备数量众多,因此我将针对各种设备ID举办很多活动。

对于每个事件,我需要对不是非常可靠的系统进行3-4个API调用。而且由于其中一些是跨地理电话,因此可能需要一些时间。

我打算从事件中心接收事件,并将其放入Service Bus。我的原因如下。

  1. 事件中心只能扩展到32个分区,如果一个事件花费时间,整个分区将被阻塞。
  2. 另一方面,
  3. 服务总线具有更高的水平可扩展性。如果吞吐量下降,我可以将更多订户添加到服务总线。

我一直在寻找这样的模式,但是我没有看到从基于日志的消息传递系统中获取数据并将其推送到基于队列的模式的模式。

是否有更好的方法来处理这种情况?

2 个答案:

答案 0 :(得分:0)

我认为您可以使用事件中心触发器和服务总线输出绑定来实现所需的功能。

例如,我要监视事件中心“测试”,而我正在使用C#库:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.EventHubs;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace FunctionApp68
{
    public static class Function1
    {
        [FunctionName("Function1")]
        [return: ServiceBus("test1", Connection = "ServiceBusConnection")]
        public static string Run([EventHubTrigger("test", Connection = "str")] EventData[] events, ILogger log)
        {
            var exceptions = new List<Exception>();
            string messageBodyt = "";
            foreach (EventData eventData in events)
            {
                try
                {
                    string messageBody = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
                    messageBodyt = messageBodyt + messageBody;
                    // Replace these two lines with your processing logic.
                    log.LogInformation($"C# Event Hub trigger function processed a message: {messageBody}");
                    //await Task.Yield();
                }
                catch (Exception e)
                {
                    // We need to keep processing the rest of the batch - capture this exception and continue.
                    // Also, consider capturing details of the message that failed processing so it can be processed again later.
                    exceptions.Add(e);
                }
            }

            // Once processing of the batch is complete, if any messages in the batch failed processing throw an exception so that there is a record of the failure.

            if (exceptions.Count > 1)
                throw new AggregateException(exceptions);

            if (exceptions.Count == 1)
                throw exceptions.Single();
            return messageBodyt;
        }
    }
}

上面的代码将从事件中心“ test”收集并保存到服务总线队列“ test1”。

看看这些文档:

https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-hubs-trigger?tabs=csharp

https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus-output?tabs=csharp#example

答案 1 :(得分:0)

实际上,您需要的是每个设备ID的专用队列。一旦事件到达事件中心,就从事件中心中提取事件,并将其放入设备ID的专用队列中,然后对其进行串行处理。

如何为每个设备ID建立队列:

  1. 建立队列的简单方法是使用SQL数据库(大多数情况下,如果每秒的请求不是很高,则正常工作,因为sql-db 100 req / second正常。)
  2. 另一种水平可伸缩的方法是使用azure附加blob(如果事件处理器是无状态的)。
  3. 您还可以使用高级方法,例如使用Azure Service Fabric可靠队列。