I have a lambda function with 2 aliases.
Dev - Points to the $LATEST version
Test - Points to a specific version.
I have setup my SQS queue to trigger both aliases when it receives a message in the queue. However, it only seems to trigger one of them (The one that got registered the latest) and not both. Has anyone else come across this issue?
arn:aws:lambda:us-east-1:XXXXXXXXXXXXXX:function:Amoel:Dev
arn:aws:lambda:us-east-1:XXXXXXXXXXXXXX:function:Amoel:Test
A message on the queue would be consumed only once, by whichever Lambda function grabs it.
If you wish to send the same message to multiple AWS Lambda functions, combine it with Amazon SNS:
SQS queue -> SNS topic -> 2 x Lambda function subscriptions
Be sure to activate Raw Message Delivery on the Amazon SNS topic to preserve the original format of the message from Amazon SQS.
Related
I have set up a lambda function and an SQS service. I want the events from the SQS service to get consumed by the lambda function.
SQS configuration
All the other configuration is set to match the default.
Lambda trigger
Lambda configuration
The code used is from the sqs-poller template (and the configuration too)
Code configuration
I'm using the following code to send the event. I run the code with the following command
AWS_SDK_LOAD_CONFIG=true AWS_SHARED_CREDENTIALS_FILE=./credentials node sqs.js
That works fine because I'm seeing the messages in the monitoring panel of the SQS service.
Any idea why events are not being consumed by my lambda function?
It would appear that you have two competing concepts in your architecture.
Amazon SQS and AWS Lambda
When an Amazon SQS queue is configured as a trigger to an AWS Lambda function, the AWS service polls the SQS queue looking for messages. When message(s) are found, the Lambda function is invoked, with the messages being passed to the function via the event variable.
The Lambda function can then process those messages, reading the detail of the messages from the event variable.
If the Lambda function completes without error, the AWS service will automatically delete the messages from the SQS queue. If there was an error in the function, the messages will automatically reappear on the SQS queue after the invisibility period has expired.
At no time does the AWS Lambda function actually call the Amazon SQS service to receive or delete messages. Rather, it is given the messages when it is invoked.
SQS Poller
You mention that you are using an sqs-poller class. I'm not sure whether you are referring to Receiving Messages Using the QueuePoller Class in Amazon SQS - AWS SDK for Ruby or #jishimi/sqs-poller - npm.
Nonetheless, polling is a traditional way that worker processes retrieve messages from an SQS queue, and then delete the messages after they are processed. The process is:
They ask check whether there are messages available in the SQS queue
If so, they invoke a worker
When the worker is finished, they delete the message
You should notice that these are the same steps that the AWS Lambda service does when SQS is configured as a trigger for an AWS Lambda function. Therefore, using a polling architecture is incompatible with using SQS as a trigger for an AWS Lambda function.
You should pick one or the other, not both.
What is the difference between setting a Dead Letter Queue on an SNS Topic or on a Lambda function?
I was wondering, because if you set the DLQ on the SNS subscription, then that subscription message will fail over to DLQ when the Lambda (the subscriber) fails, correct? So in that scenario would setting the DLQ in these two places have the same effect?
I have set a DLQ on a SNS Topic Subscription, and it didn't "automagically" appear as the DLQ on the Lambda screen settings, so I assume there may be some difference?
SNS dead letter queue ref: https://docs.aws.amazon.com/sns/latest/dg/sns-dead-letter-queues.html
In general, message delivery fails when Amazon SNS can't access a subscribed endpoint due to a client-side or server-side error.
Lambda dead letter queue ref: https://aws.amazon.com/about-aws/whats-new/2016/12/aws-lambda-supports-dead-letter-queues/
AWS Lambda will write the event object invoking the Lambda function to this [DLQ] endpoint after the standard retry policy (2 additional retries on failure) is exhausted.
Lambda:
SNS subscription:
The SNS DLQ is specific for SNS, the benefit here is that it also accounts for client errors such as the Lambda service being down. This will ensure if the Lambda service is down the messages can be replayed to it later, whereas if the DLQ is attached to the Lambda this would only account for a replay if the service is running.
However as I mentioned the SNS DLQ is only for notifications that are from SNS, whereas Lambda can support the DLQ from any incoming events. This means if you have multiple SNS topics, or an SNS topic and some SQS queues you only need to apply it to the Lambda itself.
Both services use SQS for their DLQs so the ingestion/retrieval from both would be identical. If you have a DLQ on both services then yes you might end up with 2 copies of the event/notification, however it is unlikely that you will get both as in theory would the Lambda endpoint acknowledges it SNS would treat as sent, this would then be Lambdas responsibility to add to the DLQ if it fails.
SNS DLQ and Lambda DLQ protect your workload from different failure modes. The former is for failed message delivery from a topic, whereas the latter is for failed function execution. You should use both simultaneously. Here more info: https://aws.amazon.com/blogs/compute/designing-durable-serverless-apps-with-dlqs-for-amazon-sns-amazon-sqs-aws-lambda/
I want to trigger Lambda function whenever new message added to SQS.
Note that I don't want to add new message (events) to SQS.
What I'm trying to do:
My app will send message to SQS
Whenever new message added to queue CloudWatch event gets generated
CloudWatch Event triggers lambda
Problem:
In AWS console while configuring CloudWatch Events I haven't found any option to add source of event i.e. URL or Name of my SQS queue.
I'm not sure if this use case is valid but please help me out.
EDIT: AWS now supports SQS as an event source to trigger Lambda functions. See this blog post for more details.
ORIGINAL ANSWER:
SQS is not supported as a direct event source for AWS Lambda functions. If there are properties of a queueing system that you need for your use case, then you could have a "cron-job" type Lambda function that runs on a schedule, receives messages from the queue, and calls your worker Lambda function in response to each message received. The problem with this approach is that you must continually poll SQS even during periods when you don't expect messages, which incurs unnecessary cost.
The easiest approach is to use SNS instead. Create a topic, publish events to that topic instead of adding a message to an SQS queue, and have your Lambda function subscribe to that SNS topic. It will then be invoked each time a message is published to that SNS topic. There's a tutorial on this approach here:
http://docs.aws.amazon.com/lambda/latest/dg/with-sns-example.html
I would recommend to change your approach.
Your application should publish a message to an existing SNS topic. Your SQS and Lambda should than subscribe to this SNS topic.
Application -> publish -> SNS_TOPIC
-> SQS is notified
-> Lambda is notified
Does AWS lambda provide support for listening to SQS queue? I found some examples which says one can do that but I am not sure if AWS lambda explicity provide support for that. When I create the lambda function, then I found one blueprint for SQS. So,
I linked to it in your other thread - these are the supported event sources. Notice that cloudwatch events are one of the possible event types. You could set up a Lambda to, for example, run every minute and poll an SQS queue. You cannot directly trigger a Lambda off of an SQS queue.
Good news, this feature was released yesterday!
28 JUN 2018: AWS Lambda Adds Amazon Simple Queue Service to Supported Event Sources
Read the announcement blog post here: https://aws.amazon.com/blogs/aws/aws-lambda-adds-amazon-simple-queue-service-to-supported-event-sources/
AWS Serverless Model supports a new event source as following:
Type: SQS
PropertiesProperties:
QueueQueue: arn:aws:sqs:us-west-2:012345678901:my-queue arn:aws:sqs:us-west-2:0123456789 # NOTE: FIFO SQS Queues are not yet supported
BatchSize: 10
And this is how it can be configured from the AWS Console UI:
You can make your lambda function poll the queue using the SQS API. You could use SNS to trigger the Lambda function.
Update: AWS Lambda can now be triggered from Amazon SQS queues.
Old answer:
Rather than having AWS Lambda poll an Amazon SQS queue, the application that sends the message to SQS queue should instead directly invoke the Lambda function. This could be done in several ways:
Direct invocation via an AWS API call
Sending a message to an Amazon SNS topic, with the Lambda function subscribed to the topic
Calling a function via AWS API Gateway, which can then trigger a Lambda function
The extra step of putting a message into an SQS queue is not necessary.
I have the following infrastructure:
I have an EC2 instance with a NodeJS+Express process listening on a port for messages (process 1). Every time the process receives a message it sends it to an SQS queue. Then I have another process in the same machine reading the queue using long polling (process 2). When it finds a message in the queue it inserts the data in a MariaDB database sitting on an RDS instance.
(Just to clarify, messages are generated by users, they send a chunk of data which can contain arbitrary information to the endpoint where the process 1 is listening)
Now I want to put the process that reads the SQS (process 2) in a Lambda function so that the process that writes to the queue and the one that reads from the queue are completely independent. The problem is that I don't know if this is possible.
I know that Lambda function are invoked in response to an event, and the events supported at the moment are S3, SNS, SES, DynamoDB, Kinesis, Cognito, CloudWatch and Cloudformation but NOT SQS.
I was thinking in using SNS notifications to invoke the Lambda function so that every time a message is pushed to the queue, an SNS notification is fired and invokes the Lambda function but after playing a bit with it I've realised that is not possible to create an SNS notification from SQS, it's only possible to write SNS notifications to the queue.
Right now I'm a bit stuck because I don't know how to continue. I have the feeling that is not possible to create this infrastructure due to the current limitations in the AWS services. Is there another way to do what I want or am I in a dead-end?
Just to extend my question with some research I've made, this github repo shows how to read an SQS queu from a Lambda function but the lambda function works only if is fired from the command line:
https://github.com/robinjmurphy/sqs-to-lambda
In the readme, the author mentions the following:
Update: Lambda now supports SNS notifications as an event source,
which makes this hack entirely unneccessary for SNS notifcations. You
might still find it useful if you like the idea of using a Lambda
function to process jobs on an SQS queue.
But I think this doesn't solve my problem, an SNS notification can invoke the Lambda function but I don't see how I can create a notification when a message is received in the SQS queue.
Thanks
There are couple of Strategies which can be used to connect the dots, (A)Synchronously or Run-Sleep-Run to keep the data process flow between SNS, SQS, Lambda.
Strategy 1 : Have a Lambda function listen to SNS and process it in real time [Please note that an SQS Queue can subscribe to an SNS Topic - which would may be helpful for logging / auditing / retry handling]
Strategy 2 : Given that you are getting data sourced to SQS Queue. You can try with 2 Lambda Functions [Feeder & Worker].
Feeder would be scheduled lambda function whose job is to take items
from SQS (if any) and push it as an SNS topic (and continue doing it forever)
Worker would be linked to listen the SNS topic which would do the actual data processing
We can now use SQS messages to trigger AWS Lambda Functions. Moreover, no longer required to run a message polling service or create an SQS to SNS mapping.
Further details:
https://aws.amazon.com/blogs/aws/aws-lambda-adds-amazon-simple-queue-service-to-supported-event-sources/
AWS SQS is one of the oldest products of Amazon, which only supported polling (long and short) up until June 2018. As mentioned in this answer, AWS SQS now supports the feature of triggering lambda functions on new message arrival in SQS. A complete tutorial for this is provided in this document.
I used to tackle this problem using different mechanisms, and given below are some approaches you can use.
You can develop a simple polling application in Lambda, and use AWS CloudWatch to invoke it every 5 mins or so. You can make this near real-time by using CloudWatch events to invoke lambda with short downtimes. Use this tutorial or this tutorial for this purpose. (This could cost more on Lambdas)
You can consider that SQS is redundant if you don't need to persist the messages nor guarantee the order of delivery. You can use AWS SNS (Simple Notification Service) to directly invoke a lambda function and do whatever the processing required. Use this tutorial for this purpose. This will happen in real-time. But the main drawback is the number of lambdas that can be initiated per region at a given time. Please read this and understand the limitation before following this approach. Nevertheless AWS SNS Guarantees the order of delivery. Also SNS can directly call an HTTP endpoint and store the message in your DB.
I had a similar situation (and now have a working solution deploed). I have addressed it in a following manner:
i.e. publishing events to SNS; which then get fanned-out to Lambda and SQS.
NOTE: This is not applicable to the events that have to be processed in a certain order.
That there are some gotchas (w/ possible solutions) such as:
racing condition: lambda might get invoked before messages is deposited into the queue
distributed nature of SQS queue may lead to returning no messages even though there is a message note1.
The solution to both cases would be to do long-polling of SQS queue; but this does make your lambda bill more expensive.
note1
Short poll is the default behavior where a weighted random set of machines is sampled on a ReceiveMessage call. This means only the messages on the sampled machines are returned. If the number of messages in the queue is small (less than 1000), it is likely you will get fewer messages than you requested per ReceiveMessage call. If the number of messages in the queue is extremely small, you might not receive any messages in a particular ReceiveMessage response; in which case you should repeat the request.
http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html
We had some similar requirements so we ended up building a library and open sourcing it to help with SQS to Lambda async. I'm not sure if this fills your particular set of requirements, but thought it might be worth a look: https://read.iopipe.com/sqs-lambda-teaming-up-92c4096be49c