Azure Functions事件网格触发器

3

我已经实施了一个EventGrid触发器来响应Blob Storage事件,其逻辑如下所示:

public static async void Run(
    JObject eventGridEvent,
    TraceWriter log,
    ExecutionContext context)
{
    string eventContent = ParseEvent(eventGridEvent);

    HttpClient client = GetProxyClient();
    HttpResponseMessage response = await client.GetAsync("blabla/" + eventContent);
    string responseContent = await response.Content.ReadAsStringAsync();
    log.Info("Here is the response :" + responseContent);
}

外部API响应速度很快(1秒或更短),我的主机配置设置为默认状态(因此允许并发调用数量不受限制)。
当同时添加多个blob(从2个blob开始)时,日志中会出现大量重复事件(脚本快速一次上传一个blob而没有等待时间)。
我感觉这可能是因为我从未确认收到事件,并且不知道我是否应该在我的代码中执行此操作,或者EventGrid Trigger是否会自动处理。
处理事件的确认逻辑是否应该在EventGrid Trigger(Http 200响应)中实现,还是由系统自动处理?
如果不是,请问我是否仍然会收到重复的事件?通常,在上传单个blob时,我会收到3-4次事件。
我提出这个问题的原因是,当使用Http Trigger并返回400响应时,我也会收到重复的事件,这是有道理的,因为我没有确认已正确处理事件。但是,当我返回200响应时,我就不会收到重复的事件了。
谢谢!

1
我也遇到了Azure Functions事件网格触发器的同样问题。单个Blob插入会触发Azure Function 3-4次。我们有任何更新吗? - No8
我也发现了相同的问题。对于运行时间较长的函数,我们该如何解决? - ericOnline
2个回答

5

您不需要做任何特殊的操作来向事件网格指示成功。如果您的函数执行成功(未抛出异常),触发器将自动响应成功状态码。


只是为了明确这一点,如果我的函数需要3分钟才能执行完,但EventGrid的重试策略设置为30秒,那么EventGrid会继续重试直到函数完成,对吗? - ericOnline
有没有一种方法可以在代码中更早地确认EventGrid消息,以防止重试行为? - ericOnline
这是正确的。我认为你不能提前确认,所以你应该保持函数简短(例如,将繁重的工作转移到基于队列的函数中)。 - Mikhail Shilkov
嗯。有没有办法调整EventGrid重试等待时间? - ericOnline
很奇怪的是,这种行为在我的 DEV 功能中根本不会发生。只有 PROD。两者都在移动大文件/运行相同的持续时间。 - ericOnline
我发现在运行时间为1-4.5秒左右的Azure Functions上,EventGrid的重试是不一致的。Azure Function和EventGrid之间是否存在某种响应延迟? - ericOnline

1
您可以尝试使用EventGrid的高级筛选器data.api String ends with FlushWithClose。当上传Blob时,我的Azure函数执行多次的原因是为每个AppendFile操作创建了一个EventGrid消息。
我发现(通过试错)Azure Data Factory使用一系列API调用将单个Blob写入Blob存储。
最终看起来像这样:
- CreateFilePath - LeaseFile - AppendFile - AppendFile - AppendFile(每个附加都会放置一部分Blob,直到完成Blob) - FlushFile(这是文件已完成的实际指示;因此显示了上面的高级筛选器) - LeaseFile 以下是查看此上传流程的示例查询:
注意:您需要一个已上传到Blob容器的示例文件的Uri
//==================================================//
// Author: Eric
// Created: 2021-05-26 0900 
// Query: ADF-to-Blob Storage reference flow
// Purpose: 
// To provide a reference flow of ADF-to-Blob Storage
// file uploads
//==================================================//
// Assign variables
//==================================================//
let varStart = ago(10d);
let varEnd = now();
let varStorageAccount = '<storageaccountname>';
let varStatus = 'Success';
let varSampleUri = 'https://<storageaccountname>.dfs.core.windows.net/<containername>/<parentfolder1>%2F<parentfolder2>%2F<samplefilename.extension>'
//==================================================//
// Filter table
//==================================================//
StorageBlobLogs
| where TimeGenerated between (varStart .. varEnd)
  and AccountName == varStorageAccount
  and StatusText == varStatus
  and split(Uri, '?')[0] == varSampleUri
//==================================================//
// Group and parse results
//==================================================//
| summarize 
  count() by OperationName,
  CorrelationId,
  TimeGenerated,
  UserAgent = tostring(split(UserAgentHeader, ' ')[0]),
  RequesterAppId,
  AccountName, 
  ContainerName = tostring(split(tostring(parse_url(url_decode(Uri))['Path']), '/')[1]),
  FileName = tostring(split(tostring(parse_url(url_decode(Uri))['Path']), '/')[-1]),
  ChunkSize = format_bytes(RequestBodySize, 2, 'MB'),
  StatusCode,
  StatusText
| order by TimeGenerated asc

很有趣的是,上传来自不同来源(Azure Data Factory、Azure Storage Explorer、Python/C# SDK、Azure Portal等)的样本,并查看它们使用的不同API方法。实际上,您可能需要这样做才能使您的记录和警报设置得到完善。
很遗憾,各种工具之间的方法标准化并不一致,因此这个特定问题很难自己发现!
同样,在这种情况下,EventGrid的高级过滤器是您的好帮手。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接