简体   繁体   中英

Can't use SQS from Lambda

What I've done:

I'm creating an example scheduled lambda that needs to dequeue messages from a SQS queue. I've created it using Serverless framework and Kotlin with the following configuration:

service: example

provider:
  name: aws
  runtime: java8
  region: eu-west-1
  memorySize: 128
  environment:
      sqs_url:
        Ref: MessagesQueue
  iamRoleStatements:
      - Effect: Allow
        Action:
          - sqs:*
        Resource:
          Fn::GetAtt: [ MessagesQueue, Arn ]

package:
  artifact: target/example-1.0.0.jar

functions:
  dequeue:
    handler: com.example.Handler
    events:
      - schedule: rate(2 minutes)

resources:
  Resources:
    MessagesQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: ${self:service}-queue

Here's the Handler class:

package com.example

import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler
import org.slf4j.LoggerFactory
import com.amazonaws.services.sqs.AmazonSQSClientBuilder

class Handler:RequestHandler<Map<String, Any>, Any> {
    override fun handleRequest(input:Map<String, Any>, context:Context):Any {

        LOG.info("Initializing SQS Client...")
        val sqs = AmazonSQSClientBuilder.defaultClient()
        LOG.info("SQS Client Initialized!")

        return Any()
    }
    companion object {
        private val LOG = LoggerFactory.getLogger(Handler::class.java)
    }
}

I'm using the following AWS dependencies on my POM:

    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-sqs</artifactId>
        <version>1.11.251</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-lambda-java-core</artifactId>
        <version>1.1.0</version>
    </dependency>

My problem:

My lambda is logging as following:

START RequestId: ac75e49e-e56e-11e7-ba03-39085056ac2f Version: $LATEST
[2017-12-20 10:15:18.015] ac75e49e-e56e-11e7-ba03-39085056ac2f INFO c.p.Handler - Initializing SQS Client...
END RequestId: ac75e49e-e56e-11e7-ba03-39085056ac2f
REPORT RequestId: ac75e49e-e56e-11e7-ba03-39085056ac2f  Duration: 6006.13 ms  Billed Duration: 6000 ms Memory Size: 128 MB  Max Memory Used: 60 MB  
2017-12-20T10:15:23.185Z ac75e49e-e56e-11e7-ba03-39085056ac2f Task timed out after 6.01 seconds

So basically something bad happens when I'm trying to initialize the SQS client, since I can't see the "done" log, bringing Lambda to timeout.

I've searched for some working example using java for a simple lambda that dequeue, but I can't find anything valuable, only SQS SDK example without lambdas.

Am I doing something wrong? Is there maybe another SDK that I need to use inside a Lambda?

The answer to this question has been discussed in the question's comments section. But I would like to emphasize on how to troubleshoot a problem like this if faced, and so that this question will get an answer and that it may also help the community.

When faced with a problem where Lambda terminates without executing a certain part of a code, it could be due to the following reasons.

Reason 1 : Lambda times out, even before it could finish processing. Lambda is meant to be a server-less architecture that can be used for small tasks. If you want to run a process that needs to be running all the time, I recommend using an EC2 instance. Therefore every Lambda function has a time-out for the process to complete. Therefore increasing the time-out of the Lambda function can solve this problem. (Always refrain from setting time-out to a maximum of 5 mins, because it can cost you a lot for unexpected function time-outs) - This is the answer to this question .

Reason 2 : If the function is using asynchronous calls like in NodeJS, your lambda can terminate while you are still executing the asynchronous call. Therefore have a mechanism where lambda does not terminate until all asynchronous calls have returned their values. Best way to solve this is by using sync call libraries instead of async calls.

Reason 3 : Most obvious reason where code has mistakes in it. This will terminate Lambda, where you can see the error and fix it accordingly.

Reason 4 : This could also happen due to lack of proper resource allocation like memory. If your function needs a certain memory to execute, do allocate it before hand by estimating the proper value required by running the function on a test environment beforehand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM