O Amazon SQS (Simple Queue Service) é uma solução de fila para troca de mensagens entre aplicações hospedada pela própria Amazon, assim seu gerenciamento é todo através de serviços, o que faz com que toda a complexidade da infraestrutura seja terceirizada para AWS, dessa forma, nos deixando apenas concentrado na utilização da solução de fila. Além disso, o SQS disponibiliza até 1 milhões de solicitações por mês sem custo.
O gerenciamento da fila pode ser feita pelo console do SQS na conta da AWS, como na imagem abaixo.
Para utilizar o SQS em aplicações Java, a Amazon disponibiliza as libs aws-java-sdk e amazon-sqs-java-messaging-lib, a primeira (aws-java-sdk) é o SDK da AWS, onde estão as classes para autenticação e a amazon-sqs-java-messaging-lib as funcionalidades para utilizar o SQS. Também é adicionado a lib spring-jms que habilita as funcionalidades do JMS no Spring Boot.
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk</artifactId> <version>1.11.236</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>amazon-sqs-java-messaging-lib</artifactId> <version>1.0.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> </dependency>
Como vamos utilizar o JMS como padrão de conexão com a fila, basicamente a única diferença de uma implementação para outra tecnologia de fila é configurar a ConnectionFactory do SQS, com isso, no exemplo abaixo é criado a connectionFactory no @PostConstruct da classe de configuração e depois as configurações padrões do JMS, os beans de jmsListenerContainerFactory e JmsTemplate.
@SpringBootApplication @EnableJms public class ConsumerApplication { private SQSConnectionFactory connectionFactory; public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } @PostConstruct public void init() { connectionFactory = createSQSConnectionFactory(); } private SQSConnectionFactory createSQSConnectionFactory() { final AmazonSQS sqs = AmazonSQSClient.builder() .withRegion(Regions.US_EAST_2) .withCredentials(new ProfileCredentialsProvider()) .build(); return new SQSConnectionFactory(new ProviderConfiguration(), sqs); } @Bean public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() { final DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); return factory; } @Bean public JmsTemplate defaultJmsTemplate() { return new JmsTemplate(connectionFactory); } }
- SQSConnectionFactory: Factory com as configurações de autenticação ao serviço do SQS na AWS;
- DefaultJmsListenerContainerFactory: Factory padrão com as configurações do Listener da fila, como será utilizado apenas o essencial no listener, apenas necessário preencher a connectionFactory do SQS;
- JmsTemplate: É a declaração do bean do JMS, que possibilita a injeção e utilização dos recursos do JMS.
Umas das vantagens de utilizar o JMS para consumir a fila do SQS é que a implementação é basicamente a mesma independente da solução de fila, caso no futuro a solução mude para outra tecnologia (por exemplo RabbitMQ), seria basicamente mudar a connectionFactory.
Após feita as configurações na classe ConsumerApplication, a conexão com o SQS será iniciada no startup da aplicação, assim, o próximo passo é configurar o listener(ou consumer) da fila utilizando a anotação @JmsListener no método, assim o método estará consumindo a fila, como demonstrado no exemplo abaixo.
@Component public class ConsumerListener { @JmsListener(destination = "${consumer.sqs.message.queue.name}") public void messageConsumer(@Headers Map<String, Object> messageAttributes, @Payload String message) { // Do something System.out.println("Messages attributes: " + messageAttributes); System.out.println("Body: " + message); } }
- @JmsListener: Anotação que define que o método está “escutando” uma fila;
- destination: Defina a fila que será “escutada”;
- ${consumer.sqs.message.queue.name}: O nome da fila que está sendo referenciado pela configuração do application.properties, que por placeholder, o Spring Boot faz o bind do valor da configuração;
- @Headers Map<String, Object messageAttributes: A anotação @Headers define que o atributo do tipo Map<String, Object> vai receber os parâmetros de headers, chamados de messageAttributes no contexto do SQS;
- @Payload String message: A anotação @Payload define qual atributo receberá o valor da mensagem consumida pela fila.
O código demonstrado pode ser encontrado no github.
Veja também como enviar mensagens para o SQS no post “Enviando mensagens para o Amazon SQS”.
Muito bom!
Poderia explicar um pouco o uso do ProfileCredentialsProvider()?
Obrigado mesmo!
CurtirCurtir
Que bom que tenha gostado. Claro, o ProfileCredentialsProvider faz com que as credencias utilizadas na conexão com o SQS seja a default do ambiente, no caso, as credencias (aws_access_key_id e aws_secret_access_key) do arquivo .aws/credentials.
[default]
aws_access_key_id = XXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXX
CurtirCurtir