AWSMiddleTechnical
Что такое fan-out pattern SNS → SQS?
Producer публикует событие в SNS topic один раз — SNS доставляет копию в каждую подписанную SQS-очередь. Каждый consumer получает независимый буфер, DLQ и retry policy. Filter policy позволяет очереди получать только релевантные типы событий.
Fan-out SNS → SQS
Fan-out — архитектурный паттерн, при котором одно событие обрабатывается несколькими независимыми системами одновременно. SNS публикует событие один раз, а каждая подписанная SQS-очередь получает свою копию. Это позволяет billing, warehouse и analytics работать независимо: разный темп, своя DLQ, свой visibility timeout.
Настройка через AWS CLI + Python
# 1. Создаём SNS topic
aws sns create-topic --name order-events
# -> TopicArn: arn:aws:sns:eu-west-1:123456789012:order-events
# 2. Создаём SQS очереди для каждого consumer
aws sqs create-queue --queue-name billing-orders
aws sqs create-queue --queue-name warehouse-orders
aws sqs create-queue --queue-name analytics-orders
# 3. Подписываем каждую очередь на topic
aws sns subscribe \
--topic-arn arn:aws:sns:eu-west-1:123456789012:order-events \
--protocol sqs \
--notification-endpoint arn:aws:sqs:eu-west-1:123456789012:billing-orders
import boto3
import json
sns = boto3.client('sns', region_name='eu-west-1')
TOPIC_ARN = 'arn:aws:sns:eu-west-1:123456789012:order-events'
# Producer публикует событие один раз — SNS рассылает в все три очереди
def emit_order_created(order_id: str, customer_id: str, total: float):
sns.publish(
TopicArn=TOPIC_ARN,
Message=json.dumps({
'order_id': order_id,
'customer_id': customer_id,
'total': total,
'version': '1'
}),
MessageAttributes={
# Filter policy по этому атрибуту позволяет отфильтровать
# события на стороне SNS до попадания в очередь
'event_type': {
'DataType': 'String',
'StringValue': 'OrderCreated'
}
}
)
Filter policy: подписка только на нужные события
# Применяем filter policy к подписке analytics-orders:
# они хотят только крупные заказы (event_type=OrderCreated)
SUBSCRIPTION_ARN="arn:aws:sns:eu-west-1:123456789012:order-events:subscription-id"
aws sns set-subscription-attributes \
--subscription-arn $SUBSCRIPTION_ARN \
--attribute-name FilterPolicy \
--attribute-value '{"event_type": ["OrderCreated", "OrderUpdated"]}'
SQS Queue Policy — разрешаем SNS писать в очередь
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "sns.amazonaws.com"},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:eu-west-1:123456789012:billing-orders",
"Condition": {
"ArnEquals": {
"aws:SourceArn": "arn:aws:sns:eu-west-1:123456789012:order-events"
}
}
}]
}
Подводные камни
- Не добавить SQS Queue Policy с разрешением
sqs:SendMessageдля SNS: delivery молча упадёт, сообщения не дойдут, и это трудно заметить без DLQ или метрик. - Не настроить DLQ на каждой очереди: отравленное сообщение будет крутиться до maxReceiveCount, блокируя throughput и маскируя баг в consumer.
- Игнорировать idempotency: каждая очередь получает копию, но при SNS retry (при недоступности) или re-drive из DLQ consumer может получить дубликат — должен обрабатывать его безопасно.
- Не версионировать схему события: если producer добавит новое обязательное поле без согласования, все downstream consumers сломаются одновременно.
- Смешивать Standard и FIFO очереди без понимания: SNS FIFO topic работает только с SQS FIFO queues, а throughput ограничен 300 msg/s (3000 с batching).
- Не следить за метрикой
NumberOfMessagesSentна topic иApproximateNumberOfMessagesNotVisibleна очередях: можно пропустить накопление backlog у одного из consumers. - Использовать filter policy с атрибутом типа Number для строковых значений: SNS не приведёт тип автоматически, фильтр не сработает и очередь будет получать всё подряд.
- Не тестировать cross-account fan-out: если topic и очередь в разных AWS accounts, resource policy нужна с обеих сторон, и это частый источник production-инцидентов при первом деплое.
Common mistakes
- Подключать всех consumers к одной SQS queue и ожидать fan-out.
- Не настраивать queue policy для SNS delivery.
- Забывать DLQ и idempotent processing.
What the interviewer is testing
- Описывает SNS topic и отдельные SQS queues.
- Учитывает retries, DLQ и filters.
- Понимает независимость consumers.