Entregando mensagens em formato ‘raw’ com AWS SNS

Marcelo Palladino
3 min readAug 20, 2017

--

Atualmente tenho trabalhado bastante com sistemas distribuídos e a dupla AWS SNS /SQS aparece em muitos deles. A finalidade óbvia é desacoplar diferentes serviços e jogar ‘nas costas’ da AWS parte da escalabilidade/confiabilidade. As mensagens que são trocadas entre os serviços são as mais diversas possíveis, como se pode imaginar, e algumas vezes o tamanho do que é transmitido (payload) importa muito. Neste artigo vou mostrar uma opção que tenho usado para tornar menores as mensagens entregues pelo SNS.

LEIA ANTES DE PROSSEGUIR

Sobre o que se trata este artigo? Trata-se de explorar sobre uma propriedade específica de assinatura de um tópico SNS.

Criando os recursos necessários

IMPORTANTE: Os exemplos que vou mostrar daqui para frente utilizam a stack do AWS CloudFormation abaixo. Ela cria um tópico SNS, uma fila SQS e uma fila para DLQ.

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Stack para brincar com SNS, SQS'
Resources:
SampleDLQ:
Type: AWS::SQS::Queue
Properties:
DelaySeconds: '0'
VisibilityTimeout: '10'
MessageRetentionPeriod: '1209600'
SampleQueue:
Type: AWS::SQS::Queue
Properties:
DelaySeconds: '0'
VisibilityTimeout: '5'
RedrivePolicy:
deadLetterTargetArn: !GetAtt [SampleDLQ, Arn]
maxReceiveCount: '3'
SampleSNSTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !GetAtt [SampleQueue, Arn]
Protocol: sqs
SampleQueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Id: SampleQueuePolicy
Statement:
- Sid: Allow-SendMessage-To-SampleQueue-From-SNS-Topic
Effect: Allow
Principal: '*'
Action:
- sqs:SendMessage
Resource: '*'
Condition:
ArnEquals:
aws:SourceArn: !Ref 'SampleSNSTopic'
Queues:
- !Ref 'SampleQueue'

Produtores e Consumidores

Usar SNS/SQS normalmente implica em ter produtores e consumidores de dados. No exemplo deste artigo o produtor (uma aplicação console simples) publica a seguinte mensagem no tópico SNS:

{
"Prop1":"Value for property 1",
"Prop2":false,
"Prop3":1000
}

Considerando a stack criada, a notificação da fila SQS vai gerar a mensagem a ser consumida conforme mostra o trecho abaixo.

{
"Type" : "Notification",
"MessageId" : "400eb8e3-f4de-5fdd-b3a8-eaf01ccdafc5",
"TopicArn" : "arn:aws:sns:us-east-1:821038529621:SetSubscriptionAttrSamples-SampleSNSTopic-1DDY6BVXEJAHF",
"Message" : "{\"Prop1\":\"Value for property 1\",\"Prop2\":false,\"Prop3\":1000}",
"Timestamp" : "2017-08-20T19:41:07.849Z",
"SignatureVersion" : "1",
"Signature" : "iHDQO8T0JvX4BeBDscxWSRJw9Le026r3AvAjVZqUg2QZM4oVHZSX88dEXVO+dq5bQeFqjJkuAhRXw0k1D87blq/25cNkA6n4PBM8WcDC25KYhwOgRZOcRKiGZhF3tqSIXt6HnhPGD1jDYoSZlVagXhyRaTWcTLgFkGuM0cNhYt+VnNRYaIPqiN82dQx7JlR7+DGak6XXMn5WDgTvfxsxeEtvGAuWy9pIN2Vfn8j2qnguphcMpdu8ekjH/RtXeU3/iC6H/G74GOj3zueBL/BqQZ7pZpp8HdcYjT8Se3VFEsXECFNGPMLzVWLg40OTaJP1J9MhkOXPRALff0jyKakViA==",
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-433026a4050d206028891664da859041.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:821038529621:SetSubscriptionAttrSamples-SampleSNSTopic-1DDY6BVXEJAHF:d8aef064-ddcb-4794-83a4-df155576c3f1"
}

Note que além da mensagem recebida (deixei em negrito no código), temos uma série de informações úteis. O id da mensagem, data e hora e assim por diante. O tamanho total desta mensagem na fila SQS é 1KB.

Ativando o atributo ‘Raw message delivery’ via console

É possível configurar uma determinada assinatura do SNS para que a mensagem seja entregue em modo raw. Para tanto, nos detalhes do tópico SNS na assinatura específica, escolha ‘Edit subscription attributes’ e marque a opção Raw message delivery.

indicando que a mensagem deve ser entregue à fila SQS em formato raw

Com a assinatura configurada desta forma, temos que a mensagem entregue terá 59 bytes e o aspecto abaixo.

Mensagem na fila SQS em formato raw

Ativando o atributo ‘Raw message delivery’ via AWS CLI

Para fazer a mesma configuração via AWS CLI, basta saber o arn da assinatura SNS que você deseja configurar.

aws sns set-subscription-attributes --attribute-name RawMessageDelivery --attribute-value true --subscription-arn arn-assinatura-vai-aqui

Ativando o atributo ‘Raw message delivery’ da forma como SERIA o ideal

O ideal seria conseguir fazer esta configuração via CloudFormation, não é verdade? Bem, eu ainda não encontrei uma forma de fazer isso. Caso você tenha esbarrado nisso e saiba como fazer, dê um toque aí nos comentários. Vai ser muito bem vindo. :)

Vi umas soluções utilizando ‘custom resources’, mas pelo menos em princípio me parece bem estranho. Não se trata de um recurso customizado…

Fontes utilizados neste artigo

--

--

Marcelo Palladino

Husband, father & enjoying life with family. AWS Community Hero, Software engineer at Hi Platform. Strongly interested in Cloud Computing, specially AWS.