我已经实现了一个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响应时,我不会收到重复的事件。
由于
答案 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
以下是您自己查看此上传流程的示例查询:
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
是您的朋友。