Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 理解eventhub中的检查点_C#_Azureservicebus_Azure Eventhub - Fatal编程技术网

C# 理解eventhub中的检查点

C# 理解eventhub中的检查点,c#,azureservicebus,azure-eventhub,C#,Azureservicebus,Azure Eventhub,我想确保,如果我的eventhub客户端崩溃(目前是一个控制台应用程序),它只会拾取尚未从eventhub获取的事件。实现这一点的一种方法是利用偏移量。但是,这(据我所知)要求客户机存储最新的偏移量(此外,事件似乎不一定会命中按SequenceNumber排序的ProcessEventsSync方法的foreach循环) 另一种方法是使用检查点。我认为它们是使用提供的存储帐户凭据通过服务器(eventhub)持久化的。这是正确的吗 这是我目前使用的一些初步代码: public class Sim

我想确保,如果我的eventhub客户端崩溃(目前是一个控制台应用程序),它只会拾取尚未从eventhub获取的事件。实现这一点的一种方法是利用偏移量。但是,这(据我所知)要求客户机存储最新的偏移量(此外,事件似乎不一定会命中按SequenceNumber排序的ProcessEventsSync方法的foreach循环)

另一种方法是使用检查点。我认为它们是使用提供的存储帐户凭据通过服务器(eventhub)持久化的。这是正确的吗

这是我目前使用的一些初步代码:

public class SimpleEventProcessor : IEventProcessor
{
    private Stopwatch _checkpointStopWatch;

    async Task IEventProcessor.CloseAsync(PartitionContext context, CloseReason reason)
    {
        Console.WriteLine("Processor Shutting Down. Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason);
        if (reason == CloseReason.Shutdown)
        {
            await context.CheckpointAsync();
        }
    }

    Task IEventProcessor.OpenAsync(PartitionContext context)
    {
        Console.WriteLine("SimpleEventProcessor initialized.  Partition: '{0}', Offset: '{1}'", context.Lease.PartitionId, context.Lease.Offset);
        _checkpointStopWatch = new Stopwatch();
        _checkpointStopWatch.Start();
        return Task.FromResult<object>(null);
    }

    async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
    {
        foreach (var eventData in messages)
        {
            // do something                    
        }

        //Call checkpoint every 5 minutes, so that worker can resume processing from 5 minutes back if it restarts.
        if (_checkpointStopWatch.Elapsed > TimeSpan.FromMinutes(5))
        {
            await context.CheckpointAsync();
            _checkpointStopWatch.Restart();
        }
    }
}
公共类SimpleEventProcessor:IEventProcessor
{
私人秒表(秒表);;
异步任务IEventProcessor.CloseAsync(PartitionContext上下文,CloseReason)
{
WriteLine(“处理器正在关闭。分区“{0}”,原因:“{1}.”,context.Lease.PartitionId,原因);
如果(原因==CloseReason.Shutdown)
{
wait context.CheckpointAsync();
}
}
任务IEventProcessor.OpenAsync(分区上下文)
{
WriteLine(“SimpleEventProcessor已初始化。分区:'{0}',偏移量:'{1}',context.Lease.PartitionId,context.Lease.Offset);
_checkpointStopWatch=新秒表();
_checkpointStopWatch.Start();
返回Task.FromResult(空);
}
异步任务IEventProcessor.ProcessEventsAsync(PartitionContext上下文,IEnumerable消息)
{
foreach(消息中的var eventData)
{
//做点什么
}
//每5分钟调用一次检查点,以便工作进程在重新启动时可以从5分钟后恢复处理。
如果(_checkpointStopWatch.appeased>TimeSpan.FromMinutes(5))
{
wait context.CheckpointAsync();
_checkpointStopWatch.Restart();
}
}
}
我相信它每5分钟向服务器发送一个检查点。服务器如何知道哪个客户端(通过上下文)提交了检查点?此外,如果客户端重新启动,如何防止事件再次处理?此外,仍然可能有一个长达5分钟的窗口,在此窗口中事件将再次处理。考虑到我的需求,也许我更应该使用队列/主题

附言:

这似乎足够了:

async Task IEventProcessor.ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> messages)
{
    foreach (var eventData in messages)
    {
        // do something
    }
    await context.CheckpointAsync();
}
异步任务IEventProcessor.ProcessEventsAsync(分区上下文,IEnumerable消息) { foreach(消息中的var eventData) { //做点什么 } wait context.CheckpointAsync(); }
在回答之前,莱姆提出了几个基本术语: EventHubs是一种高吞吐量、持久的事件摄取管道。简单地说,这是一个可靠的云端事件流。 EventData(流中的一个事件)上的偏移量实际上是流上的光标。拥有此游标-将启用诸如-从此游标重新启动读取(也称为偏移量)-包含或排除之类的操作。 是EventHubs团队在ServiceBus SDK之上构建的一个框架,使“eventhub接收器”看起来更简单活动中心卡夫卡EPH的ZooKeeper。它将确保在特定分区上运行EventProcessor的进程死机/崩溃时,它将从其他可用的EventProcessorHost实例中的最后一个检查点偏移量恢复。 检查点:从今天起-EventHubs仅支持客户端检查点。从客户端代码调用检查点时:

await context.CheckpointAsync();
-它将转换为一个存储调用(直接来自客户机)——该调用将在您提供的存储帐户中存储当前偏移量。EventHubs服务将不与存储对话以进行检查点

答案 EventProcessor框架旨在实现您想要的目标。

检查点不会通过服务器持久化(也称为EVENTHUBS服务)。它完全是客户端的。您正在与Azure存储对话。这就是EventProcessor库引入新的附加依赖项的原因。您可以连接到存储帐户&检查点写入的容器-我们维护所有权信息-EPH实例(名称)到它们拥有的EventHub分区,以及它们当前读取/处理的检查点。 按照基于计时器的检查点模式——您最初拥有的模式——如果进程停止,您将在最后5分钟窗口中重新执行事件。 这是一种健康的模式:

  • 基本假设是,故障是罕见的事件,所以 将很少处理重复事件
  • 你最终会赚得更少 调用存储服务(您很容易被 经常检查指针)。我会更进一步 实际上,将异步触发检查点调用。OnProcessEvents 如果检查点失败,则不需要失败 如果您完全不想重复任何事件,则需要在下游管道中构建此重复数据消除逻辑

    • 每次EventProcessorImpl启动时,向下游查询最后一个序列号。它会一直丢弃事件,直到当前序列号

    感谢您的冗长回复。是检查点被持久化为“服务器端/云中”。即在链接到eventhub的azure存储帐户中。这与必须在客户端持久化的偏移量形成对比。您能否提供更多的“事务性代码”,以确保事件以正确的顺序传递到目标事件接收器?谢谢谢谢“链接到eventhub的存储帐户”是什么意思?没有这样的事。您提供给EventProcessorHost的存储帐户纯粹是客户端。正如我所说,API context.CheckpointAsync()直接调用Azure存储并检查当前偏移量。我猜你是写信给