1

我正在使用无服务器,移植两个函数,一个(称为生成器)当前是一个长时间运行的节点进程,另一个(称为检查器)由 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

在我看来,它确实看起来像代码使用与命令行相同的所有值,但它只是不起作用。希望其他人可以在这里看到明显的东西。

谢谢。

4

0 回答 0