• Event Hub On Azure


    Azure Event Hub 技术研究系列

     

    前两个系列研究了Azure IoT Hub和Azure Messaging。最近准备继续研究Azure Event Hub,即Azure的事件中心。首先,

    Azure Event Hub的官方介绍:

    1. Azure 事件中心是超大规模的遥测引入服务,可收集、传输和存储数以百万的事件

    2. 从网站、应用和任何数据流引入云端大规模的遥测数据,进行流式处理和分析

    可以看出,Azure Event Hub是一个数据的云端接入服务。我们上面的博客中讲到的Azure IoT Hub中的数据,发送到云端之后,也是使用的Azure Event Hub作为数据接入服务。

    那么,在实际的应用场景中,有哪几类可以借鉴应用的场景

    1. IoT设备遥测数据接入,例如,充电桩的遥测数据,接入到云端的Azure Event Hub中,接入后进行实时流式处理,数据分发等操作

    2. 分布式事件中心:将跨域、跨模块、跨服务中心的事件,统一发送到Azure Event Hub中,通过事件的订阅者,集中分发处理。

    3. 云端的ESB(私有云和公有云系统的集成打通),作为事件通道,Azure Messaging作为消息通道

    有其他的应用场景,欢迎大家继续补充,上面列出了我们这边可以用到的一些实际应用场景。

    Azure Event Hub的具体功能有哪些?

    1. 每秒对数百万事件进行流式处理
    Azure 事件中心是超大规模的遥测引入服务,可收集、传输和存储数以百万的事件。作为分布式流式处理平台,它为用户提供低延迟和可配置的时间保留,使用户可以将大量遥测数据引入到云中,并使用发布-订阅语义从多个应用程序中读取数据。

    2. 处理相同数据流中的实时和批处理
    使用事件中心存档功能,使单个流可以支持实时、基于批处理的管道,并降低解决方案的复杂性。在支持将来的实时分析和处理的平台上针对现在的批处理进行构建。事件中心存档是将数据加载到 Azure 最简单的方法。

    3. 利用完全托管的平台型服务
    事件中心是一种完全托管的服务,无需维护任何服务器,也无需获取任何软件许可证。定价简单且方便。事件中心可使用户专注于从遥测数据获取值,而非收集该数据。

    4. 处理容量、种类和速度
    大数据有很多来源,其负载分布也各不相同,例如每隔数分钟就会生成遥测数据的恒温器、每秒都会生成事件的应用程序性能计数器,以及每个客户操作时捕获捕获遥测数据的移动应用。事件中心是一种完全托管的服务,可以根据不同的负载分布以及负载高峰来采集规模具有弹性的事件。

    5. 通过多语言支持进行跨平台开发
    事件中心使用高级消息队列协议 (AMQP) 来实现跨平台的互操作性和二进制文件兼容性,同时还支持 HTTPS 实现数据引入。借助 Java 和 .NET 的本机客户端,可轻松开始使用事件中心,并且可以将其与流分析、Functions 和虚拟机等其他 Azure 服务集成。还有一个持续为 Apache NiFi 和 Elastic Stack 等热门平台创建新适配器和连接器的强大事件中心开源社区。

    Azure Event Hub的体系结构:

    Azure 事件中心是一种事件处理服务,用于提供云规模的事件与遥测引入,具有较低的延迟和较高的可靠性。 事件中心提供消息流处理功能,其特征不同于传统的企业消息传送。 事件中心功能围绕高吞吐量和事件处理方案而构建。 

    因此,事件中心未实现适用于消息传送实体(例如主题)的某些消息传送功能。

    事件中心在命名空间级别创建,使用 AMQP 和 HTTP 作为其主要的 API 接口。

    事件发布者:

    向事件中心发送数据的任何实体都称为“事件发布者”。 事件发布者可以使用 HTTPS 或 AMQP 1.0 发布事件。 事件发布者通过共享访问签名 (SAS) 令牌向事件中心表明其身份,可以使用唯一的标识,也可以使用通用的 SAS 令牌。

    事件发布:

    可以通过 AMQP 1.0 或 HTTPS 发布事件。 服务总线提供了一个 EventHubClient 类,使用该类可从 .NET 客户端向事件中心发送事件。 对于其他运行时和平台,你可以使用任何 AMQP 1.0 客户端,例如 Apache Qpid。 可以逐个或者批量发送事件。 单个发布(事件数据实例)限制为 256 KB,不管它是单个事件还是事件批。 发布大于此限制的事件将导致出错。 发布者最好是不知道事件中心内的分区数,而只是通过其 SAS 令牌指定“分区键”(如下一部分所述)或其标识。

     

    分区:

    事件中心通过分区使用者模式提供消息流式处理功能,在此模式下,每个使用者只读取消息流的特定子集或分区。 此模式支持事件处理的水平缩放,同时提供队列和主题中不可用的其他面向流的功能。
    分区是事件中心内保留的有序事件。 当较新的事件到达时,它们将添加到此序列的末尾。 可以将分区视为“提交日志”。

    事件中心按配置的保留时间保留数据,该时间适用于事件中心的所有分区。 事件根据特定的时间过期;无法显式删除事件。 由于分区互相独立且包含自身的数据序列,因此通常按不同速率增大。

    分区数在创建时指定,必须介于 2 到 32 之间。 分区计数不可更改,因此在设置分区计数时应考虑长期规模。 分区是一种数据组织机制,与使用方应用程序中所需的下游并行度相关。 

    分区中填充了一系列的事件数据,这些数据包含事件的正文、用户定义的属性包和元数据,例如,它在分区中的偏移量,以及它在流序列中的编号。 这一点和Kafka+ZooKeeper很像

    SAS 令牌

    事件中心使用在命名空间和事件中心级别提供的共享访问签名。 SAS 令牌是从 SAS 密钥生成的,它是以特定格式编码的 URL 的 SHA 哈希。 事件中心可以使用密钥(策略)的名称和令牌重新生成哈希,以便对发送者进行身份验证。 通常,为事件发布者创建的 SAS 令牌只对特定的事件中心具有发送权限。

    事件使用者

    从事件中心读取事件数据的任何实体称为“事件使用者”。 所有事件中心使用者通过 AMQP 1.0 会话进行连接,事件在可用时通过会话传送。 客户端不需要轮询数据可用性。

    事件使用者组

    事件中心的发布/订阅机制通过“使用者组”启用。 使用者组是整个事件中心的视图(状态、位置或偏移量)。 使用者组使多个消费应用程序都有各自独立的事件流视图,并按自身步调和偏移量独立读取流。

    在流处理体系结构中,每个下游应用程序相当于一个使用者组。 如果你要将事件数据写入长期存储,则该存储写入器应用程序就是一个使用者组。 然后即可由另一独立的使用者组执行复杂的事件处理。 你只能通过使用者组访问分区。 每个分区一次只能有一个活动的读取者来自给定的使用者组。 事件中心内始终有一个默认的使用者组,最多可为一个标准层事件中心创建 20 个使用者组。

    这个使用者组合Kafka Consumer中Group是类似的概念,但是从下面的图例看,Kafka的每个消费组 Group 都能同时消费同一Topic的消息,Azure Event Hub则不是,更多的是并行事件使用。

    流偏移量 

    “偏移量”是事件在分区中的位置。 可以将偏移量视为客户端游标。 偏移量是事件的字节编号。 有了该偏移量,事件使用者(读取者)便可以在事件流中指定要从其开始读取事件的点。 可以时间戳或者偏移量值的形式指定偏移量。 使用者负责在事件中心服务的外部存储其自身的偏移量值。 在分区中,每个事件都包含一个偏移量。

    事件的数据结构:

    • Offset
    • 序列号
    • 正文
    • 用户属性
    • 系统属性

    管理偏移量由用户负责。

    以上即是Azure Event Hub 的一些主要的概念、体系结构和术语说明,相信搞过Kafka的小伙伴可以很快就理解了。下一篇我们将继续Azure Event Hub 的编程研究。

    本篇文章中,我们继续深入研究,了解Azure Event Hub的创建、编程SDK,实现将事件发送到云端的Azure Event Hub。

    一、Azure Portal中创建Event Hub

    创建一个新的Event Hub:

    将连接字符串拷贝出来,备用。

    二、通过Event Hub的SDK将事件发送到Event Hub

    新建一个Console工程:EventHubSend

    添加Nuget:

    Microsoft.Azure.EventHubs

    添加关键引用:

    using Microsoft.Azure.EventHubs;
    using System.Text;
    using System.Threading.Tasks;

    添加常量作为事件中心连接字符串和实体路径(单个事件中心名称)

     private static EventHubClient eventHubClient;
    private const string EhConnectionString = "{Event Hubs connection string}";  //第一步拷贝的连接字符串
     private const string EhEntityPath = "{Event Hub path/name}"; //MyEventHub

    新加MainAsync函数

    复制代码
    private static async Task MainAsync(string[] args)
            {            
                var connectionStringBuilder = new EventHubsConnectionStringBuilder(EhConnectionString)
                {
                    EntityPath = EhEntityPath
                };
    
                eventHubClient = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString());
    
                await SendEvents(100);
    
                await eventHubClient.CloseAsync();
    
                Console.WriteLine("Press ENTER to exit.");
                Console.ReadLine();
            }
    复制代码

    将100个事件消息发送到EventHub方法:SendEvents

    复制代码
            /// <summary>
            /// 创建100个消息事件,异步发送到EventHub
            /// </summary>
            /// <param name="count">个数</param>
            /// <returns></returns>
            private static async Task SendEvents(int count)
            {
                for (var i = 0; i < count; i++)
                {
                    try
                    {
                        var eventEntity = $"Event {i}";
                        Console.WriteLine($"Sending Event: {eventEntity}");
                        await eventHubClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(eventEntity)));
                    }
                    catch (Exception exception)
                    {
                        Console.WriteLine($"{DateTime.Now} > Exception: {exception.Message}");
                    }
    
                    await Task.Delay(10);
                }
    
                Console.WriteLine($"{count} messages sent.");
            }
    复制代码

    在Main函数中添加:

    static void Main(string[] args)
    {
         MainAsync(args).GetAwaiter().GetResult();
    }

    Run:

     

    发现错误了:The messaging entity 'sb://myeventhubtest.servicebus.chinacloudapi.cn/MyEventHub' could not be found.

    MyEventHub这个是我们在代码中指定的。

    private const string EhEntityPath = "MyEventHub"; //MyEventHub

    这个是否需要在Azure Portal中提前创建好?

    再次Run:

    这次可以了。

    本篇文章中,我们继续:从Event Hub中接收事件。

    1. 新建控制台工程 EventHubReceiver

    2. 添加Nuget引用

    Microsoft.Azure.EventHubs

    Microsoft.Azure.EventHubs.Processor

    3. 实现IEventProcessor接口

    MyEventProcessor

    复制代码
     1     using Microsoft.Azure.EventHubs;
     2     using Microsoft.Azure.EventHubs.Processor;
     3     using System.Threading.Tasks;
     4 
     5     public class MyEventProcessor : IEventProcessor
     6     {
     7         public Task CloseAsync(PartitionContext context, CloseReason reason)
     8         {
     9             Console.WriteLine($"Processor Shutting Down. Partition '{context.PartitionId}', Reason: '{reason}'.");
    10             return Task.CompletedTask;
    11         }
    12 
    13         public Task OpenAsync(PartitionContext context)
    14         {
    15             Console.WriteLine($"MyEventProcessor initialized. Partition: '{context.PartitionId}'");
    16             return Task.CompletedTask;
    17         }
    18 
    19         public Task ProcessErrorAsync(PartitionContext context, Exception error)
    20         {
    21             Console.WriteLine($"Error on Partition: {context.PartitionId}, Error: {error.Message}");
    22             return Task.CompletedTask;
    23         }
    24 
    25         public Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
    26         {
    27             foreach (var eventData in messages)
    28             {
    29                 var data = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);
    30                 Console.WriteLine($"Event message received. Partition: '{context.PartitionId}', Data: '{data}'");
    31             }
    32 
    33             return context.CheckpointAsync();
    34         }
    35     }
    复制代码

    4. Program程序

    添加常量作为事件中心连接字符串、事件中心名称、存储帐户容器名称、存储帐户名称和存储帐户密钥。 添加以下代码,并将占位符替换为其对应的值。

    复制代码
            private const string EhConnectionString = "{Event Hubs connection string}";
            private const string EhEntityPath = "{Event Hub path/name}"; //MyEventHub
            private const string StorageContainerName = "{Storage account container name}"; //eventhubcontainer
            private const string StorageAccountName = "{Storage account name}"; //linux1
            private const string StorageAccountKey = "{Storage account key}";
    private static readonly string StorageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", StorageAccountName, StorageAccountKey);
    复制代码

    这里涉及到Azure Storage Account,必须为上篇博文中创建的事件中心MyEventHub指定一个存储账户和存储容器

    增加MainAysnc方法:注册事件处理器,处理事件消息

    复制代码
     1         /// <summary>
     2         /// 注册事件处理器
     3         /// </summary>
     4         /// <param name="args"></param>
     5         /// <returns></returns>
     6         private static async Task MainAsync(string[] args)
     7         {
     8             Console.WriteLine("Registering EventProcessor...");
     9 
    10             var eventProcessorHost = new EventProcessorHost(
    11                 EhEntityPath,
    12                 PartitionReceiver.DefaultConsumerGroupName,
    13                 EhConnectionString,
    14                 StorageConnectionString,
    15                 StorageContainerName);
    16 
    17             // Registers the Event Processor Host and starts receiving messages
    18             await eventProcessorHost.RegisterEventProcessorAsync<MyEventProcessor>();
    19 
    20             Console.WriteLine("Receiving. Press ENTER to stop worker.");
    21             Console.ReadLine();
    22 
    23             // Disposes of the Event Processor Host
    24             await eventProcessorHost.UnregisterEventProcessorAsync();
    25         }
    复制代码

    Main函数

    1         static void Main(string[] args)
    2         {
    3             MainAsync(args).GetAwaiter().GetResult();
    4         }

    Run

    至此,我们实现了事件消息发送到Event Hub,同时从Event Hub接收处理事件消息。

  • 相关阅读:
    HTML表单
    CSS等高布局的6种方式
    HTML用户反馈表单
    HTML美化修饰<A>
    sql查询语句 --------一个表中的字段对应另外一个表中的两个字段的查询语句
    jq 表格添加删除行
    js 静止f1到f12 和屏蔽鼠标右键
    手机自适应页面的meta标签
    tp3.2 的验证码的使用
    php多线程抓取网页
  • 原文地址:https://www.cnblogs.com/lingdanglfw/p/13985525.html
Copyright © 2020-2023  润新知