每5秒调用一次Lambda函数

时间:2017-12-04 09:41:19

标签: amazon-web-services cron aws-lambda

我的问题

出于某些监控目的,我想每5秒调用一次AWS Lambda函数。

根据the docs

  

不支持不到一分钟的费率。

我尝试了什么

STFW。

我的问题

我可以每5秒自动调用一次AWS Lambda函数吗?

8 个答案:

答案 0 :(得分:5)

答案 1 :(得分:4)

虽然我不推荐这种方式,但如果你真的需要每5秒执行一次Lambda函数,你可以试试这个:

  1. 创建一个每分钟执行的Lambda函数A.
  2. 创建一个Lambda函数B,由Lambda函数A每5秒触发一次。(A触发B,等待5秒,触发B,等待5秒,......)
  3. 大约一分钟后停止Lambda功能A. (如果达到> 55秒,您可以阅读remaining miliseconds from the context object =>,停止执行)
  4. 请仔细考虑是否真的需要这个。

答案 2 :(得分:2)

这是无服务器的全部功能,它具有每秒执行一次的步进功能-永远一天:

service:
  name: your-service

plugins:
  - serverless-python-requirements
  - serverless-step-functions
  - serverless-pseudo-parameters

custom:
  pythonRequirements:
    dockerizePip: non-linux
  region: eu-west-1
  stage: dev

package:
  exclude:
    - node_modues/**
    - venv/**

provider:
  name: aws
  iamManagedPolicies:
    - arn:aws:iam::aws:policy/AWSStepFunctionsFullAccess
    - arn:aws:iam::aws:policy/AWSLambdaFullAccess
  runtime: python3.7
  versionFunctions: false
  region: ${self:custom.region}
  stage: ${self:custom.stage}
  environment:
    PUSH_FUNCTION: arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:${self:service}-${self:custom.stage}-push
functions:

  schedulerStart:
    handler: scheduler.start
    events:
      - schedule: rate(1 minute)
    environment:
      STATEMACHINE_ARN: ${self:resources.Outputs.SchedulerStateMachine.Value}

  scheduler:
    handler: scheduler.handle

  push:
    handler: scheduler.push


stepFunctions:
  stateMachines:
    everySecond:
      name: SchedulerStateMachine
      definition:
        Comment: "Step Function invoked every minute"
        StartAt: ConfigureCount
        States:
          ConfigureCount:
            Type: Pass
            Result:
              index: 0
              count: 60
            ResultPath: "$.iterator"
            Next: "Iterator"
          Iterator:
            Type: Task
            Resource: "arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:${self:service}-${self:custom.stage}-scheduler"
            ResultPath: "$.iterator"
            Next: "IsCountReached"
          IsCountReached:
            Type: Choice
            Choices:
              - Variable: "$.iterator.continue"
                BooleanEquals: true
                Next: "Wait"
            Default: "Done"
          Wait:
            Type: Wait
            Seconds: 1
            Next: "Iterator"
          Done:
            Type: Pass
            End: true

resources:
  Outputs:
    SchedulerStateMachine:
      Description: The ARN of the state machine
      Value:
        Ref: SchedulerStateMachine

scheduler.py

import os

import boto3

lambda_client = boto3.client('lambda')
step_functions_client = boto3.client('stepfunctions')


def start(event, context):
    step_functions_client.start_execution(stateMachineArn=os.environ['STATEMACHINE_ARN'])
    return {}


def handle(event, context):
    index = event['iterator']['index'] + 1
    lambda_client.invoke(
        FunctionName=os.environ['PUSH_FUNCTION'],
        InvocationType='Event'
    )
    return {
        'index': index,
        'continue': index < event['iterator']['count'],
        'count': event['iterator']['count']
    }

def push(event, context):
    print("Executed every seconds!")
    return{}

答案 3 :(得分:2)

假设重试或轻微的时间漂移​​并不是世界末日。另一种可能的方法是每分钟 cron 一次编排 lambda,然后转身并创建延迟的 sqs 消息。然后您可以使用 sqs lambda 触发器来调用您的目标 lambda。

使用 SQS SendMessage DelaySeconds API(它可能是所有 AWS sdk 的原生 API)作为一个人想要进行的亚分钟调用次数的偏移量。例如,如果您想每 5 秒拨打一次电话,您将创建 12 条消息

  1. delaySeconds: 00
  2. delaySeconds: 05
  3. delaySeconds: 10
  4. delaySeconds: 15
  5. ...

使用这种方法必须特别注意 sqs 的 lambda 调用和重试逻辑。如果多次尝试存在问题,请务必设置 DLQ 并考虑使用 FIFO 队列。根据设计,AWS 可能会多次调用目标 lambda。请注意,标准 SQS 队列是:至少一次传送,FIFO 队列是:恰好一次处理。这种方法也可能会出现一些时间漂移,因为 CloudWatch 可能会在“一分钟之后”几秒钟调用编排 lambda。

这种方法是否比长时间运行编排 lambda 甚至阶跃函数更好?嗯,这取决于很多事情。就我个人而言,我觉得让 lambda 处于等待状态运行的想法很浪费,你必须为大部分时间什么都不做的 lambda 付出代价,如果它是一个大 lambda,那么这些成本就不是微不足道的。使用 step 函数似乎有点矫枉过正,而且设置比 sqs 集成复杂得多。

至少对我来说,让它启动,通过 sqs 安排一组任务并死亡似乎更好。这比长时间运行的 lambda 更复杂,有一些必须解决的并发问题,但如果这是人们想要的地方,它完全是“无服务器”。

综上所述,lambda 并不是所有事情的最佳选择——如果这是一项“永远”的任务,请考虑使用 ECS/Fargate/EC2,因为它很可能更便宜,最终也更简单。< /p>

答案 4 :(得分:1)

Cron只允许至少一分钟。你可以做的是写一个带有无限循环的shell脚本来运行你的任务,然后睡5秒钟。这样,您的任务将每5秒运行一次或多或少,具体取决于任务本身需要多长时间。

但它确实听起来像你在做一些你可能不应该做的事情。这感觉不对。

答案 5 :(得分:1)

无论您何时调用lambda,都可以说1分钟。将其划分为5秒钟,这样您就可以在调用lambda时保持可配置的状态。

然后让循环等待,并在处理程序中每5秒重复一次。 这样,您将不需要任何新的lambda和lambda通话费用。

答案 6 :(得分:0)

我仍然会回答这个问题。

您的整个问题是,无服务器不适用于几乎恒定的工作负载。它们更适合于快速扩展和缩小。但是,如果这不是您的用例,那么几乎肯定可以使用ec2实例在成本上更好,您甚至可以保留一个实例。但是我确实知道您失去了Lambda的高可用性和其他一些好处,这可能会让您仍然选择这种方法。

如果您想使用大锤使这种方法有效,则可以使用StepFunction。 StepFunction可以等待几秒钟,但是唯一的收获是它们不会无限期运行,并且会在一年后死亡,因此您的StepFunction将需要在死亡之前启动另一个StepFunction,否则您将不得不采用其他某种机制,即云监视警报。

对于您正在谈论的调用次数,这种方法也要花费一些钱,这会导致超过

的费用。
  

(31,540,000 [秒/年] / 5 [秒/调用] x $ 0.000025 = $ 157.7)

加上您的Lambda成本,(我认为您实际上需要2次状态转换,因此我认为您需要将该数字翻倍)

如果只打算运行1,可能会没事的。但是如果运行100,那将超过10k!无疑,一个ec2实例将花费您更少的钱。

答案 7 :(得分:-1)

现在有一种使用CloudWatch Events Rule的解决方法,该方法将每分钟触发一次Step Function。然后,step函数将触发给定次数的“迭代器” Lambda,它将调用您的lambda。这是AWS blog post