Предисловие
Построение архитектуры микросервисов часто включает в себя создание микросервисов, взаимодействующих с использованием шины сообщений или любых слабо связанных средств, таких как AWS Simple Queue Service, нежно называемый AWS SQS.
Что мы строим
Полный код: spring-boot-localstack Вот пошаговое руководство по настройке простого веб-приложения с весенней загрузкой, взаимодействующего с AWS SQS с использованием локального стека для моделирования среды AWS.
Это включает в себя минимальные конфигурации, необходимые для создания веб-приложения, взаимодействующего только с использованием SQS.
Основные определения:
- локальный стек : Просто инструмент для моделирования облачного провайдера AWS в вашей локальной среде, помогающий разрабатывать облачные приложения.
- Junit5 :
- : Платформа тестирования для Java-приложения, основанного на Java 8. доступность
- : Инструмент для простого и краткого выражения ожиданий от асинхронной системы.
Предварительные условия:
- Базовые знания Java и spring-boot.
- Настройка среды для запуска Docker, например, docker для mac или просто счастливой системы Linux
- Можно настроить AWS CLI , чтобы поиграть с приложением. Утилита командной строки для взаимодействия со службами AWS.
- Знакомый IDE.
Настройка Базового проекта
- Перейдите на второй по популярности веб-сайт в Интернете. Инициализатор пружины
- Создайте проект spring предпочтительно с версией загрузки Spring 2.3 и следующими зависимостями
- Весенняя паутина
- Ломбок (утилита java, позволяющая избежать написания шаблонного кода)
- AWS Простой сервис очередей
- Также добавьте следующие зависимости извне в pom.xml
org.awaitility awaitility 3.1.3 test
Создавайте простые модели событий и данных для отправки и получения сообщений:
@Data @AllArgsConstructor @NoArgsConstructor @Builder public class SampleEvent { private String eventId; private String version; private String type; private ZonedDateTime eventTime; private EventData data; } @Data @AllArgsConstructor @NoArgsConstructor @Builder public class EventData { private String name; private int age; private String description; private EventType eventType; public enum EventType { CREATED, PROCESSED } }
Создайте простой контроллер с аннотацией @Sqllistener для прослушивания очереди.
@SqsListener(value = "${cloud.aws.sqs.incoming-queue.url}", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS) private void consumeFromSQS(SampleEvent sampleEvent) { log.info("Receive message {}", sampleEvent); //do some processing sampleEvent.setEventTime(ZonedDateTime.now()); sampleEvent.getData().setEventType(EventData.EventType.PROCESSED); amazonSQSAsync.sendMessage(outgoingQueueUrl, mapper.writeValueAsString(sampleEvent)); }
Конфигурации свойств пружины:
настройка приложения.yml со свойствами aws sqs, такими как:
localstack: host: localhost cloud: aws: credentials: access-key: some-access-key secret-key: some-secret-key sqs: incoming-queue: url: http://localhost:4576/queue/incoming-queue name: incoming-queue outgoing-queue: name: outgoing-queue url: http://localhost:4576/queue/outgoing-queue stack: auto: false region: static: eu-central-1 logging: level: com: amazonaws: util: EC2MetadataUtils: error
Примечания : учетные данные. Aws также могут быть настроены в переменных среды или в файле .aws/учетные данные (читать далее 😉 ) б. определите имя и URL очередей, чтобы приложение могло прослушивать и записывать в очередь. Локальный стек запускает службу SQS на номере порта: 4576 c. Приведенное ниже свойство ведения журнала позволяет избежать появления нескольких строк ошибок, когда приложение пытается подключиться к экземпляру EC2 localstack. (обходной путь 😏 )
Локальная конфигурация SQS AWS:
Внутри конфигурации java для SQS мы создаем некоторые компоненты, позволяющие нашему приложению взаимодействовать со службой SQS, предоставляемой localstack. Вы можете добавить профиль для каждой конфигурации при развертывании приложения в рабочей среде, т.е. в реальной среде AWS.
@Bean //endpoint config for connecting to localstack and not actual aws environment. public AwsClientBuilder.EndpointConfiguration endpointConfiguration(){ return new AwsClientBuilder.EndpointConfiguration("http://localhost:4576", region); } @Bean @Primary //This bean will be used for communicating to AWS SQS public AmazonSQSAsync amazonSQSAsync(final AwsClientBuilder.EndpointConfiguration endpointConfiguration){ AmazonSQSAsync amazonSQSAsync = AmazonSQSAsyncClientBuilder .standard() .withEndpointConfiguration(endpointConfiguration) .withCredentials(new AWSStaticCredentialsProvider( new BasicAWSCredentials(awsAccesskey, awsSecretKey) )) .build(); createQueues(amazonSQSAsync, "incoming-queue"); createQueues(amazonSQSAsync, "outgoing-queue"); return amazonSQSAsync; } //create initial queue so our application can talk to it private void createQueues(final AmazonSQSAsync amazonSQSAsync, final String queueName){ amazonSQSAsync.createQueue(queueName); var queueUrl = amazonSQSAsync.getQueueUrl(queueName).getQueueUrl(); amazonSQSAsync.purgeQueueAsync(new PurgeQueueRequest(queueUrl)); }
Мы можем использовать QueueMessagingTemplate для отправки и получения сообщений из AWS SQS
@Bean public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSQSAsync){ return new QueueMessagingTemplate(amazonSQSAsync); }
Также настройте QueueMessageHandlerFactory, чтобы он мог преобразовывать входящие сообщения из SQS в виде строки в нужный вам фактический объект, в данном случае Простое событие, с помощью objectmapper. Вы можете настроить objectmapper отдельно. Добавьте свой пользовательский десериализатор, зарегистрировав свой модуль, или добавьте пользовательское преобразование даты и времени.
@Bean public QueueMessageHandlerFactory queueMessageHandlerFactory(MessageConverter messageConverter) { var factory = new QueueMessageHandlerFactory(); factory.setArgumentResolvers(singletonList(new PayloadArgumentResolver(messageConverter))); return factory; } @Bean protected MessageConverter messageConverter(ObjectMapper objectMapper) { var converter = new MappingJackson2MessageConverter(); converter.setObjectMapper(objectMapper); // Serialization support: converter.setSerializedPayloadClass(String.class); // Deserialization support: (suppress "contentType=application/json" header requirement) converter.setStrictContentTypeMatch(false); return converter; }
Наконец добавьте этот докер составьте yaml с просьбой к докеру создать локальный контейнер стека:
version: '3.0' services: localstack: image: localstack/localstack:0.10.7 environment: - DEFAULT_REGION=eu-central-1 - SERVICES=sqs ports: - "4576:4576" volumes: - "/var/run/docker.sock:/var/run/docker.sock"
Запуск приложения
- запустите локальный стек с помощью: docker-составьте (в том же каталоге, что и файл docker)
- запустите приложение с помощью: mvn spring-boot: бежать
- отправьте сообщение в sqs с помощью интерфейса командной строки AWS, например:
aws --endpoint="http://localhost:4576" --region=eu-central-1 sqs send-message --queue-url http://localhost:4576/queue/incoming-queue --message-body '{ "eventId": "some-event-id-1", "eventTime": "2016-09-03T16:35:13.273Z", "type": "some-type", "version": "1.0", "data": { "name": "Dev. to", "age": 20, "description": "User created", "eventType": "CREATED" } }'
- Вы должны увидеть сообщения журнала полученных и отправленных событий.
- Также добавлен тест Junit, который использует ту же конфигурацию, что и для локального запуска.
Спасибо!!
Оригинал: “https://dev.to/sanket2021/aws-sqs-with-spring-boot-localstack-with-junit-testing-8p”