Manejar errores en aplicaciones sin servidor

con AWS Step Functions y AWS Lambda

En este tutorial, aprenderá a usar AWS Step Functions para manejar los errores de tiempo de ejecución del flujo de trabajo. AWS Step Functions es un servicio de coordinación sin servidor que le permite coordinar fácilmente múltiples funciones de Lambda en flujos de trabajo flexibles que son fáciles de depurar y de cambiar. AWS Lambda es un servicio informático que le permite ejecutar código sin aprovisionar ni administrar servidores. 

Las funciones de Lambda pueden fallar ocasionalmente, como cuando se genera una excepción no controlada, cuando se ejecutan por más tiempo que el tiempo de espera configurado o cuando se quedan sin memoria. Escribir y mantener la lógica de manejo de errores en cada una de sus funciones de Lambda para manejar situaciones tales como la limitación de API o los tiempos de espera de socket puede requerir mucho tiempo y ser complicado, especialmente para aplicaciones distribuidas. Incorporar este código en cada función de Lambda crea dependencias entre ella y puede ser difícil mantener todas esas conexiones a medida que las cosas cambian.

Para evitar esto y reducir la cantidad de código de manejo de errores que escribe, puede usar AWS Step Functions para crear un flujo de trabajo sin servidor que admita el manejo de errores de función. Independientemente de si el error es una excepción de función creada por el desarrollador (por ejemplo, archivo no encontrado) o no prevista (por ejemplo, sin memoria), puede configurar Step Functions para responder con lógica condicional en función del tipo de error que ocurrió. Cuando separa su lógica de flujo de trabajo de su lógica empresarial de esta manera, puede modificar cómo responde su flujo de trabajo a los errores sin cambiar la lógica empresarial de sus funciones de Lambda.

En este tutorial, diseñará y ejecutará un flujo de trabajo sin servidor con AWS Step Functions que manejará estos errores con elegancia. Creará una función de AWS Lambda que simulará llamadas a la API RESTful y devolverá varios códigos de respuesta y excepciones. Luego, utilizará AWS Step Functions para crear una máquina de estado con capacidades de Reintentar y Capturar que responda con una lógica diferente según la excepción planteada.

Es necesario contar con una cuenta de AWS para realizar este tutorial

No hay cargos adicionales para AWS Step Functions o AWS Lambda. Los recursos que cree en este tutorial son elegibles para el capa gratuita. 

Más información sobre la capa gratuita >>


Paso 1. Cree una función de Lambda para simular una API

En este paso, creará una función de Lambda que imitará algunas interacciones de API básicas. La función de Lambda genera excepciones para simular respuestas de una API ficticia, según el código de error que proporcione como entrada en el parámetro del evento.


a.  Abra la consola de administración de AWS para poder mantener abierta esta guía paso a paso. Cuando la pantalla se cargue, escriba su nombre de usuario y contraseña para comenzar. Luego, escriba Lambda en la barra de búsqueda y seleccione Lambda para abrir la consola de servicio.

(Haga clic para ampliar)


b. Seleccione Crear una función.

(Haga clic para ampliar)


c. Deje seleccionado Autor desde cero. Luego, configure su función de Lambda de la siguiente manera:

Para Nombre, escriba MockAPIFunction.
Para Tiempo de ejecución, elija Python 3.6.
Para Rol, seleccione Crear rol personalizado.

Se abrirá una nueva ventana de IAM. Deje el Nombre del rol como lambda_basic_execution y haga clic en Permitir. Volverá automáticamente a la consola de Lambda.

Haga clic en Crear función.

(Haga clic para ampliar)


d. En la pantalla de MockAPIFunction , desplácese hacia abajo hasta la sección Código de función. En este tutorial, creará una función que utiliza el modelo de programación para crear funciones de Lambda en Python. En la ventana de código, reemplace todo el código con lo siguiente, luego seleccione Guardar.

class TooManyRequestsException(Exception): pass
class ServerUnavailableException(Exception): pass
class UnknownException(Exception): pass

def lambda_handler(event, context):
    statuscode = event["statuscode"]    
    if statuscode == "429":
        raise TooManyRequestsException('429 Too Many Requests')
    elif statuscode == "503":
        raise ServerUnavailableException('503 Server Unavailable')
    elif statuscode == "200":
        return '200 OK'
    else:
        raise UnknownException('Unknown error')

(Haga clic para ampliar)


e. Una vez que se crea su función de Lambda, desplácese hasta la parte superior de la ventana y observe su nombre de recurso de Amazon (ARN) en la esquina superior derecha de la página. Los nombres de recursos de Amazon (ARN) identifican de manera exclusiva los recursos de AWS y lo ayudan a rastrear y usar elementos y políticas de AWS en los servicios de AWS y las llamadas a la API. Se requiere un ARN cuando necesita referirse a un recurso específico de Step Functions.

(Haga clic para ampliar)


Paso 2. Cree un rol de AWS Identity and Access Management (IAM)

AWS Step Functions puede ejecutar código y acceder a otros recursos de AWS (por ejemplo, datos almacenados en buckets de Amazon S3). Para mantener la seguridad, debe otorgar a Step Functions acceso a estos recursos mediante AWS Identity and Access Management (IAM).


a. En otra ventana del navegador, vaya hasta la consola de administración de AWS y escriba IAM en la barra de búsqueda. Haga clic en IAM para abrir la consola de servicio.

(Haga clic para ampliar)


b. Haga clic en Roles, luego seleccione Crear rol.

(Haga clic para ampliar)


c. En la página de Seleccionar tipo de entidad de confianza, en el servicio de AWS, seleccione Step Functions de la lista y luego seleccione Siguiente: permisos.

(Haga clic para ampliar)


d. En la página de Adjuntar política de permisos, elija Siguiente: revisar.

 

(Haga clic para ampliar)


e. En la página de Revisar, escriba step_functions_basic_execution para Nombre del rol y haga clic en Crear rol.

(Haga clic para ampliar)


f. Su nuevo rol de IAM se crea y aparece en la lista debajo del rol de IAM para su función de Lambda.

(Haga clic para ampliar)


Paso 3. Cree una máquina de estado de Step Functions

Ahora que ha creado su función de Lambda simple que simula una respuesta de API, puede crear una máquina de estado de Step Functions para llamar a la API y manejar excepciones.

En este paso, usará la consola de Step Functions para crear una máquina de estado que use un estado de tarea con un campo de reintentar y capturar para manejar los diversos códigos de respuesta de API. Utilizará un estado de tarea para invocar su simulación de la función de API de Lambda, que devolverá el código de estado de API que proporcionó como entrada en su máquina de estado.


a. Inicie sesión en la consola de AWS Step Functions. En la página de Crear una máquina de estado, seleccione Autor desde cero. En la sección de Detalles, asigne un nombre a su máquina de estado a MyAPIStateMachine y luego seleccione Usaré una función existente.

(Haga clic para ampliar)


b. A continuación, diseñará una máquina de estado que tomará diferentes acciones en función de la respuesta de su API simulada. Si no se puede alcanzar la API, el flujo de trabajo volverá a intentarlo. Los reintentos son una forma útil de abordar los errores transitorios. El flujo de trabajo también detecta diferentes excepciones lanzadas por la API simulada.

Reemplace el contenido de la sección de Definición de máquina de estado con el siguiente código:

{
  "Comment": "An example of using retry and catch to handle API responses",
  "StartAt": "Call API",
  "States": {
    "Call API": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME",
      "Next" : "OK",
      "Comment": "Catch a 429 (Too many requests) API exception, and resubmit the failed request in a rate-limiting fashion.",
      "Retry" : [ {
        "ErrorEquals": [ "TooManyRequestsException" ],
        "IntervalSeconds": 1,
        "MaxAttempts": 2
      } ],
      "Catch": [ 
        {
          "ErrorEquals": ["TooManyRequestsException"],
          "Next": "Wait and Try Later"
        }, {
          "ErrorEquals": ["ServerUnavailableException"],
          "Next": "Server Unavailable"
        }, {
          "ErrorEquals": ["States.ALL"],
          "Next": "Catch All"
        }
      ]
    },
    "Wait and Try Later": {
      "Type": "Wait",
      "Seconds" : 1,
      "Next" : "Change to 200"
    },
    "Server Unavailable": {
      "Type": "Fail",
      "Error":"ServerUnavailable",
      "Cause": "The server is currently unable to handle the request."
    },
    "Catch All": {
      "Type": "Fail",
      "Cause": "Unknown error!",
      "Error": "An error of unknown type occurred"
    },
    "Change to 200": {
      "Type": "Pass",
      "Result": {"statuscode" :"200"} ,
      "Next": "Call API"
    },
    "OK": {
      "Type": "Pass",
      "Result": "The request has succeeded.",
      "End": true
    }
  }
}

(Haga clic para ampliar)


c. Busque la línea de “Recurso” en el estado de la tarea “API de llamada” (línea 7). Para actualizar este ARN al ARN de la función simulada de API de Lambda que acaba de crear, haga clic en el texto de ARN y luego seleccione el ARN de la lista.

(Haga clic para ampliar)


d. Haga clic en el botón de Actualizar al lado del panel de flujo de trabajo visual para que Step Functions creen un diagrama de máquina de estado que corresponda al flujo de trabajo que acaba de diseñar. Después de revisar el flujo de trabajo visual, haga clic en Crear máquina de estado.

(Haga clic para ampliar)


Paso 4. Pruebe su flujo de trabajo de manejo de errores

Para probar su flujo de trabajo de manejo de errores, invocará su máquina de estado para llamar a su API simulada proporcionando el código de error como entrada.


a. Haz clic en Iniciar ejecución.

(Haga clic para ampliar)


b. Aparecerá un nuevo cuadro de diálogo de ejecución, donde puede ingresar la entrada para su máquina de estado. Representará a la API y proporcionará el código de error que queremos que devuelva la API simulada. Reemplace el texto existente con el código a continuación, luego seleccione Iniciar ejecución:

{
    "statuscode": "200"
}

(Haga clic para ampliar)


c. En la pantalla de Detalles de ejecución, haga clic en Entrada para ver la entrada que proporcionó a su máquina de estado. Luego, haga clic en Salida para ver el resultado de la ejecución de su máquina de estado. Puede ver que el flujo de trabajo interpretó el código de estado 200 como una llamada la API exitosa.

(Haga clic para ampliar)


d. En Flujo de trabajo visual, puede ver la ruta de ejecución de cada ejecución, que se muestra en verde en el flujo de trabajo. Haga clic en el estado de la tarea “Llamar a la API” y luego expanda los campos de Entrada y Salida en la pantalla de Detalles del paso.

Puede ver que este estado de tarea invocó con éxito su simulación de la función de API de Lambda con la entrada que proporcionó y capturó el resultado de esa función de Lambda, “200 OK”.

(Haga clic para ampliar)


e. A continuación, haga clic en el estado de la tarea “OK” en el flujo de trabajo visual. En Detalles del paso, puede ver que la salida del paso anterior (el estado de la tarea de Llamar a la API) se ha pasado como entrada a este paso. El estado OK es un estado de Pasó, que simplemente pasa su entrada a su salida, sin realizar ningún trabajo. Los estados de pasada son útiles cuando se construye y depura máquinas de estados.

(Haga clic para ampliar)


Paso 5. Inspeccione la ejecución de su máquina de estado


a. Desplácese hasta la parte superior de la pantalla en Detalles de ejecución y haga clic en MyAPIStateMachine.

(Haga clic para ampliar)


b. Haga clic en Iniciar ejecución nuevamente y esta vez proporcione la siguiente entrada y luego haga clic en Iniciar ejecución.

{
    "statuscode": "503"
}

(Haga clic para ampliar)


c. En la sección de Historial de eventos de ejecución, expanda cada paso de ejecución para confirmar que su flujo de trabajo se comportó como se esperaba. Esperábamos que esta ejecución fallara, ¡así que no se alarme! Notará que:

  1. Step Functions capturó su entrada
  2. Esa entrada se pasó al estado de la tarea de Llamar a la API
  3. El estado de la tarea Llamar a la API llamó a MockAPIFunction con esa entrada
  4. MockAPIFunction se ejecutó
  5. MockAPIFunction falló con ServerUnavailableException
  6. La declaración de captura en el estado de tarea de Llamar a la API detectó esa excepción
  7. La declaración de captura falló en el flujo de trabajo
  8. Su máquina de estado completó su ejecución

(Haga clic para ampliar)


d. A continuación, simulará una excepción 429. Desplácese hasta la parte superior de la pantalla en Detalles de ejecución y haga clic en MyAPIStateMachine. Haga clic en Iniciar ejecución, proporcione la siguiente entrada y haga clic en Iniciar ejecución:

{
    "statuscode": "429"
}

(Haga clic para ampliar)


e. Ahora inspeccionará el comportamiento de reintento de su flujo de trabajo. En la sección de Historial de eventos de ejecución, expanda cada paso de ejecución una vez más para confirmar que Step Functions intentó llamar a la función MockAPILambda dos veces más y ambas fallaron. En ese momento, su flujo de trabajo pasó al estado Esperar e intentar más tarde (que se muestra en la imagen de la derecha), con la esperanza de que la API no respondiera temporalmente.

Luego, el estado de Espera utilizó la fuerza bruta para cambiar el código de respuesta a 200 y su flujo de trabajo completó la ejecución con éxito. Probablemente no sea así como manejó una excepción 429 en una aplicación real, pero mantenemos las cosas simples por el bien del tutorial.

(Haga clic para ampliar)


f. Ejecute una instancia más de su flujo de trabajo y esta vez proporcione una respuesta a la API aleatoria que no sea manejada por su máquina de estado:

{
    "statuscode": "999"
}

Inspeccione la ejecución nuevamente con el Historial de eventos de ejecución. Cuando termine, haga clic en MyAPIStateMachine una vez más. En el panel Ejecuciones, puede ver el historial de todas las ejecuciones de su flujo de trabajo y acceder a ellas individualmente como lo desee.

(Haga clic para ampliar)


Paso 6. Finalice los recursos

En este paso, finalizará los recursos relacionados con AWS Step Functions y AWS Lambda.

Importante: finalizar los recursos que no se utilizan de forma activa reduce los costos y es una práctica recomendada. No terminar los recursos puede conllevar cargos.


a. En la parte superior de la ventana de la consola de AWS Step Functions, haga clic en Máquinas de estado.

(Haga clic para ampliar)


b. En la ventana de Máquinas de estado, haga clic en MyAPIStateMachine y seleccione Eliminar. Confirme la acción con la selección de Eliminar máquina de estado en el cuadro de diálogo. Su máquina de estado se eliminará en uno o dos minutos una vez que Step Functions haya confirmado que se han completado las ejecuciones en proceso.

(Haga clic para ampliar)


c. A continuación, eliminará sus funciones de Lambda. En el menú de la consola de administración de AWS, haga clic en Servicios y luego seleccione Lambda.

(Haga clic para ampliar)


d. En la pantalla de Funciones , haga clic en MockAPIFunction, seleccione Acciones y luego Eliminar. Confirme la eliminación con un clic en Eliminar nuevamente.

(Haga clic para ampliar)


e. Por último, eliminará sus roles de IAM. Haga clic en Servicios en el menú de la consola de administración de AWS, luego seleccione IAM.

(Haga clic para ampliar)


f. Seleccione los dos roles de IAM que creó para este tutorial, luego haga clic en Eliminar rol. Confirme la eliminación con un clic en Sí, eliminar en el cuadro de diálogo.


Ahora puede cerrar sesión en la consola de administración de AWS.

(Haga clic para ampliar)


¡Felicitaciones!

Ha utilizado AWS Step Functions y AWS Lambda para crear un flujo de trabajo de manejo de errores para una API de red. Con AWS Lambda, puede ejecutar código para prácticamente cualquier tipo de aplicación o servicio de backend, todo sin necesidad de administración. Solo tiene que cargar el código y Lambda se encargará de todo lo necesario para ejecutar y escalar el código con alta disponibilidad.

La combinación de AWS Step Functions con AWS Lambda simplifica la coordinación de las funciones de AWS Lambda para aplicaciones sin servidor. Step Functions le permite controlar flujos de trabajo complejos con las funciones de Lambda sin que la aplicación subyacente administre y coordine el estado. También puede usar Step Functions para la coordinación de microservicios con recursos informáticos como Amazon EC2 y Amazon ECS.


¿Le resultó útil este tutorial?