Sé que cuando una función Lambda falla (por ejemplo, cuando hay un tiempo de espera), intenta ejecutar la función 3 veces más nuevamente. ¿Hay alguna forma de evitar este comportamiento? He estado leyendo la documentación, pero no encontré nada sobre esto.

¡Gracias!

26
AleGallagher 2 mar. 2018 a las 15:42

8 respuestas

La mejor respuesta

No hay una forma de deshabilitar el comportamiento de reintento de las funciones de Lambda.

Sugiero dos opciones para lidiar con eso:

  1. Haga que su Lambda pueda manejar los casos de reintento correctamente. Puede usar context.AwsRequestId (o el campo correspondiente) que será el mismo cuando se vuelva a intentar un Lambda.
  2. Coloque su Lambda dentro de una máquina de estado (usando las funciones de paso de AWS). Solo puede deshabilitar los reintentos.

Esta publicación de blog escrito da una explicación más general.

17
Ronyis 20 abr. 2020 a las 19:54

Si llama a la función de forma asincrónica, en Console, debajo de Function configuration, puede modificar el Retry attempts:

enter image description here

2
Franco Piccolo 21 ene. 2020 a las 13:52

Use el código a continuación para identificar y detener el reintento cuando haya una falla.

  exports.handler = (event, context, callback) => {
      context.callbackWaitsForEmptyEventLoop = false;
      let lastReqId;
      if (lastReqId == context.awsRequestId) {
        console.log("Lambda auto retry detected. Aborting");// you can write your own logic to decide what to do with the failure data
        return context.succeed();
      } else {
        console.log("new context");
        lastReqId = context.awsRequestId;
      }
    };

Puede leer más al respecto aquí

0
Kshitiz Jaiswal 11 jul. 2019 a las 05:17

Lo logré colocando la siguiente línea de código:

Devolución de llamada (nulo, "mensaje");

En mi función, como la actualización a continuación de DynamoDB. Cuando hay un error, en lugar de volver a intentarlo durante horas, esta devolución de llamada fuera del if / else detendrá los reintentos.

dynamodb.updateItem(params, function(err, data){
                 if (err) {
                    console.log(err)
                    callback(err, data)
            } else {
                 console.log(data);
                 callback(null, data);
           }
           callback(null, "message");
        });
0
user7249817 10 dic. 2019 a las 03:53

Si está utilizando Python, le recomiendo que siga este hilo.

Si está utilizando Java, dentro del método handleRequest agregue estas líneas:

ClientConfiguration config = new ClientConfiguration();
config.setMaxErrorRetry(0);
-1
herbertgoto 26 ago. 2018 a las 18:10

Si usa Python, entonces también debe poner el código en el bloque try / catch, sin embargo, no habrá devolución de llamada. Por ejemplo:

try:
    do_something()
except Exception as e:
    print('Error: ' + str(e))

Como el error se ha solucionado, Lambda no volverá a intentarlo.

0
Raptor 23 may. 2019 a las 05:15

Desde noviembre de 2019, es posible establecer el recuento de reintentos en 0.

Eso significa que la lambda no se volverá a intentar en caso de error.

2
Matthieu Napoli 10 mar. 2020 a las 18:24

Vuelve a intentarlo cuando se trata de un error no controlado (un error que no detectó) o si lo manejó pero aún así le dijo a Lambda que lo vuelva a intentar (por ejemplo, en Nodo, cuando llame a callback() con un primer argumento no nulo).

Para evitar que vuelva a intentarlo, debe asegurarse de que se maneja cualquier error y decirle a Lambda que su invocación finalizó correctamente al devolver un error (o en Nodo, llamando a callback(null, <any>).

Para hacer esto, puede encerrar todo el cuerpo de su función de controlador con un try-catch.

module.exports.handler(event, context, callback) {
  try {
    // Do you what you want to do.
    return callback(null, 'Success')
  } catch (err) {
    // You probably still want to log it.
    console.error(err)
    // Return happy despite all the hardships you went through.
    return callback(null, 'Still success')
  }
}

En cuanto a las fallas debido a los tiempos de espera, hay cosas que puede hacer.

Si se agota el tiempo de espera fuera de su controlador, generalmente hay algo mal con su código (por ejemplo, configuración incorrecta de la base de datos, etc.) que debe mirar.

Si se agota el tiempo de espera dentro de su controlador durante una invocación, hay algo que puede hacer al respecto.

  • Si se trata de una solicitud HTTP, debe configurar el tiempo de espera de la solicitud para que sea más corto que el tiempo de espera de su Lambda, de esta manera fallará correctamente y podrá atraparlo.
  • Si se trata de una conexión de base de datos, probablemente pueda establecer un tiempo de espera usando la biblioteca que está utilizando.
  • Si su lógica es el tiempo de espera, puede actualizar el Lambda para usar una CPU de memoria más alta para hacerlo más rápido. También puede verificar context.getRemainingTimeInMillis() para saber si el Lambda está a punto de agotarse, para que pueda manejarlo antes.
25
dashmug 3 mar. 2018 a las 23:05