Azure Functions EventGrid触发器

时间:2018-05-16 11:50:00

标签: c# azure azure-functions azure-blob-storage azure-eventgrid

我已经实现了一个EventGrid触发器来响应Blob存储事件,其逻辑简化如下:

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触发器是否自动执行此操作。

确认事件处理的逻辑是否应该在EventGrid触发器(Http 200响应)中实现,还是自动处理?

如果不是,我还应该收到重复的事件吗?通常,在上传单个blob时,我会收到3-4次事件。

我问这个问题的原因是,当使用Http Trigger并返回400响应时,我也会得到重复的事件,这是有意义的,因为我没有承认已经正确处理了事件。但是,当我返回200响应时,我不会收到重复的事件。

由于

2 个答案:

答案 0 :(得分:2)

您不需要做任何特别的事情来表明Event Grid的成功。如果函数执行成功(不抛出异常),触发器将自动响应成功状态代码。

答案 1 :(得分:1)

您可以尝试使用 Advanced Filter 的 EventGrid data.api String ends with FlushWithClose。我的 Azure 函数在 blob 上传时多次执行的原因是,为 blob 上传执行的每个 AppendFile 操作都创建了一条 EventGrid 消息。

我发现(通过反复试验)Azure 数据工厂使用一系列 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 数据工厂、Azure 存储资源管理器、Python/C# SDK、Azure 门户等)上传示例并查看它们使用的不同 API 方法很有趣。事实上,您可能需要这样做才能让您的日志记录和警报拨入。

太糟糕了,这些方法没有跨工具标准化,因为这个特定问题很难自己发现!

同样,在这种情况下,EventGrid Advanced Filters 是您的朋友。