¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Colas de SQS: enviar, recibir y borrar

Después de esta lección: Puedo decir qué le pasa a un mensaje desde que se envía hasta que se borra.

Lección de 55 min6 comandosLaboratorio Cloud: practica con buckets S3, colas SQS y tablas DynamoDB desde la línea de comandos de AWS

La cola del bocadillo en el recreo

En la cantina de un instituto hay una sola cola. El alumno nuevo se pone al final y el cantinero atiende a quien está al principio.

Una cola de SQS hace lo mismo con mensajes. Una tienda deja cada pedido nuevo en la cola y un trabajador los coge de uno en uno. Esta lección sigue un mensaje desde que se envía hasta que se borra.

Al final de esta lección

Nota

Puedo decir qué le pasa a un mensaje desde que se envía hasta que se borra.

Palabras clave

PalabraQué significa
Colauna fila de mensajes que esperan a ser tratados
Mensajeun texto que espera en una cola
Recibirpedir a la cola mensajes para trabajar con ellos
Visibility timeoutel tiempo que un mensaje recibido queda oculto
Receipt handleel resguardo que permite borrar un mensaje recibido
Al menos una vezun mensaje puede llegar dos veces, pero nunca ninguna

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Recibir te da un mensaje

send_message pone un texto en la cola. Su respuesta trae un MessageId. receive_message pide mensajes. Su respuesta trae una lista llamada Messages.

Cada mensaje tiene un Body, que es el texto, y un ReceiptHandle. Un cuerpo es solo texto. Muchas tiendas guardan JSON en él, y el trabajador lo vuelve diccionario con json.loads.

Ejemplo resuelto: una respuesta de receive

CampoQué contieneEjemplo
Messagesuna lista con un diccionario por mensajedos mensajes
MessageIdel id que dio la cola al enviarm-1
Bodyel texto que se envió{"pedido": 1, "producto": "bocadillo"}
ReceiptHandleel resguardo para borrar esta recepciónh-1
ApproximateReceiveCountcuántas veces se recibió, en texto"1"

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Leer una respuesta de receive

Código: python
import json
answer = {
    "Messages": [
        {"MessageId": "m-1", "ReceiptHandle": "h-1",
         "Body": "{\"pedido\": 1, \"producto\": \"bocadillo\"}",
         "Attributes": {"ApproximateReceiveCount": "1"}},
        {"MessageId": "m-2", "ReceiptHandle": "h-2", "Body": "dos",
         "Attributes": {"ApproximateReceiveCount": "1"}},
    ]
}
for message in answer["Messages"]:
    print(message["MessageId"], message["Body"])
order = json.loads(answer["Messages"][0]["Body"])
print("producto:", order["producto"])
# Cambia el bucle para que muestre también el ReceiptHandle.

Un mensaje recibido está oculto, no borrado

Recibir no quita el mensaje. Lo oculta durante el visibility timeout, que es de 30 segundos en la cola capturada. Otros trabajadores no pueden recibirlo mientras está oculto.

Cuando el trabajo termina, llama a delete_message con el ReceiptHandle. Solo entonces desaparece el mensaje. Si el trabajador se cae antes, el tiempo acaba y el mensaje vuelve a ser visible para otro.

Ejemplo resuelto: atributos de una cola

AtributoValorSignificado
VisibilityTimeout"30"segundos que un mensaje recibido queda oculto
ApproximateNumberOfMessages"3"mensajes que esperan ser recibidos
ApproximateNumberOfMessagesNotVisible"0"mensajes ocultos tras una recepción
MessageRetentionPeriod"345600"segundos que se guarda un mensaje, cuatro días

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Oculto y luego visible otra vez

Código: python
TIMEOUT = 30
received_at = {"m-1": 100}


def is_visible(message_id, now):
    if message_id not in received_at:
        return True
    return now >= received_at[message_id] + TIMEOUT


for now in [100, 120, 130, 160]:
    print(now, is_visible("m-1", now))
print("m-2 nunca recibido:", is_visible("m-2", 100))
# Cambia TIMEOUT a 60. ¿En qué momentos es visible m-1 ahora?

Un error frecuente

Advertencia

Mucha gente cree que recibir quita el mensaje. Solo lo oculta. Si nunca llamas a delete_message, el mensaje vuelve tras el tiempo y se trata otra vez. Bórralo cuando el trabajo esté hecho, nunca antes.

Al menos una vez significa que hay repeticiones

La cola guarda un mensaje hasta que se borra, así que un mensaje puede llegar dos veces. Un trabajador puede acabar el trabajo y caerse antes de borrar.

Una recepción también puede devolver menos mensajes de los pedidos, o ninguno. Una respuesta vacía no tiene la clave Messages, así que léela con .get. Escribe el trabajador para que una repetición no haga daño.

Saltarse una repetición

Código: python
deliveries = ["m-1", "m-2", "m-1", "m-3"]
done = []
for message_id in deliveries:
    if message_id in done:
        print(message_id, "otra vez: sáltalo")
    else:
        done.append(message_id)
        print(message_id, "primera vez: haz el trabajo")

empty = {}
print("mensajes:", len(empty.get("Messages", [])))
# Prueba con empty["Messages"]. ¿Qué sale mal?

Pruébalo en el laboratorio de nube

El laboratorio de nube es una copia de práctica de S3, SQS y DynamoDB. Pulsa Iniciar el laboratorio en la barra y luego Ejecutar en cada orden de abajo. Usan la línea de comandos real de AWS, así que las mismas palabras sirven en una cuenta real. Tras borrar, vuelve a preguntar a la cola: no imprime nada, la cola parece vacía. Este paso es para practicar. La tarea de abajo sigue siendo Python simple, así que puedes hacerla sin el laboratorio.

Pon una clave inventada y la dirección

Comando
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test AWS_DEFAULT_REGION=us-east-1 AWS_ENDPOINT_URL=http://cloud:4566

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Crea una cola

Comando
Q=$(aws sqs create-queue --queue-name orders --query QueueUrl --output text)

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Envía un mensaje

Comando
aws sqs send-message --queue-url $Q --message-body "order 1"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Recíbelo y guarda la respuesta

Comando
aws sqs receive-message --queue-url $Q | tee reply.json

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Guarda su resguardo, el ReceiptHandle

Comando
H=$(grep -o '"ReceiptHandle": "[^"]*"' reply.json | cut -d'"' -f4)

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Borra el mensaje

Comando
aws sqs delete-message --queue-url $Q --receipt-handle "$H"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Sobre este laboratorio y su código: Laboratorio Cloud: practica con buckets S3, colas SQS y tablas DynamoDB desde la línea de comandos de AWS

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.