Azure functions 具有事件中心触发器的Azure函数写入重复消息

Azure functions 具有事件中心触发器的Azure函数写入重复消息,azure-functions,azure-eventhub,azure-blob-storage,azure-eventhub-capture,Azure Functions,Azure Eventhub,Azure Blob Storage,Azure Eventhub Capture,我有一个带有事件中心触发器的Azure函数。此集线器接收来自设备的消息并将其存储在Blob中。最近,我注意到重复的消息存储在blob中。blob store中的文件是按上次修改日期排序的,如果您查看屏幕截图,就会发现情况并非如此。以前有人见过这个问题吗 我还有一个Azure函数,它正在写入cosmos DB,对于blob中的重复消息,cosmos中没有相应的重复消息 我还连接了时间序列洞察,它也没有任何重复的消息 我打开了事件中心捕获,那里也没有重复的消息 这是截图 第一列是事件中心排队时间的u

我有一个带有事件中心触发器的Azure函数。此集线器接收来自设备的消息并将其存储在Blob中。最近,我注意到重复的消息存储在blob中。blob store中的文件是按上次修改日期排序的,如果您查看屏幕截图,就会发现情况并非如此。以前有人见过这个问题吗

我还有一个Azure函数,它正在写入cosmos DB,对于blob中的重复消息,cosmos中没有相应的重复消息

我还连接了时间序列洞察,它也没有任何重复的消息

我打开了事件中心捕获,那里也没有重复的消息

这是截图

第一列是事件中心排队时间的unix时间戳。如果我没有与文件名关联的guid,它会引发异常。下面是一个将数据存储在blob中的片段

dynamic msg = JObject.Parse(myEventHubMessage);
string deviceId = msg.deviceId;
if (deviceId == "5Y.....")
{
           var filename = "_" + ((DateTimeOffset)enqueuedTimeUtc).ToUnixTimeSeconds() + "_" + Guid.NewGuid().ToString() + ".json";
        
           var containerName = "containerName/";
        
           var path = containerName + deviceId + "/" + filename;
        
           using (var writer = binder.Bind<TextWriter>(new BlobAttribute(path)))
           {
                writer.Write(myEventHubMessage);
           }
 }

这里的逻辑很简单。如果事件到达事件中心,则会触发该函数,并将数据存储在Azure Blob中。

一个重要的调用是事件中心具有;强烈建议确保您的处理能够以适合于您的应用程序场景的任何方式恢复事件重复

关于您在本例中看到的复制,Azure函数的绑定使用了,以便读取事件并触发函数代码的执行。随着Azure功能自动向上和向下扩展,EventProcessorHost的实例将加入并离开负责处理已配置事件中心的使用者组

当处理器启动时,它将尝试与同一用户组的其他活动处理器平衡处理工作。如果处理器无法通过声明无主分区来实现其公平的工作份额,它将试图从其他处理器窃取分区的所有权。在此期间,新所有者将开始读取上次记录的检查点。同时,旧所有者可能正在将上次读取的事件分派给处理程序进行处理;在尝试从事件中心服务读取下一组事件之前,它不会理解所有权已更改。当处理器关闭并放弃其分区所有权时,也会出现类似的模式


因此,当处理器启动或停止时,您将看到一些重复事件正在被处理,当处理器达到负载平衡的稳定状态时,这些重复事件将消失。该窗口的持续时间应该很短,但根据处理器的配置和所使用的检查点策略的不同而有所不同。

一个重要的调用是事件中心具有;强烈建议确保您的处理能够以适合于您的应用程序场景的任何方式恢复事件重复

关于您在本例中看到的复制,Azure函数的绑定使用了,以便读取事件并触发函数代码的执行。随着Azure功能自动向上和向下扩展,EventProcessorHost的实例将加入并离开负责处理已配置事件中心的使用者组

当处理器启动时,它将尝试与同一用户组的其他活动处理器平衡处理工作。如果处理器无法通过声明无主分区来实现其公平的工作份额,它将试图从其他处理器窃取分区的所有权。在此期间,新所有者将开始读取上次记录的检查点。同时,旧所有者可能正在将上次读取的事件分派给处理程序进行处理;在尝试从事件中心服务读取下一组事件之前,它不会理解所有权已更改。当处理器关闭并放弃其分区所有权时,也会出现类似的模式

因此,当处理器启动或停止时,您将看到一些重复事件正在被处理,当处理器达到负载平衡的稳定状态时,这些重复事件将消失。该窗口的持续时间应该很短,但根据处理器的配置和所使用的检查点策略而有所不同