【问题标题】:ingesting in azure eventhub fails every morning每天早上在 azure eventthub 中摄取失败
【发布时间】:2017-09-08 20:58:35
【问题描述】:

每天清晨向 eventthub 发送事件都会失败,并显示以下消息。我已经掩盖了这个数字,因为我不确定那个数字是什么以及出于安全原因。(下面的代码和错误)

  1. 我始终每分钟发送约 240 个非常小的事件,所以这应该不是问题。
  2. 我的 eventthub 有 2 个分区和 2 个使用者 如果你们中的任何人知道解决方案或需要更多信息,请告诉我。 谢谢!

错误: 消息:与“XXXXX06f186e4bb89aea2d8959bXXXXX_GXX”通信时发生错误。检查连接信息,然后重试。

StackTrace:在 Microsoft.ServiceBus.Common.AsyncResult.End[TAsyncResult](IAsyncResult 结果) 在 Microsoft.ServiceBus.Common.AsyncResult1.End(IAsyncResult asyncResult) 在 Microsoft.ServiceBus.Messaging.Amqp.FaultTolerantObject1.OnEndCreateInstance(IAsyncResult asyncResult) 在 Microsoft.ServiceBus.Messaging.SingletonManager1.EndGetInstance(IAsyncResult asyncResult) 在 Microsoft.ServiceBus.Messaging.AmqpMessageSender.OnEndOpen(IAsyncResult 结果) 在 Microsoft.ServiceBus.Messaging.ClientEntity.EndOpen(IAsyncResult 结果) 在 Microsoft.ServiceBus.Messaging .OpenOnceManager.OnEndCreateInstance(IAsyncResult asyncResult) 在 Microsoft.ServiceBus.Messaging.SingletonManager1.EndGetInstance(IAsyncResult asyncResult) 在 Microsoft.ServiceBus.Messaging.OpenOnceManager.OpenOnceManagerAsyncResult1.OpenComplete(IAsyncResult 结果) 在 Microsoft.ServiceBus.Common.AsyncResult.SyncContinue(IAsyncResult 结果) 在 Microsoft.ServiceBus.Messaging.OpenOnceManager.OpenOnceManagerAsyncResult1..ctor(OpenOnceManager openOnceManager, TimeSpan openTimeout, AsyncCallback 回调,对象状态,Func3 beginOperation,EndOperation1 endOperation) 在 Microsoft.ServiceBus.Messaging.OpenOnceManager.Begin(AsyncCallback 回调,对象状态,Func3 beginOperation,Action1 endOperation) 在 Microsoft.ServiceBus.Messaging.EventHubSender 的 Microsoft.ServiceBus.Messaging.MessageSender.BeginSendEventData(TrackingContext trackingContext,IEnumerable1 eventDatas,TimeSpan 超时,AsyncCallback 回调,对象状态)。c__DisplayClass23_0.b__0(AsyncCallback c,Object s)在系统。 Threading.Tasks.TaskFactory1.FromAsyncImpl(Func3 beginMethod, Func2 endFunction, Action1 endAction, Object state, TaskCreationOptions creationOptions) 在 Microsoft.ServiceBus.Common.Parallel.TaskHelpers.CreateTask(Func3 begin, Action`1 end, Object state) --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.GetResult() 日期:2017 年 4 月 12 日凌晨 2:48:17

代码: EventHubClient deveventHubClient = EventHubClient.CreateFromConnectionString(connectionString, "EventHubName");

private async Task SendInBatch(IList<byte[]> source, Guid UUID)
{
List events = new List(source.Select(b => new EventData(b)));

    EventHubSender Partition0;
    EventHubSender Partition1;
    Partition0 = deveventHubClient.CreatePartitionedSender("0");
    Partition1 = deveventHubClient.CreatePartitionedSender("1");
    if (UUID.GetHashCode() % 2 == 0)
    {
        await Partition0.SendBatchAsync(events);
    }
    else
    {
        await Partition1.SendBatchAsync(events);
    }
    return Unit.Default;
}

【问题讨论】:

  • 每天早上都会出现这个问题吗?您是否尝试使用另一个事件中心来测试是否出现相同的问题?
  • 我尝试了 2 个 eventthub,其中 1 个在凌晨 2:40 失败,另一个在凌晨 4:30 失败。这种情况每天都在发生。

标签: c# .net azure azure-eventhub


【解决方案1】:

简短的 ANS

您在发送时可能遇到暂时性错误。如果您想要绝对高可用性的代码 - 考虑将您的代码更改为 EventHubClient.sendBatchAsync(...) 而不是使用 PartitionedSender.sendBatchAsync(...) 并在您的代码中摆脱 % 2 逻辑。

为什么

想象一下 - EventHubs 作为 Events 在云/天蓝色上的流。

在分布式环境中 - 尽管概率很低 - 故障肯定会一直发生 - 例如:托管您的 EventHubs 的 VM 可能会重新启动,其中一个 n/w 网关可能会失败并且连接可能会重置,托管您的代码的容器可能体验高负载和我们的负载平衡算法。可能会移动它等等,

当故障发生时,我们希望我们的客户能够在不察觉故障的情况下发送到 EventHubs。因此,换句话说,为了向我们的客户提供高可用性,我们公开了partitions 的概念。

当您使用 EventHubClient.sendBatchAsync(...) 发送时 - 我们的 网关 将检测哪个 eventthub 分区立即可用并将事件路由到该特定事件中心分区 - 如果多个分区可用 - 它会四舍五入-robin(例如:就像你使用 %2 所做的那样)。

简单地说,不。 EventHubs的分区数决定了EventHubs的高可用程度。因此,如果您对连接失败很敏感 - 请考虑放弃创建 PartitionedSender 并使用 EventHubClient 直接将事件发送到 EventHub。

【讨论】:

  • 这是有道理的,但我有一个要求,在从 eventthub 读取时,我需要对来自 1 个 UUID 的一分钟数据进行平均。如果我使用 EventHubClient 而不是特定分区来发送数据UUID,我每分钟得到 2 个平均值(每个来自我的 2 个分区)而不是 1 个。为了避免这种情况,我仅使用 %2 逻辑通过 1 个分区发送了 1 个 UUID 的数据。
  • 要从 eventthub 中读取,我使用的是 IEventProcessor,在 OpenAsync 方法中,我平均如下:stream.GroupBy(item => item.PartitionKey).Subscribe(group => group .Buffer(TimeSpan.FromMinutes (1)).Subscribe(buffer => { aggregation.Aggregate(buffer);
  • 一旦你得到了 2 个值 - 如何获得平均值。那个平均值?一般来说,如果您对发送错误和延迟敏感,我不建议您发送到特定分区。行之有效的方法是尽可能快地发送 - 并处理下游(聚合)问题。
  • 你建议如何取这两个值的平均值?因为从 IEventProcessor 实现的整个类运行两次(每个分区一次)
  • 我没有关于您在此处尝试解决的问题的端到端上下文。因为,您的问题是关于 - 发送可靠性 - 我试图建议如何实现这一点.. Idea1:对于下游 EventProcessorImpl - 创建 AverageCalculator 的 Singleton 实例并在 EventProcessorImpl.onProcessEvents 中调用此类。在 AverageCalculator 类中处理聚合平均值。 Idea2:从您的流中发出带有时间戳的中间事件并加入 Partition1 和 Partition2 的两个流
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多