消除 Azure 函数工作流中的重复项?
Eliminating duplicate items in an Azure functions workflow?
我有一个功能应用程序可以监控 swappa.com 并在 phone 列表符合我的条件时发送短信。定时器触发器功能每 15 分钟检查一次 swappa,队列触发器功能为每个匹配的列表发送一条文本消息。我专门使用绑定来访问存储和 twilio 来保持额外的东西 "functiony".
维护状态并避免发送关于相同列表的重复文本消息的最佳函数模式是什么?即使我可以检查列表的年龄,也可以降低较旧列表的价格,使它们成为新的匹配项。所以我需要跟踪已处理的个别列表。
这是我目前想到的两个解决方案。
- 在中间添加一个队列触发函数来检查table存储。如果 table 中没有条目,请将项目添加到 table 和第二个队列中。
function.json
{
"disabled": false,
"bindings": [
{
"name": "queueItem",
"type": "queueTrigger",
"direction": "in",
"queueName": "itemqueue",
"connection": "AzureWebJobsStorage"
},
{
"name": "itemsFoundIn",
"type": "table",
"tableName": "itemsFound",
"partitionKey": "{productId}",
"rowKey": "{price}",
"direction": "in",
"connection": "AzureWebJobsStorage"
},
{
"name": "itemsFoundOut",
"type": "table",
"tableName": "itemsFound",
"partitionKey": "{productId}",
"rowKey": "{price}",
"direction": "out",
"connection": "AzureWebJobsStorage"
},
{
"type": "queue",
"direction": "out",
"name": "$return",
"queueName": "smsqueue",
"connection": "AzureWebJobsStorage"
}
]
}
index.js
module.exports = function (context, queueItem) {
if (context.bindings.itemsFoundIn) {
context.log("queueItem already present in table storage. Treating as duplicate.");
context.done();
}
else {
context.log("queueItem not found in table storage. Placing in table and destination queue.");
context.bindings.itemsFoundOut = queueItem;
context.done(null, queueItem);
}
};
缺点:如果这个功能禁用一段时间后又启用,可能会有并行执行同时检查table存储并传递两个实例将同一列表放到第二个队列中。
- 为短信功能使用 blob 触发器而不是队列触发器。使用 blob 名称来消除重复项。如果只使用绑定,可能需要在两者之间添加一个单独的队列触发器函数来检查现有的 blob,并将队列项转换为新的 blob。
缺点:
- blob 输出绑定将更新现有的 blob,因此中间函数的并行执行仍有机会触发两条文本消息。
- 根据https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob,短信功能可以延迟10分钟。
如果您担心重复,最直接的方法是将列表的所有 ID(或哈希值)保持在一个状态(例如,在单个 table 存储行中)。在您的计时器触发器中加载此状态,根据该状态筛选出解析结果,然后更新状态并发送 SMS 队列项目。
您还应该能够从此状态中移除旧项目,以避免它随着时间的推移而爆炸。
我不确定您将拥有多少列表。但由于您能够每 15 分钟抓取一次所有这些,我认为我的场景是可行的。否则,请按照您的回答中所述使用基于队列的方案。
我有一个功能应用程序可以监控 swappa.com 并在 phone 列表符合我的条件时发送短信。定时器触发器功能每 15 分钟检查一次 swappa,队列触发器功能为每个匹配的列表发送一条文本消息。我专门使用绑定来访问存储和 twilio 来保持额外的东西 "functiony".
维护状态并避免发送关于相同列表的重复文本消息的最佳函数模式是什么?即使我可以检查列表的年龄,也可以降低较旧列表的价格,使它们成为新的匹配项。所以我需要跟踪已处理的个别列表。
这是我目前想到的两个解决方案。
- 在中间添加一个队列触发函数来检查table存储。如果 table 中没有条目,请将项目添加到 table 和第二个队列中。
function.json
{
"disabled": false,
"bindings": [
{
"name": "queueItem",
"type": "queueTrigger",
"direction": "in",
"queueName": "itemqueue",
"connection": "AzureWebJobsStorage"
},
{
"name": "itemsFoundIn",
"type": "table",
"tableName": "itemsFound",
"partitionKey": "{productId}",
"rowKey": "{price}",
"direction": "in",
"connection": "AzureWebJobsStorage"
},
{
"name": "itemsFoundOut",
"type": "table",
"tableName": "itemsFound",
"partitionKey": "{productId}",
"rowKey": "{price}",
"direction": "out",
"connection": "AzureWebJobsStorage"
},
{
"type": "queue",
"direction": "out",
"name": "$return",
"queueName": "smsqueue",
"connection": "AzureWebJobsStorage"
}
]
}
index.js
module.exports = function (context, queueItem) {
if (context.bindings.itemsFoundIn) {
context.log("queueItem already present in table storage. Treating as duplicate.");
context.done();
}
else {
context.log("queueItem not found in table storage. Placing in table and destination queue.");
context.bindings.itemsFoundOut = queueItem;
context.done(null, queueItem);
}
};
缺点:如果这个功能禁用一段时间后又启用,可能会有并行执行同时检查table存储并传递两个实例将同一列表放到第二个队列中。
- 为短信功能使用 blob 触发器而不是队列触发器。使用 blob 名称来消除重复项。如果只使用绑定,可能需要在两者之间添加一个单独的队列触发器函数来检查现有的 blob,并将队列项转换为新的 blob。
缺点:
- blob 输出绑定将更新现有的 blob,因此中间函数的并行执行仍有机会触发两条文本消息。
- 根据https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob,短信功能可以延迟10分钟。
如果您担心重复,最直接的方法是将列表的所有 ID(或哈希值)保持在一个状态(例如,在单个 table 存储行中)。在您的计时器触发器中加载此状态,根据该状态筛选出解析结果,然后更新状态并发送 SMS 队列项目。
您还应该能够从此状态中移除旧项目,以避免它随着时间的推移而爆炸。
我不确定您将拥有多少列表。但由于您能够每 15 分钟抓取一次所有这些,我认为我的场景是可行的。否则,请按照您的回答中所述使用基于队列的方案。