Asp.NetCore能录应对物联网的潮汐大流量我们使用以Azure App Service形式部署,依赖Azure App Service的自动缩放

通常推荐批量发送到事件中心,能有效增加web服务的吞吐量和响应能力。
目前新版SDk: Azure.Messaging.EventHubs仅支持分批发送。

  1. nuget上引入Azure.Messaging.EventHubs库
  2. EventHubProducerClient客户端负责分批发送数据到事件中心,根据发送时指定的选项,事件数据可能会自动路由到可用分区或发送到特定请求的分区。

在以下情况下,建议允许自动路由分区:
1) 事件的发送必须高度可用
2) 事件数据应在所有可用分区之间平均分配。
自动路由分区的规则:
1)使用循环法将事件平均分配到所有可用分区中
2)如果某个分区不可用,事件中心将自动检测到该分区并将消息转发到另一个可用分区。

我们要注意,根据选定的 命令空间定价层, 每批次发给事件中心的最大消息大小也不一样:

分段批量发送策略

这里我们就需要思考: web程序收集数据是以个数为单位; 但是我们分批发送时要根据分批的字节大小来切分。
我的方案是: 因引入TPL Dataflow 管道:

  1. web程序收到数据,立刻丢入TransformBlock
  2. 转换到EventData之后,使用BatchBlock按照个数打包
  3. 利用ActionBlock在包内 累积指定字节大小批量发送
  • 最后我们设置一个定时器(5min),强制在BatchBlock的前置队列未满时打包,并发送。

核心的TPL Dataflow代码如下:

public class MsgBatchSender
    {
        private readonly EventHubProducerClient Client; private readonly TransformBlock<string, EventData> _transformBlock; private readonly BatchBlock _packer; private readonly ActionBlock _batchSender; private readonly DataflowOption _dataflowOption; private readonly Timer _trigger; private readonly ILogger _logger; public MsgBatchSender(EventHubProducerClient client, IOptions option,ILoggerFactory loggerFactory) { Client = client; _dataflowOption = option.Value; var dfLinkoption = new DataflowLinkOptions { PropagateCompletion = true }; _transformBlock = new TransformBlock<string, EventData>( text => new EventData(Encoding.UTF8.GetBytes(text)), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = _dataflowOption.MaxDegreeOfParallelism }); _packer = new BatchBlock(_dataflowOption.BatchSize); _batchSender = new ActionBlock(msgs=> BatchSendAsync(msgs)); _packer.LinkTo(_batchSender, dfLinkoption); _transformBlock.LinkTo(_packer, dfLinkoption, x => x != null); _trigger = new Timer(_ => _packer.TriggerBatch(), null, TimeSpan.Zero, TimeSpan.FromSeconds(_dataflowOption.TriggerInterval)); _logger = loggerFactory.CreateLogger(); } private async Task BatchSendAsync(EventData[] msgs) { try { if (msgs != null) { var i = 0; while (i < msgs.Length) { var batch = await Client.CreateBatchAsync(); while (i < msgs.Length) { if (batch.TryAdd(msgs[i++]) == false) { break; } } if(batch!= null && batch.Count>0) { await Client.SendAsync(batch); batch.Dispose(); } } } } catch (Exception ex) { // ignore and log any exception _logger.LogError(ex, "SendEventsAsync: {error}", ex.Message); } } public async Task<bool> PostMsgsync(string txt) { return await _transformBlock.SendAsync(txt); } public async Task CompleteAsync() { _transformBlock.Complete(); await _transformBlock.Completion; await _batchSender.Completion; await _batchSender.Completion; } }

 

你可能感兴趣的:(Asp.NetCore能录应对物联网的潮汐大流量我们使用以Azure App Service形式部署,依赖Azure App Service的自动缩放)