使用Amazon SQS完成Lambda功能时通知浏览器客户端

时间:2015-10-20 19:55:26

标签: node.js amazon-web-services amazon-sqs aws-lambda

在我的场景中,我正在尝试实现服务器较少的后端运行相当长时间的计算。此计算由Lambda管理,引用一些外部API。

要求我这样做,我正在使用具有10秒执行限制的Amazon API Gateway。然而Lambda运行大约100秒。

为了避免这种限制,我使用第二个Lambda函数来执行这个耗时的计算&报告计算已开始。

我看起来非常相似:

var AWS = require('aws-sdk');
var colors = require('colors');

var functionName = 'really-long'

var lambda = new AWS.Lambda({apiVersion: '2015-03-31'});

var params = {
  FunctionName: functionName, 
  InvocationType: 'Event'
};


lambda.invoke(params, function(err, data) {
  if (err) console.log(err, err.stack); // an error occurred
  else     console.log(functionName.green + " was successfully executed and returned:\n" + JSON.stringify(data, null, 2).gray);           // successful response
});

console.log("All done!".rainbow);

此代码由数千个客户端浏览器独立在AWS API Gateway上执行。

通知每个特定客户端他的Lambda函数执行成功完成我计划使用AWS SQS(因为长轮询和一些其他有用的功能开箱即用)。

所以我的问题是

如何在客户端上确定队列中哪条消息属于此特定客户端?或者我应该遍历所有队列以通过每个客户端浏览器中的某个请求ID参数查找正确的消息?我想当1000个客户端同时等待他们的结果时,这种方法效率低下。

我知道我可以将结果写入DynamoDB,并通过一些自制的API定期轮询DB以获得结果。但是是否有任何优雅的解决方案来通知基于浏览器的客户端基于某些Amazon PaaS解决方案完成执行耗时的Lambda功能?

2 个答案:

答案 0 :(得分:3)

老实说,DynamoDB路线可能是你最好的选择。您可以在API网关执行的第一个Lambda函数中生成uuid。将该uuid传递给长期运行的Lambda函数。在第二个函数完成之前,它会写入一个包含两列的DynamoDB表:uuidresult

API网关使用生成的uuid响应客户端。然后,客户端使用针对DynamoDB表的getItem请求进行长轮询(通过aws-sdk直接或通过其他API网关请求)。成功响应后,从DynamoDB表中删除所述项目。

答案 1 :(得分:1)

lambda函数的上下文对象将AWS请求ID返回给调用Lambda函数的客户端。

因此,客户端将具有Lambda 1的lambda请求ID,Lambda 1 Context对象将具有相同的请求Id(无论lambda重试,请求ID保持不变)。因此,通过实际请求ID将此请求ID传递给Lambda 2,直到结束。

使用来自客户端的请求ID进行轮询对于像dynamodb这样的任何数据存储都相当容易。