C# 理解eventhub中的检查点
我想确保,如果我的eventhub客户端崩溃(目前是一个控制台应用程序),它只会拾取尚未从eventhub获取的事件。实现这一点的一种方法是利用偏移量。但是,这(据我所知)要求客户机存储最新的偏移量(此外,事件似乎不一定会命中按SequenceNumber排序的ProcessEventsSync方法的foreach循环) 另一种方法是使用检查点。我认为它们是使用提供的存储帐户凭据通过服务器(eventhub)持久化的。这是正确的吗 这是我目前使用的一些初步代码:C# 理解eventhub中的检查点,c#,azureservicebus,azure-eventhub,C#,Azureservicebus,Azure Eventhub,我想确保,如果我的eventhub客户端崩溃(目前是一个控制台应用程序),它只会拾取尚未从eventhub获取的事件。实现这一点的一种方法是利用偏移量。但是,这(据我所知)要求客户机存储最新的偏移量(此外,事件似乎不一定会命中按SequenceNumber排序的ProcessEventsSync方法的foreach循环) 另一种方法是使用检查点。我认为它们是使用提供的存储帐户凭据通过服务器(eventhub)持久化的。这是正确的吗 这是我目前使用的一些初步代码: public class Sim
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分钟窗口中重新执行事件。 这是一种健康的模式:
- 每次EventProcessorImpl启动时,向下游查询最后一个序列号。它会一直丢弃事件,直到当前序列号
感谢您的冗长回复。是检查点被持久化为“服务器端/云中”。即在链接到eventhub的azure存储帐户中。这与必须在客户端持久化的偏移量形成对比。您能否提供更多的“事务性代码”,以确保事件以正确的顺序传递到目标事件接收器?谢谢谢谢“链接到eventhub的存储帐户”是什么意思?没有这样的事。您提供给EventProcessorHost的存储帐户纯粹是客户端。正如我所说,API context.CheckpointAsync()直接调用Azure存储并检查当前偏移量。我猜你是写信给