C# 事件中心消息分发
我们正在使用物联网中心接收设备数据。我们目前正在使用10个分区来处理消息。因此,运行5个worker将使每个实例处理2个分区 我们发现,如果一个设备连接并卸载500条消息到集线器,那么所有这些消息都将通过管道从一个上下文分区传输出去,即使其他的上下文分区没有做任何工作 利用路由/端点设计系统以实现此目的的唯一选项是什么 我们在低级别设备上使用MQTT,因此短期内不可能更改设备固件,但长期内可能更改 老实说,我认为它能提供最少的信息,即使是循环赛也会更好。我们很可能需要将消息送入队列并从那里处理它们,以实现更好的规模。目前正在创建多个线程来处理每个分区及其多个分区的每个C# 事件中心消息分发,c#,azureservicebus,azure-eventhub,azure-iot-hub,event-processor-host,C#,Azureservicebus,Azure Eventhub,Azure Iot Hub,Event Processor Host,我们正在使用物联网中心接收设备数据。我们目前正在使用10个分区来处理消息。因此,运行5个worker将使每个实例处理2个分区 我们发现,如果一个设备连接并卸载500条消息到集线器,那么所有这些消息都将通过管道从一个上下文分区传输出去,即使其他的上下文分区没有做任何工作 利用路由/端点设计系统以实现此目的的唯一选项是什么 我们在低级别设备上使用MQTT,因此短期内不可能更改设备固件,但长期内可能更改 老实说,我认为它能提供最少的信息,即使是循环赛也会更好。我们很可能需要将消息送入队列并从那里处理它
IEnumerable消息。然而,瓶颈仍将以某种形式存在,直到我们开始实施进一步的队列并在那里扩展
更新-添加一些示例代码,显示我在做什么
首先,通过多个任务处理每批消息,我们现在的性能提高了10倍。我将在我们的下一个版本中重构代码,但目前这一切都很好
async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
{
await ProcessEventsBulk(context, messages);
}
async Task ProcessEventsBulk(PartitionContext context, IEnumerable<EventData> messages)
{
List<Task> TaskList = new List<Task>();
foreach (EventData message in messages)
{
var LastTask = Task.Run(() => GoBoy(context, message));
TaskList.Add(LastTask);
}
await Task.WhenAll(TaskList);
}
async Task GoBoy(PartitionContext context, EventData message)
{
using (var db = new AppDbContext(_dbContextConnectionString))
{
await ProcessEvent(message, context.Lease.PartitionId, new CoreManagerContainer(db), db);
await db.SaveChangesAsync();
}
}
异步任务IEventProcessor.ProcessEventsAsync(分区上下文,IEnumerable消息)
{
等待ProcessEventsBulk(上下文、消息);
}
异步任务ProcessEventsBulk(PartitionContext上下文,IEnumerable消息)
{
List TaskList=新列表();
foreach(消息中的EventData消息)
{
var LastTask=Task.Run(()=>GoBoy(上下文,消息));
任务列表。添加(上一个任务);
}
等待任务。WhenAll(任务列表);
}
异步任务GoBoy(PartitionContext上下文,EventData消息)
{
使用(var db=new-AppDbContext(_-dbContextConnectionString))
{
等待ProcessEvent(消息,context.Lease.PartitionId,新的CoreManagerContainer(db),db);
等待db.saveChangesSync();
}
}
流程事件将执行以下操作:
- 解码包
- 通过NLOG登录到Azure表存储
- 更新SQL中的值(特别是设备表)
- 将消息插入DocumentDB
- 将消息转发到2个队列
- 对单位作出回应
我用一些早期代码创建了一个分支,在那里我在确认之前批量插入到DocDB中。虽然并没有看到大的改进,但应该对RUs Im假设有所帮助。在大多数情况下,将数据从同一设备发送到同一分区是有意义的:您可以按顺序处理数据,批处理通常更容易。500听起来不多。您能否分享处理过程的细节/所需时间以及绩效目标是什么?@Mikhail感谢您的回复。EVPH恰好从1个分区中提供相同的单元数据。从我的理解来看,事件中心无论如何都不能保证FIFO,所以如果不能保证FIFO,那么我做这种设计是毫无意义的?我刚开始在每批中使用线程,它已经好多了。我将在原始postEvents中发布更多详细信息给定分区中的事件按总顺序排列。所以,如果你按顺序发送它们,你将始终按照相同的顺序读取它们。@Mikhail Ah ok cool Think event hubs不能保证FIFO。很高兴知道。我用更多的果汁更新了我原来的帖子:)谢谢!在大多数情况下,将数据从同一设备发送到同一分区是有意义的:您可以按顺序处理它们,而批处理通常更容易。500听起来不多。您能否分享处理过程的细节/所需时间以及绩效目标是什么?@Mikhail感谢您的回复。EVPH恰好从1个分区中提供相同的单元数据。从我的理解来看,事件中心无论如何都不能保证FIFO,所以如果不能保证FIFO,那么我做这种设计是毫无意义的?我刚开始在每批中使用线程,它已经好多了。我将在原始postEvents中发布更多详细信息给定分区中的事件按总顺序排列。所以,如果你按顺序发送它们,你将始终按照相同的顺序读取它们。@Mikhail Ah ok cool Think event hubs不能保证FIFO。很高兴知道。我用更多的果汁更新了我原来的帖子:)谢谢!