首页 > 解决方案 > 从 ASP .NET 应用程序批处理到事件中心

问题描述

我有一组网站(异步)将事件分析发送到 ASP.NET 网站,然后应该将事件发送到 Azure EventHubs 实例。

我面临的挑战是,当请求超过每秒 50,000 个时,我注意到我为这些请求提供服务的响应时间在数秒范围内,从而影响了初始发送网站的总加载时间。我已经扩展了所有部分,但是我认识到,由于打开与事件中心的 AMQP 连接并发送有效负载的开销,每个请求发送一个事件效率不高。

作为一种解决方案,我一直在尝试对发送到我的 EventHubs 实例的事件数据进行批处理,但是我在同步方面遇到了一些问题。对于每个请求,我将事件数据添加到EventDataBatch通过EventHubClient.CreateBatch()with创建的静态数据中,eventHubData.TryAdd() 然后检查事件的数量是否在预定义的阈值内,如果是,我通过异步发送事件EventHubClient.SendAsync()。这带来的挑战是,由于这是一个 ASP .NET 应用程序,因此可能有许多线程试图在任何给定实例上为请求提供服务——其中任何一个都可能试图在同一时间点eventHubData.TryAdd()EventHubClient.SendAsync()在同一时间点。作为一个糟糕的尝试为了解决这个问题,我试图在lock(batch)之前打电话eventHubData.TryAdd()但是,这并不能解决问题,因为我也不能锁定异步方法EventHubClient.SendAsync()

实现此解决方案的最佳方法是什么,以便每个请求不需要它自己对事件中心的请求,并且可以利用批处理,同时还保持批处理本身的完整性并且不会遇到任何死锁问题?

标签: c#asp.netazureconcurrencyazure-eventhub

解决方案


Have a look at the source code for the application insights SDK to see how they have solved this problem - you can reuse the key parts of this to achieve the same thing with event hubs AMQP.

The pattern is ,

1) Buffer data. Define a buffer that you will share among threads with a maximum size. Multiple threads write data into the buffer

https://github.com/Microsoft/ApplicationInsights-dotnet/blob/develop/src/Microsoft.ApplicationInsights/Channel/TelemetryBuffer.cs

2) Prepare a transmission. You can transmit the items in the buffer either when the buffer is full, when some interval elapses, or whichever happens first. Take all the items from the buffer to send

https://github.com/Microsoft/ApplicationInsights-dotnet/blob/develop/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs

3) Do the transmission. Send all items as multiple data points in a single Event Hub message,

https://github.com/Microsoft/ApplicationInsights-dotnet/blob/develop/src/Microsoft.ApplicationInsights/Channel/Transmission.cs

They are the 3 classes that combine to achieve this using HTTP to post to the Application Insights collection endpoint - you can see how the sample pattern can be applied to collect, amalgamate and transmit to Event Hubs.

You'll need to control the maximum message size, which is 256KB per Event Hub message, which you could do by setting the telemetry buffer size - that's up to your client logic to manage that.


推荐阅读