I've been playing with Lambda recently and am working on creating an API using API Gateway and Lambda. I have a lambda function in place that returns a JSON and an API Gateway endpoint that invokes the function. Everything works well with this simple setup.
I tried loadtesting the API gateway endpoint with the loadtest npm module. While Lambda processes the concurrent requests (albeit with an increase in mean latency over the course of execution), when I send it 40 requests per second or so, it starts throwing errors, only partially completing the requests.
I read in the documentation that by default, Lambda invocation is of type RequestResponse (which is what the API does right now) which is synchronous in nature, and it looks like it is non-blocking. For asynchronous invocation, the invocation type is Event. But lambda discards the return type for async invocations and the API returns nothing.
Is there something I am missing either with the sync, async or concurrency definitions in regards to AWS? Is there a better way to approach this problem? Any insight is helpful. Thank you!
You will have to use Synchronous execution if you want to get a return response from API Gateway. It doesn't make sense to use Async execution in this scenario. I think what you are missing is that while each Lambda execution is blocking, single threaded, there will be multiple instances of your function running in multiple Lambda server environments.
The default number of concurrent Lambda executions is fairly low, for safety reasons. This is to prevent you from accidentally writing a run-away Lambda process that would cost lots of money while you are still learning about Lambda. You need to request an increase in the Lambda concurrent execution limit on your account.
Related
I need to asynchronously invoke lambda functions from my EC2 instance. At high level, so many services come to my mind(most likely all of these support my desired functionality) -
AWS State machine(not sure), step functions, Active MQ, SQS, SNS. I am aware about pros and cons of each at high level. However not sure which one should I go for :|. Please let me know your feedback.
PS: We expect the invocation in 1000s per second at peak for very short periods. Concurrency for lambda functions is not an issue as we can ask Amazon for increase in the limit along with the burst.
If you want to invoke asynchronously then you can not use SQS as SQS invoke lambda function synchronously with event source mapping.
You can use SNS to invoke lambda function asynchronously out of the option you listed above.
Better option would be writing small piece of code in any AWS SDK whichever you are comfortable and then call lambda function from that piece of code asynchronously.
Example in python using boto3 asynchronously
pass Event in InvocationType to invoke lambda function asynchronously and pass RequestResponse to invoke lambda function synchronously
client = boto3.client('lambda')
response = client.invoke(
FunctionName="loadSpotsAroundPoint",
**InvocationType='Event',**
Payload=payload3
I used to think aws lambda was best suited to handle background tasks which did not require immediate results. However more and more I have seen aws lambda being used to handle real-time requests as well, for example fetch users from a db in a http get.
API Gateway -> AWS Lambda -> Results
Is this a standard approach or is this the improper use of lambda ?
Use of API Gateway to provide a front end for the Lambda function invocation is the standard way of executing Lambda function code on the fly. If you are concerned about the cold starts on the function; and want to minize the latency, you can consider Provisioned Concurrency to keep 'n' active containers at a small cost.
I have a aws lambda function which is invoked by API Gateway. The Lambda function calls external API endpoints and it sometime receives network time out while calling external API.
What is the best way to implement retry mechanism in aws lambda to handle network time out or other server side errors? Also is it good to use retry inside lambda function, which cost as per execution time?
Any recommendation is highly appreciated.
Regards
What is the best way to implement retry mechanism in aws lambda to handle network time out or other server side errors?
You can throw time out error further and don't handle it in your Lambda function, in this case your Lambda will be invoked again. Please note that it depends on configuration of your Lambda (i.e. number of retries set).
You can find more theory and practical examples here.
Also is it good to use retry inside lambda function, which cost as per execution time?
Lambda Retries are free for you (you pay only for Lambda execution and not for retry logic). Implementing your own retry approach inside Lambda is not free for you, because you pay for its execution.
You may increase the lambda execution time limiting.
You may track the execution time of the lambda, and when it close to limit, re-call your lambda with the same payload. I mean that lambda re-triggers itself until the external API would successfully response.
You can introduce SQS(Simple Queue System) to your system, where the messages for external API will be stored. And the some of consumer will send messages to external API. It may be an another lambda or some another running service which is responsible just for calling external API.
I have been researching AWS Documentation on how to invoke lambda functions, and I've come across different ways to do that. Mainly, Lambda invocation is done by calling Invoke() function which can be used to invoke lambda functions synchronously or asynchronously.
Currently I am invoking my Lambda functions via HTTP Request (as REST API), but, HTTP Request times out after 30 seconds, while asynchronous calls as far as I know times out after 15min.
What are the advantages, besides time that I have already mentioned, of asynchronous lambda invocation compared to invoking lambda with HTTP Request. Also, what are best (recommended) ways to invoke lambdas in production? On AWS docs (SDK for Go - https://docs.aws.amazon.com/sdk-for-go/api/service/lambda/#InvokeAsyncInput) I see that InvokeAsyncInput and InvokeAsyncOutput have been depricated. So I am wondering how async implementation would actually look like.
Lambda really is about event-driven-computing. This means Lambda always gets triggered in response to an event. This event can originate from a wide range of AWS Services as well as the AWS CLI and SDK.
All of these events invoke the Lambda function and pass some kind of information in the form of an event and context object. How this event looks like depends on the service that triggered lambda. You can find more information about the context in this documentation.
There is no real "best" way to invoke Lambda - this mostly depends on your use case - if you're building a webservice, let API Gateway invoke Lambda for you. If you want to process new files on S3 - let S3 trigger Lambda. If you're just testing the Lambda function you can invoke it via the CLI. If you have custom software that needs to trigger a Lambda function you can use the SDK. If you want to run Lambda on a schedule, configure CloudWatch events...
Please provide more information about your use case if you require a more detailed evaluation of the available options - right now this is very broad.
Here is the situation I suffer.
Lambda has 1000 concurrency limit. (There is no reserved number)
100-200 Clients access to Lambda at a time.
Lambda still doesn't reach throttling in the figures(100-200).
However, Lambda returns a lot of 502 errors.
And I assume
The first time, any Lambda isn't up.
When Lambda receives a lot of requests, it starts scaling.
However, because of Lambda's cold start time, It takes time to execute enough concurrency to handle all requests and as the result, it returns the error(even if it is not reached to maximum concurrency execution number[1000])
Is my assumption correct? If so, is it inevitable situation?
I have read on warming Lambda by sending ping requests at regular interval to the Lambda.
However, It looks not to solve the above issue because the ping is sent to only one Lambda making only the Lambda is resued, causing the same issue when a lot of requests is received at a time.
------Edit------
About #M Mo's asking
How are the lambdas being invoked?
By API-getaway it is invoked.
If through api gateway, are you using proxy integration?
Yes, proxy integration.
Do the lambdas call any other resources?
Yes, The Lambda calls S3 resource to get objects.
What are the average response times of the lambdas?
it takes about 1 sec.