paint-brush
Cómo activar Lambda con SNS Messaging: Sin servidor con AWSpor@taavi-rehemagi
9,959 lecturas
9,959 lecturas

Cómo activar Lambda con SNS Messaging: Sin servidor con AWS

por Taavi Rehemägi2022/01/11
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

Este tutorial analiza las funciones de activación de Amazon Simple Notification Service (SNS). El código en sí solo imitará el comportamiento de un cálculo complejo aleatorio. Usar la cola de mensajes fallidos como grupo para sus registros de errores es un caso de uso inteligente. Enviar datos a través de un servicio de publicación/suscripción como SNS o una cola como SQS garantizará la integridad de los datos. Todo el código de este tutorial ya está en GitHub si desea ver el resultado final de inmediato.

Company Mentioned

Mention Thumbnail
featured image - Cómo activar Lambda con SNS Messaging: Sin servidor con AWS
Taavi Rehemägi HackerNoon profile picture

Si eres como yo, un fanático de la programación basada en eventos, querrás seguir leyendo. Hoy analizaremos la activación de funciones de AWS Lambda a partir de mensajes de AWS SNS . Ya he cubierto algunos temas interesantes relacionados con las arquitecturas sin servidor y AWS, pero nada como esto todavía. Excava y prepárate. Vamos.

TL;DR


Nota *: todo el código de este tutorial ya está en GitHub si desea ver el resultado final de inmediato.*

¿Qué estamos construyendo?

Nuestro enfoque estará únicamente en los pasos para crear los componentes de infraestructura que necesitará nuestra aplicación. El código en sí solo imitará el comportamiento de un cálculo complejo aleatorio. Elegí una función recursiva que calcula el factorial del número que se le pasa. ¡Aquí hay un buen diagrama, porque los diagramas son increíbles, por supuesto!

funciones lambda

La función init es la única función expuesta, que está conectada a API Gateway . Toma un solo parámetro de number que valida, si tiene éxito, publica un tema de SNS y envía el valor del number .


El tema de SNS activará una segunda función llamada calculate . Esta función realizará el cálculo y cerrará la sesión del resultado en la consola. Esto imita una pesada tarea computacional en segundo plano, como el procesamiento de datos, la manipulación de imágenes o los cálculos de aprendizaje automático.

Si la función de calculate falla, el tema SNS de cola de mensajes fallidos recibirá un mensaje y activará la función de error .


Cada función invocada de forma asincrónica volverá a intentar su ejecución dos veces si falla. Usar la cola de mensajes fallidos como grupo para sus registros de errores es un caso de uso inteligente.

Ahora se pregunta, ¿por qué toda la complicación con SNS en lugar de simplemente invocar la segunda función lambda desde la primera con la API de invocación de Lambda ?


En primer lugar, es un gran antipatrón para flujos de trabajo asincrónicos, que es nuestro caso. De lo contrario, está bien si necesita la respuesta de la segunda función lambda de inmediato. Otro problema es alcanzar los límites de concurrencia de Lambda bastante rápido. Puede provocar la pérdida de invocaciones y la eliminación de datos. Enviar sus datos a través de un servicio de publicación/suscripción como SNS o una cola como SQS garantizará la integridad de los datos.


¿Tiene sentido ahora? Dulce, hablemos un poco más sobre SNS.

¿Qué es AWS SNS?

Antes de comenzar a codificar, debemos cubrir los conceptos básicos. Sabemos qué es AWS Lambda, pero ¿qué pasa con SNS? Los documentos de AWS son bastante sencillos.


Amazon Simple Notification Service (SNS) es un servicio de notificaciones móviles y de mensajería pub/sub flexible y completamente administrado para coordinar la entrega de mensajes a los clientes y puntos finales suscritos.

-- Documentos de AWS


En inglés, esto significa que es una forma de enviar notificaciones entre servicios sobre la base de editor/suscriptor. Un servicio publica algunos datos sobre un tema y los envía a lo largo de su camino. SNS luego lo canalizará a todos los suscriptores de ese tema en particular. El enfoque clave está en el tema aquí, verá por qué un poco más abajo.

Cree la API con Serverless Framework

Lo primero que hay que hacer, como siempre, es configurar el proyecto e instalar las dependencias.

1. Instale el marco sin servidor

Mi herramienta preferida de desarrollo e implementación para aplicaciones sin servidor es Serverless Framework . Vamos a seguir adelante e instalarlo.

 $ npm i -g serverless

Nota: si está utilizando Linux, es posible que deba ejecutar el comando como sudo.


Una vez instalado globalmente en su máquina, los comandos estarán disponibles para usted desde cualquier parte de la terminal. Pero para que se comunique con su cuenta de AWS, debe configurar un usuario de IAM. Salta aquí para ver la explicación , luego regresa y ejecuta el comando a continuación, con las teclas provistas.


 $ serverless config credentials\ --provider aws\ --key xxxxxxxxxxxxxx\ --secret xxxxxxxxxxxxxx

Ahora su instalación sin servidor sabe a qué cuenta conectarse cuando ejecuta cualquier comando de terminal. Entremos y veámoslo en acción.

2. Crea un servicio

Cree un nuevo directorio para albergar sus servicios de aplicaciones sin servidor. Enciende una terminal allí. Ahora está listo para crear un nuevo servicio.


¿Qué es un servicio? Es como un proyecto. Es donde define las funciones de AWS Lambda, los eventos que las desencadenan y los recursos de infraestructura de AWS que requieren, incluido SNS, que agregaremos hoy, todo en un archivo llamado serverless.yml .


De vuelta en su tipo de terminal:

 $ serverless create --template aws-nodejs\ --path lambda-sns-dlq-error-handling

El comando crear creará un nuevo servicio . ¡Qué sorpresa! También elegimos un tiempo de ejecución para la función. Esto se llama la plantilla . Pasar aws-nodejs establecerá el tiempo de ejecución en Node.js. Justo lo que queremos. La ruta creará una carpeta para el servicio.

3. Explore el directorio de servicios con un editor de código

Abra la carpeta lambda-sns-dlq-error-handling con su editor de código favorito. Debería haber tres archivos allí, pero por ahora, solo nos centraremos en serverless.yml . Contiene todos los ajustes de configuración de este servicio. Aquí se especifican tanto los ajustes de configuración generales como los ajustes por función. Su serverless.yml estará lleno de código repetitivo y comentarios. Siéntase libre de eliminarlo todo y pegar esto.

 service: lambda-sns-dlq-error-handling plugins: - serverless-pseudo-parameters provider: name: aws runtime: nodejs8.10 stage: dev region: eu-central-1 memorySize: 128 environment: accountId: '#{AWS::AccountId}' region: '#{AWS::Region}' iamRoleStatements: - Effect: "Allow" Resource: "*" Action: - "sns:*" functions: init: handler: init.handler events: - http: path: init method: post cors: true calculate: handler: calculate.handler events: - sns: calculate-topic # created immediately onError: arn:aws:sns:#{AWS::Region}:#{AWS::AccountId}:dlq-topic error: handler: error.handler events: - sns: dlq-topic # created immediately

Analicemos lo que está pasando aquí. Consulte la sección de functions . Hay tres funciones aquí. De arriba a abajo son init , calculate y error . La función init se activará mediante una solicitud HTTP simple, que invocamos a través de API Gateway. Territorio familiar para nosotros.


Sin embargo, las funciones de calculate y error son activadas por temas de SNS. Lo que significa que tendremos lógica en la función de init que publicará mensajes en un tema llamado calculate-topic mientras la función de calculate está suscrita al mismo tema.

Continuando, la función de error está suscrita al dlq-topic mientras que la función de calculate publicará mensajes en este tema si falla, como puede ver con la propiedad onError . Ahora las cosas tienen sentido, ¿verdad?


Tome nota mentalmente, una vez que agregue los temas SNS como eventos para sus funciones, los recursos se crearán automáticamente una vez que implemente el servicio.

Qué más, eche un vistazo a iamRoleStatements , especifican que nuestras funciones tienen permiso para activarse y ser invocadas por temas de SNS. Mientras que el complemento serverless-pseudo-parameters nos permite hacer referencia a nuestro AccountId y Region con la sintaxis de CloudFormation, lo que hace que sea mucho más fácil mantener la coherencia de nuestros SNS ARN en todos los recursos.

4. Instalar dependencias

Por suerte, esta parte será corta. Solo un paquete para instalar. Primero, inicialice npm y luego puede instalar serverless-pseudo-parameters .

 $ npm init -y && npm i serverless-pseudo-parameters

Eso servirá.

5. Escribir lógica de negocios

Con todas las cosas consideradas, el proceso de configuración fue bastante simple. El código que escribiremos ahora es igual de sencillo. Nada extraordinario que ver, lamento decepcionarte.

Mantengamos las tres funciones en archivos separados, para mantenerlo simple. En primer lugar, cree un archivo init.js y pegue este fragmento.


 // init.js const aws = require('aws-sdk') const sns = new aws.SNS({ region: 'eu-central-1' }) function generateResponse (code, payload) { console.log(payload) return { statusCode: code, body: JSON.stringify(payload) } } function generateError (code, err) { console.error(err) return generateResponse(code, { message: err.message }) } async function publishSnsTopic (data) { const params = { Message: JSON.stringify(data), TopicArn: `arn:aws:sns:${process.env.region}:${process.env.accountId}:calculate-topic` } return sns.publish(params).promise() } module.exports.handler = async (event) => { const data = JSON.parse(event.body) if (typeof data.number !== 'number') { return generateError(400, new Error('Invalid number.')) } try { const metadata = await publishSnsTopic(data) return generateResponse(200, { message: 'Successfully added the calculation.', data: metadata }) } catch (err) { return generateError(500, new Error('Couldn\'t add the calculation due to an internal error.')) } }

Tenemos algunas funciones auxiliares y la función lambda exportada en la parte inferior. ¿Que está pasando aqui? La lambda valida la entrada y publica algunos datos en el tema de SNS calculate-topic . Eso es todo lo que está haciendo esta función. El calculate-topic tema de cálculo activará la función de calculate lambda. Agreguemos eso ahora.


Cree un archivo y asígnele el nombre calcule.js . Pegue este fragmento.

 // calculate.js module.exports.handler = async (event) => { const { number } = JSON.parse(event.Records[0].Sns.Message) const factorial = (x) => x === 0 ? 1 : x * factorial(x - 1) const result = factorial(number) console.log(`The factorial of ${number} is ${result}.`) return result }


Como puede ver, esto es solo un cálculo factorial simple implementado con una función recursiva. Calculará el factorial del número que publicamos en el tema SNS desde la función init .


Una nota importante aquí es que si la función de calculate falla un total de tres veces, publicará mensajes en el tema SNS de Dead Letter Queue que especificamos con la propiedad onError en el archivo serverless.yml . La cola de mensajes fallidos activará la función de error . Vamos a crearlo ahora para que pueda cerrar la sesión de errores en CloudWatch. Cree un archivo error.js y pegue estas líneas.


 // error.js module.exports.handler = async (event) => { console.error(event) }


Por ahora, esto servirá. Sin embargo, lo ideal sería tener un registro estructurado con información detallada sobre todo lo que sucede. Ese es un tema para otro artículo.

Implemente la API en AWS Lambda

Aquí viene la parte fácil. Implementar la API es tan simple como ejecutar un comando.

$ serverless deploy\ ![lambda deploy](https://cdn.hackernoon.com/images/cky-9-uq-08500-u-80-bs-6-b-31-s-7-jsp.jpg)


Puede ver que el punto final se registra en la consola. Allí es donde enviarás tus solicitudes.

Prueba la API con Dashbird

La forma más sencilla de probar una API es con CURL. Vamos a crear un comando CURL simple y enviar una carga JSON a nuestro punto final.


 $ curl -H "Content-Type: application/json"\ -d '{"number":1000}'\ https://<id>.execute-api.eu-central-1.amazonaws.com/dev/init

Si todo funciona como debería, el resultado del cálculo se registrará en CloudWatch. Si no, bueno, entonces no tienes suerte.


Después de llegar al punto final varias veces con un par de valores diferentes, este es el resultado. La función init funciona como se esperaba.

monitoreo lambda

Pero, lo que realmente nos interesa es la función de calculate . Esto es lo que parece cuando tiene éxito.

registro de la función lambda

Cuando falla, especificará un bloqueo y mostrará los registros de errores.

registro de errores

Después de dos reintentos, enviará un mensaje a Dead Letter Queue y activará la función de error .

cola de mensajes fallidos

¡Dulce! Hemos probado todos los diferentes escenarios. Espero que esto aclare las cosas un poco.

Terminando

Eso es todo amigos. Cubrimos la creación de activadores de SNS para Lambda y, al mismo tiempo, implementamos una cola de mensajes fallidos para detectar errores de invocaciones fallidas. El uso sin servidor para varios cálculos intermitentes es un caso de uso válido que solo crecerá en popularidad en el futuro.


No hay servidores de los que deba preocuparse, y solo paga por el tiempo que se ejecuta. Simplemente implemente el código y tenga la seguridad de que funcionará.


Nuevamente, aquí está el repositorio de GitHub , si desea echar un vistazo al código. Puede actuar como un iniciador para sus propios casos de uso en los que necesita mensajes SNS que activen las funciones de Lambda. Dale una estrella si te gusta y quieres que más personas lo vean en GitHub.


También publicado en: https://dashbird.io/blog/triggering-lambda-with-sns-messaging/