一个AWS Lambda函数是否可以附加多个计划任务/定时事件?

4

目前我的 Lambda 函数已经能够成功处理一个定时任务事件。以下是来自我的 template.yaml 文件的相关摘录:

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: HelloWorldFunction
      Handler: helloworld.App::handleRequest
      Runtime: java11
      MemorySize: 512
      Environment:
        Variables:
          PARAM1: VALUE
      Events:
        CronHourlyEvent: # This already works
          Type: Schedule
          Properties:
            Description: Send John Doe
            Enabled: True
            Schedule: "cron(0 0/1 * * ? *)"
            Input: !Sub '{"name": "John Doe"}'

Lambda每小时被触发一次,运行良好。
现在我想添加另一个计划事件,每天中午12点触发同一个lambda。一种方法是创建一个单独的lambda并将每日计划事件附加到其中,但我不想为此创建一个新的lambda。我希望能够将两个计划事件附加到同一个lambda上。
我没有找到任何在线示例,其中有多个计划事件附加到lambda上,但我认为需要在template.yaml文件中进行以下添加:
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: HelloWorldFunction
      Handler: helloworld.App::handleRequest
      Runtime: java11
      MemorySize: 512
      Environment:
        Variables:
          PARAM1: VALUE
      Events:
        CronHourlyEvent: # this was already present
          Type: Schedule
          Properties:
            Description: Send John Doe
            Enabled: True
            Schedule: "cron(0 0/1 * * ? *)"
            Input: !Sub '{"name": "John Doe"}'
        CronDailyEvent: # added this
          Type: Schedule
          Properties:
            Description: Send Jane Doe
            Enabled: True
            Schedule: "cron(0 12 1/1 * ? *)"
            Input: !Sub '{"name": "Jane Doe"}'

我想在本地测试,所以我下载并配置了sam-sdk。但我不认为它支持本地运行cron作业。我能够手动触发事件,但找不到任何根据提供的cron表达式自动运行计划任务的方法。

因此,我想知道:

  1. 是否可以将2个或更多的schedule/cron类型事件附加到AWS Lambda函数?
  2. 如果可以,我所做的代码更改是否正确?

这将直接进入生产环境,我似乎找不到一种在本地测试的方法。


2
  1. 可以的。
  2. 我不确定无服务器框架,但我认为您需要为额外的事件创建独立的 AWS::Events::Rule 资源。
- Marcin
1
此外,你在这里提问是因为你不能进行这些更改,因为它会直接进入生产环境(我甚至不想开始解释为什么这种流程是错误的),但你知道你可以创建一个带有测试 Lambda/Rules 的新模板,并将其部署到非生产环境中以查看它是否有效吗? - 404
1
只需设置规则每小时触发一次 Lambda,那么它将在每天中午12点触发。完全同意上面的评论,您应该拥有一个测试环境。 - AnonymousAlias
1
我不明白,虽然它是一个lambda函数,所以当它自动触发时应该做相同的事情,但是为什么你会为每个事件发送不同的输入,然后在lambda中基于此进行逻辑处理呢?听起来你应该有两个单独的lambda函数。最佳实践是将lambda函数用于小型单一目的执行,它们很容易启动且成本低廉。 - AnonymousAlias
1
是的,从设计角度来看,我会有两个不同的 Lambda 函数,其中一个函数的唯一目的是每天清理数据库。 - AnonymousAlias
显示剩余3条评论
4个回答

3

我可能有些晚了,但是对于任何寻找类似解决方案的人来说,只需为触发器使用不同的名称即可。

  Events:
    Serverless:
      Type: Api
      Properties:
        Path: /serverless
        Method: get
    FirstConfigScheduledEvent:
      Type: Schedule
      Properties:
        Schedule: cron(30 21 * * ? *)
    SecondConfigScheduledEvent:
      Type: Schedule
      Properties:
        Schedule: cron(30 23 * * ? *)

3
我正在使用类似以下配置的设置,它完美地工作并满足我的需求。
Resources:
  SayHelloWorldRule:
      Type: AWS::Events::Rule
      Properties:
          Description: The rule for greeting the world
          Name: ${self:provider.stage}-say-hello-world-rule
          ScheduleExpression: 'cron(0 7 * * ? *)'
          State: ENABLED
          Targets:
              -
                Arn:
                  !Join [ ':', [ 'arn:aws:lambda', Ref: AWS::Region, Ref: AWS::AccountId, 'function', 'HelloWorldFunction' ] ]
                Id: "GreetTheWorldDaily"
                Input: '{"user": "Sudo user", "message": "Hello world!!!"}'

  SayGoodbyeWorldRule:
      Type: AWS::Events::Rule
      Properties:
          Description: "It's time to say goodbye"
          Name: ${self:provider.stage}-say-goodbye-rule
          ScheduleExpression: 'cron(30 22 * * ? *)'
          State: ENABLED
          Targets:
              -
                Arn:
                    !Join [ ':', [ 'arn:aws:lambda', Ref: AWS::Region, Ref: AWS::AccountId, 'function', 'HelloWorldFunction' ] ]
                Id: "SayGoodbyeDaily"
                Input: '{"user": "Sudo user", "message": "Auf Wiedersehen!!!"}'

  PermissionForEventsToInvokeHelloWorldLambda:
      Type: AWS::Lambda::Permission
      Properties:
          FunctionName: HelloWorldFunction
          Action: "lambda:InvokeFunction"
          Principal: "events.amazonaws.com"

0
服务器无状态文档提供了创建多个定时任务的方面 -
# the example from our serverless.yml that runs every Monday at 03:15AM UTC
- schedule: cron(15 3 ? * MON *)
# run in 10-minute increments from the start of the hour on all working days
- schedule: cron(1/10 * ? * W *)
# run every day at 6:00PM UTC
- schedule: cron(0 18 * * ? *)

您可以为每个函数指定多个计划事件,以便将计划组合在一起。也可以在同一个函数上组合速率和cron事件。来源-无服务器

0

Serverless 提供了实现这一目标的选项:

functions:
  aggregate:
    handler: statistics.handler
    events:
      - schedule:
          rate: rate(10 minutes)
          enabled: false
          input:
            key1: value1
            key2: value2
            stageParams:
              stage: dev
      - schedule:
          rate: cron(0 12 * * ? *)
          enabled: false
          inputPath: '$.stageVariables'
      - schedule:
          rate: rate(2 hours)
          enabled: true
          inputTransformer:
            inputPathsMap:
              eventTime: '$.time'
            inputTemplate: '{"time": <eventTime>, "key1": "value1"}'

参考:- https://www.serverless.com/framework/docs/providers/aws/events/schedule


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接