我正在使用无服务器,移植两个函数,一个(称为生成器)当前是一个长时间运行的节点进程,另一个(称为检查器)由 cron 触发,因此它们都是 lambdas,由 a 触发的检查器通过接收 SQS 通知来调度和生成器。我也是能够进行本地开发的忠实粉丝,因此添加了 serverless-offline 和 serverless-offline-sqs(由 ElasticMQ 支持)。
移植了生成器,它在本地部署和运行得很好。这是 serverless.yml 中定义的函数:
reportGenerator:
handler: src/reportGenerator.handleReportRequest
events:
- sqs:
arn:
Fn::GetAtt:
- ReportRequestQueue
- Arn
我可以使用 AWS CLI 通过 ElasticMQ 触发消息(aws account # obfuscated):
$ aws sqs send-message --queue-url https://sqs.us-west-1.amazonaws.com/000000000000/local-report-request --message-body file://./test/reportGenerator/simple_payload.json --endpoint-url http://localhost:9324
{
"MD5OfMessageBody": "267bd9129a76e3f48c26903664824c13",
"MessageId": "12034cd8-3783-403a-92eb-a5935c8759ae"
}
$
并且消息接收良好,生成器 lambda 触发:
{
"requestId": "ckokpja2e0001nbyocufzdrxk",
"function": "src/reportGenerator.js::exports:14",
"level": "info",
"message": "Found 0 waiting report request(s)"
}
offline: (λ: reportGenerator) RequestId: ckokpja2e0001nbyocufzdrxk Duration: 214.53 ms Billed Duration: 215 ms
现在我想以编程方式为第二个函数发送 SQS,这几乎是对现有(非 lambda)函数的唯一真正更改。它也部署/启动得很好,但是发送相同消息的 aws-sdk 库函数不起作用。
这是 serverless.yml 中的函数定义。请注意,我注释掉了正常的 cron 计划,因为 serverless-offline 不支持它,并且仅使用 10 分钟的速率进行测试:
reportChecker:
handler: src/reportScheduler.check
environment:
REPORT_REQUEST_QUEUE_URL: "https://sqs.us-west-1.amazonaws.com/${self:custom.awsAccountId}/${opt:stage, self:custom.defaultStage}-report-request"
events:
# note that cron does not work for offline. Comment these out, and uncomment the rate to test locally
# - schedule:
# rate: cron(0 11 ? * 3 *)
# input:
# reportType: weekly
# - schedule:
# rate: cron(0 11 2 * ? *)
# input:
# reportType: monthly
- schedule:
rate: rate(10 minutes)
input:
reportType: weekly
这是我作为上述命令行的节点版本添加到函数的其余部分的内容:
const AWS = require('aws-sdk');
AWS.config.update({region: process.env.AWS_REGION});
...
try {
const sqs = new AWS.SQS({endpoint: 'http://localhost:9324'});
logger.debug('SQS info', {queueUrl: process.env.REPORT_REQUEST_QUEUE_URL, endpoint: sqs.endpoint});
await sqs.sendMessage({
QueueUrl: process.env.REPORT_REQUEST_QUEUE_URL,
MessageBody: `{"reportType":${checkType}}`
})
.promise();
}
catch(err) {
logger.error('SQS failed to send', {error: err});
}
这些记录器语句的输出是
{
"requestId": "ckokpulxw0002nbyo19sj87g2",
"function": "src/reportScheduler.js::exports:100",
"data": {
"queueUrl": "https://sqs.us-west-1.amazonaws.com/000000000000/local-report-request",
"endpoint": {
"protocol": "http:",
"host": "localhost:9324",
"port": 9324,
"hostname": "localhost",
"pathname": "/",
"path": "/",
"href": "http://localhost:9324/"
}
},
"level": "debug",
"message": "SQS info"
}
{
"requestId": "ckokpulxw0002nbyo19sj87g2",
"function": "src/reportScheduler.js::exports:109",
"data": {
"error": {
"message": "The specified queue does not exist for this wsdl version.",
"code": "AWS.SimpleQueueService.NonExistentQueue",
"time": "2021-05-12T00:20:00.497Z",
"requestId": "e55124c3-248e-5afd-acce-7dd605fe1fe5",
"statusCode": 400,
"retryable": false,
"retryDelay": 95.52839314049268
}
},
"level": "error",
"message": "SQS failed to send"
}
offline: (λ: reportChecker) RequestId: ckokpulxw0002nbyo19sj87g2 Duration: 477.95 ms Billed Duration: 478 ms
在我看来,它确实看起来像代码使用与命令行相同的所有值,但它只是不起作用。希望其他人可以在这里看到明显的东西。
谢谢。