plu*_*ich 22 c# azure azureservicebus azure-eventhub
我正在使用EventProcessorHost和一个IEventProcessor类(调用它:MyEventProcessor)从EventHub接收事件.我通过在两台服务器上运行我的EPH,并使用相同的ConsumerGroup连接到Hub,但使用唯一的hostName(使用机器名称)将其扩展到两台服务器.
问题是:在白天/黑夜的随机时间,应用程序记录:
Exception information:
Exception type: ReceiverDisconnectedException
Exception message: New receiver with higher epoch of '186' is created hence current receiver with epoch '186' is getting disconnected. If you are recreating the receiver, make sure a higher epoch is used.
at Microsoft.ServiceBus.Common.ExceptionDispatcher.Throw(Exception exception)
at Microsoft.ServiceBus.Common.Parallel.TaskHelpers.EndAsyncResult(IAsyncResult asyncResult)
at Microsoft.ServiceBus.Messaging.IteratorAsyncResult`1.StepCallback(IAsyncResult result)
Run Code Online (Sandbox Code Playgroud)
此异常与LeaseLostException同时发生,当它尝试检查点时,从MyEventProcessor的CloseAsync方法抛出.(由于ReceiverDisconnectedException,可能正在调用Close?)
我认为这是由于Event Hubs在扩展到多台机器时的自动租赁管理而发生的.但我想知道我是否需要做一些不同的事情以使其更干净地工作并避免这些例外?例如:有时代的东西?
Sre*_*ati 44
TLDR:这种行为绝对正常.
为什么租赁管理不能平稳无异常:为开发人员提供更多控制.
在很长的故事-从基础全部的路
EventProcessorhost(现EPH-是非常相似,__consumer_offset topic为做Kafka Consumers-分区所有权和检查站店)被写入Microsoft Azure EventHubs队自己-所有的翻译EventHubs partition receiver Gu成一个简单的onReceive(Events)回调.
EPH用于解决2个一般的,主要的,众所周知的问题,同时读取高吞吐量的分区流,如EventHubs:
容错接收管道 - 例如:问题的简单版本 - 如果主机运行PartitionReceiver并且返回 - 它需要从它离开的地方继续处理.要记住最后一次成功处理EventData,请EPH使用blob提供的EPH构造函数来存储检查点 - 用户何时调用context.CheckpointAsync().最终,当主机进程终止时(例如:突然重新启动或命中硬件故障并且永远不会/恢复) - 任何EPH实例都可以接收此任务并从中恢复Checkpoint.
跨EPH实例平衡/分配分区 - 假设,如果有10个分区和2个EPH实例处理来自这10个分区的事件 - 我们需要一种方法来跨实例划分分区(库的PartitionManager组件就是EPH这样做).我们Azure Storage - Blob LeaseManagement-feature 用来实现这个.从版本开始2.2.10- 为了简化问题,EPH假设所有分区均匀加载.
有了这个,让我们试着看看发生了什么:首先,在上面的10事件中心分区示例和2 EPH实例中处理事件:
EPH实例 - EPH1启动,首先,单独启动,启动的一部分,它为所有10个分区创建接收器并处理事件.在启动时 - EPH1将10通过获取10代表这些10事件中心分区的存储blob 上的租约(使用标准nomenclature- 在EPH内部创建存储帐户 - 从StorageConnectionString传递到ctor)来宣布它拥有所有这些分区.租约将在规定的时间内获得,之后EPH实例将失去该分区的所有权.EPH1不时地announces- 它仍然拥有这些分区 - 通过renewingblob上的租约.renewal可以使用以下方式执行频率以及其他有用的调整PartitionManagerOptionsEPH2启动-与您提供的相同AzureStorageAccount的EPH1到ctor的EPH2为好.现在,它有0分区要处理.那么,要实现跨分区的平衡EPH情况下,它会继续和download所有的列表leaseblobs具有映射owner到partitionId.从这一点来看,它将STEAL以其公平份额出租partitions - 5在我们的例子中,并将公布该信息lease blob.作为其中的一部分,EPH2读取PartitionX它写的最新检查点想要窃取租约并继续并创建相应PartitionReceiver的与s中的EPOCH相同Checkpoint. EPH1将失去这些5的所有权,partitions并将根据其所处的确切状态遇到不同的错误.
EPH1实际上正在调用该PartitionReceiver.Receive()调用 - 同时在同一个接收器上EPH2创建PartitionReceiver- EPH1将遇到ReceiverDisconnectedException.这最终会调用IEventProcessor.Close(CloseReason=LeaseLost).请注意,如果接收的消息较大或PrefetchCount较小,则触发此特定异常的概率较高- 因为在这两种情况下接收器将执行更积极的I/O.EPH1是在状态checkpointing的lease或renewing在lease,而EPH2 stole租约,该EventProcessorOptions.ExceptionReceived事件处理程序将与一个信号leaselostException(与409在冲突错误leaseblob) -这也最终调用IEventProcess.Close(LeaseLost).为什么租赁管理不能顺利和免除:
为了使消费者保持简单和无差错,租赁管理相关的异常可能已被吞并,EPH并且根本没有通知用户代码.然而,我们意识到,投掷LeaseLostException可以使客户能够在IEventProcessor.ProcessEvents()回调中发现有趣的错误- 症状将是 - 频繁的分区移动
EPH1未能renew租用而重新启动!-与想象如果N/W这台机器的代表片状一天- EPH实例要玩ping-pong有Partitions!这台机器将不断尝试从其他机器窃取租约 - 从EPH观点来看这是合法的- 但是,对于用户而言,EPH这是完全干扰处理管道的完全灾难.EPH- ReceiverDisconnectedException当n/w重新回到这个片状m/c时,会看到一个!我们认为最好也是事实上唯一的方法是让开发人员闻到这一点!ProcessEvents逻辑中有一个错误- 它会抛出未处理的异常,这些异常是致命的并且会导致整个过程 - 例如:毒害事件.这个分区将会移动很多.EPH也是错误的(如自动清理脚本)等.outageAzure DC上的5分钟特定EventHub.Partition位置 - 比如n/w事件.分区将跨越EPH实例移动.基本上,在大多数情况下,对我们来说检测差异会很棘手.在这些情况和合法租约之间由于平衡导致丢失,我们希望将这些情况的控制权委托给开发人员.
| 归档时间: |
|
| 查看次数: |
6246 次 |
| 最近记录: |