I created below resources using CloudFormation
SQS (DelayDelivery : 0)
Lambda
Roles
LambdaFunctionEventSourceMapping (SQS Triggers a Lambda function)
Logs
Resources created successfully.
When I send a message to SQS with Delay deliver for 30 seconds, SQS triggers Lambda instantaneously. Instead, it should have trigger after 30 seconds.
FYI : I am sending message using AWS console.
As per below link, it should have override the SQS delay to individual message delay.
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-timers.html
Is there any other way to achieve this.
This is possibly a bug with the AWS console, because I encounter similar issue (lambda invoked instantaneously) when I send the message to SQS via AWS console. However, I can achieve the desired behaviour if I send the message to SQS via CLI:
aws sqs send-message --queue-url https://sqs.ap-southeast-1.amazonaws.com/{account}/{sqs} --message-body "msg 1 delay 60 secs" --delay-seconds 60
aws sqs send-message --queue-url https://sqs.ap-southeast-1.amazonaws.com/{account}/{sqs} --message-body "msg 2 delay 30 secs" --delay-seconds 30
Then this is what I see in the lambda Cloudwatch log:
2019-02-19T02:26:36.189Z 510df77b-d1e5-5297-b0a0-a39eba727c61 msg 2 delay 30 secs
2019-02-19T02:26:36.189Z 510df77b-d1e5-5297-b0a0-a39eba727c61 sent 2019-02-19T02:26:06.124Z
2019-02-19T02:26:36.189Z 510df77b-d1e5-5297-b0a0-a39eba727c61 1st receive 2019-02-19T02:26:36.124Z
2019-02-19T02:26:57.729Z fedcb590-2e14-596a-bc4b-e17545a46d91 msg 1 delay 60 secs
2019-02-19T02:26:57.729Z fedcb590-2e14-596a-bc4b-e17545a46d91 sent 2019-02-19T02:25:57.667Z
2019-02-19T02:26:57.729Z fedcb590-2e14-596a-bc4b-e17545a46d91 1st receive 2019-02-19T02:26:57.667Z
As you can see from the log, the messages delivery are properly delayed, and lambdas are only invoked once the message is received.
Related
I have a FIFO Queue in the AWS SQS, which is trigger's Lambda function.
I want to process each messages in Lambda function without parallel execution (one message at a time)
For example: If I have a message A, B, C in the queue. My lambda should complete A, then start B etc.,
My current config of the FIFO queue is
Message retention period: 4 Days
Default visibility timeout: 1 Hour 30 Minutes
Delivery delay: 0 sec
Receive message wait time: 0 Second
set up another lamba(add/setup trigger to invoke this lamba for every one minute using Amazon event brige rule).
In the lamba funtion using receivemessage api call( https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) you can fetch desired number of messages from sqs queue (max 10 messages) and delete after processing each message.
In AWS SQS console,
I have created Standard SQS Queue and configured as following:
Message retention period: 4 hours
Default visibility timeout: 1 hour
Receive message wait time: 0 seconds
Delivery Delay: 0 seconds
Poll settings as following:
Polling Duration: 60 seconds
Maximum message count: 500
But, What if the count of messages sent to the queue is 1500?
There's a lambda that's processing the messages every half an hour and deleting the (read) SQS messages.
Will other 1000 messages get lost or will they get into SQS whenever another messages in SQS are getting deleted?
From docs:
A single Amazon SQS message queue can contain an unlimited number of messages.
So they will not get deleted from your SQS. Instead they will be send to your lambda as a second batch.
I have set up a dead letter queue in AWS Lambda configuration, to handle failed events. But when I tried sending an erroneous record (of size ~1KB), it is not getting sent to DLQ.
Below are the Steps I followed:-
Sent invalid record from aws cli to kinesis stream.
Lambda function polled the record from stream and tried processing. And it resulted into failure due to malformed input.
Checked Lambda function cloud watch logs to confirm that processing has resulted into error.
Checked dead letter errors number in Lambda's cloud watch log but it is still 0. Also verified DLQ through AWS Console, where available messages is still 0.
Configurations in AWS Lambda for asynchronous invocation:
Max age of event = 1 min,
Retry attempts = 1
Configuration of DLQ:
Delivery Delay: 0 seconds
Default Visibility Timeout: 30 seconds,
Maximum Message Size: 256 KB
Can someone explain what could be the possible reason for error messages not available in SQS?
Note : Lambda has required permissions to perform all operations on SQS. And there is no other consumer of SQS.
Lambda reads data from Kinesis synchronously.
DLQ is used only for asynchronous invocations of Lambda.
This all depends on the response you are returning from the function. If the response is a failure with proper error code it will definitely get pushed in DLQ.
can you remove the DLQ configuration and then check if the message appearing in the SQS after the visibility time.
Currently I'm using SQS - Lambda integration
The concurrency for Lambda is available. SQS batch is set to 1 record, 0 delay.
Visibility timeout for SQS is 15 Minutes, Lambda max exec time is 15 Minutes
I would notice that sometimes SQS Messages are stuck in-flight without being processed by any Lambda at all ( They fall into the dead letter queue after 15 minutes, CloudWatch show no Lambda being invoked with the message )
Has anyone faced the same issue?
I run Lambda inside VPC, if that matters
The Lambda backend polls SQS on your behalf and invokes a Lambda function if a message is returned. If the invocation succeeds the message will be deleted if however the function fails the message will be returned to the queue (or DLQ depending on your redrive policy) after the visibility timeout has expired. Check this blog post.
Check if you can see any error metrics for the function in Cloudwatch. Your Lambda function might be failing before it gets a chance to run any code. When this happens there's an error metric but no invocation metric/logs and it's most likely due to an incorrect permission.
I have a AWS Lambda function which is triggered by SQS. This function is triggered approximately 100 times daily, but request count to the SQS queue is approximately 20.000 times daily. I don't understand why the number of requests made to the SQS is too high. My expectation is that the number of requests made to the SQS should be same with the Lambda invocation.
I have only one Lambda function and one SQS queue in my account.
Can be related with polling of SQS queue? I tried to change the polling interval of SQS from the queue configuration but nothing changed. Another possibility is to change polling interval from Lambda function configuration. However, I cannot find any related parameter.
Briefy, I want to reduce number of SQS request, how can i do that while invoking Lmabda function with SQS?
When using SQS as an event source for AWS Lambda, AWS Lambda regularly polls the configured SQS queue to fetch new messages. While the official documentation isn't clear really about that, the blog post announcing that feature goes into the details:
When an SQS event source mapping is initially created and enabled, or when messages first appear after a period with no traffic, then the Lambda service will begin polling the SQS queue using five parallel long-polling connections.
According to the AWS documentation, the default duration for a long poll from AWS Lambda to SQS is 20 seconds.
That results in five requests to SQS every 20 seconds for AWS Lambda functions without significant load, which sums up to the ~21600 per day, which is close to the 20000 you're experiencing.
While increasing the long poll duration seems like an easy way to decrease the number of requests, that's not possible, as the 20 seconds AWS Lambda is using by default is already the maximum possible duration for an SQS queue. I'm afraid there is no easy way to decrease the requests to SQS, when using it as event source for AWS Lambda. Instead depending it could be worth evaluating if another event source, like SNS, would fit your use case as well.
Here is how we originally implemented when there is no SQS trigger.
Create a SNS trigger with the SQS Cloudwatch Metric
ApproximateNumberOfMessagesVisible > 0
Trigger a Lambda from SNS, Read Messages from SQS and deliver it to whichever the lambda needs the message.
Alternatively, you can use Kinesis to deliver it to Lambda.
SQS --> Cloudwatch (Trigger Lambda) --> Lambda(Reads Messages) -->
Kinesis (Set Batch Size) --> Lambda (Handle Actual Message)
You can also use Kinesis directly but there is no delayed delivery.
Hope it helps.