Управление очередями Amazon SQS в Java

Управление очередями Amazon SQS в Java

1. обзор

В этом руководстве мы узнаем, как использоватьuse Amazon’s SQS (Simple Queue Service) using the Java SDK.

2. Предпосылки

Зависимости Maven, настройки учетной записи AWS и клиентское соединение, необходимые для использования Amazon AWS SDK для SQS, такие же, как вthis article here.

Предполагая, что мы создали экземплярAWSCredentials,, как описано в предыдущей статье, мы можем продолжить и создать наш клиент SQS:

AmazonSQS sqs = AmazonSQSClientBuilder.standard()
  .withCredentials(new AWSStaticCredentialsProvider(credentials))
  .withRegion(Regions.US_EAST_1)
  .build();

3. Создание очередей

После того, как мы настроили наш клиент SQS,creating queues is fairly straightforward.

3.1. Создание стандартной очереди

Давайте посмотрим, как создать стандартную очередь. Для этогоwe’ll need to create an instance of CreateQueueRequest:

CreateQueueRequest createStandardQueueRequest = new CreateQueueRequest("example-queue");
String standardQueueUrl = sqs.createQueue(createStandardQueueRequest).getQueueUrl();

3.2. Создание очереди FIFO

Создание FIFO аналогично созданию стандартной очереди. Мы по-прежнему будем использовать экземплярCreateQueueRequest, как и раньше. Только на этот разwe’ll have to pass in queue attributes, and set the FifoQueue attribute to true:

Map queueAttributes = new HashMap<>();
queueAttributes.put("FifoQueue", "true");
queueAttributes.put("ContentBasedDeduplication", "true");
CreateQueueRequest createFifoQueueRequest = new CreateQueueRequest(
  "example-queue.fifo").withAttributes(queueAttributes);
String fifoQueueUrl = sqs.createQueue(createFifoQueueRequest)
  .getQueueUrl();

4. Отправка сообщений в очереди

После того, как мы настроили наши очереди, мы можем начать отправлять сообщения.

4.1. Отправка сообщения в стандартную очередь

Чтобы отправлять сообщения в стандартную очередь, мы будемhave to create an instance of SendMessageRequest.

Затем мы прикрепляем карту атрибутов сообщения к этому запросу:

Map messageAttributes = new HashMap<>();
messageAttributes.put("AttributeOne", new MessageAttributeValue()
  .withStringValue("This is an attribute")
  .withDataType("String"));

SendMessageRequest sendMessageStandardQueue = new SendMessageRequest()
  .withQueueUrl(standardQueueUrl)
  .withMessageBody("A simple message.")
  .withDelaySeconds(30)
  .withMessageAttributes(messageAttributes);

sqs.sendMessage(sendMessageStandardQueue);

withDelaySeconds()  указывает, по истечении какого времени сообщение должно поступить в очередь.

4.2. Отправка сообщения в очередь FIFO

Единственная разница в этом случае состоит в том, чтоwe’ll have to specify the group to which the message belongs:

SendMessageRequest sendMessageFifoQueue = new SendMessageRequest()
  .withQueueUrl(fifoQueueUrl)
  .withMessageBody("Another simple message.")
  .withMessageGroupId("example-group-1")
  .withMessageAttributes(messageAttributes);

Как вы можете видеть в приведенном выше примере кода, мы указываем группу, используяwithMessageGroupId().

4.3. Отправка нескольких сообщений в очередь

Мы также можемpost multiple messages to a queue, using a single request.. Создадим список изSendMessageBatchRequestEntry, который мы отправим, используя экземплярSendMessageBatchRequest:

List  messageEntries = new ArrayList<>();
messageEntries.add(new SendMessageBatchRequestEntry()
  .withId("id-1")
  .withMessageBody("batch-1")
  .withMessageGroupId("example-group-1"));
messageEntries.add(new SendMessageBatchRequestEntry()
  .withId("id-2")
  .withMessageBody("batch-2")
  .withMessageGroupId("example-group-1"));

SendMessageBatchRequest sendMessageBatchRequest
 = new SendMessageBatchRequest(fifoQueueUrl, messageEntries);
sqs.sendMessageBatch(sendMessageBatchRequest);

5. Чтение сообщений из очередей

Мы можем получать сообщения из наших очередейinvoking the receiveMessage() method on an instance of ReceiveMessageRequest:

ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(fifoQueueUrl)
  .withWaitTimeSeconds(10)
  .withMaxNumberOfMessages(10);

List sqsMessages = sqs.receiveMessage(receiveMessageRequest).getMessages();

ИспользуяwithMaxNumberOfMessages(),, мы указываем, сколько сообщений получить из очереди, хотя следует отметить, что максимум составляет10.

МетодwithWaitTimeSeconds() включаетlong-polling. Длинный опрос - это способ ограничить количество запросов на получение сообщений, которые мы отправляем в SQS. 

Проще говоря, это означает, что мы будем ждать указанное количество секунд, чтобы получить сообщение. Если в очереди в течение этого времени нет сообщений, запрос вернется пустым. Если сообщение поступит в очередь в течение этого времени, оно будет возвращено.

Мы можемget the attributes and body of a given message:

sqsMessages.get(0).getAttributes();
sqsMessages.get(0).getBody();

6. Удаление сообщения из очереди

Чтобы удалить сообщение, мы будем использоватьDeleteMessageRequest:

sqs.deleteMessage(new DeleteMessageRequest()
  .withQueueUrl(fifoQueueUrl)
  .withReceiptHandle(sqsMessages.get(0).getReceiptHandle()));

7. Очереди мертвых писем

A dead letter queue must be of the same type as its base queue — it должен быть FIFO, если базовая очередь - FIFO, и стандартным, если базовая очередь стандартная. В этом примере мы будем использовать стандартную очередь.

Первое, что нам нужно сделать, этоcreate what will become our dead letter queue:

String deadLetterQueueUrl = sqs.createQueue("example-dead-letter-queue").getQueueUrl();

Затем мыget our newly created queue’s ARN (Amazon Resource Name):

GetQueueAttributesResult deadLetterQueueAttributes = sqs.getQueueAttributes(
  new GetQueueAttributesRequest(deadLetterQueueUrl)
    .withAttributeNames("QueueArn"));

String deadLetterQueueARN = deadLetterQueueAttributes.getAttributes()
  .get("QueueArn");

Наконец, мыset this newly created queue to be our original standard queue’s dead letter queue:

SetQueueAttributesRequest queueAttributesRequest = new SetQueueAttributesRequest()
  .withQueueUrl(standardQueueUrl)
  .addAttributesEntry("RedrivePolicy",
    "{\"maxReceiveCount\":\"2\", "
      + "\"deadLetterTargetArn\":\"" + deadLetterQueueARN + "\"}");

sqs.setQueueAttributes(queueAttributesRequest);

The JSON packet we set in the addAttributesEntry() method when building our SetQueueAttributesRequest instance contains the information we need:maxReceiveCount - это2, что означает, что если сообщение получено столько раз, предполагается, что оно было обработано неправильно, и отправлено в нашу очередь недоставленных сообщений.

АтрибутdeadLetterTargetArn указывает нашу стандартную очередь на нашу недавно созданную очередь недоставленных сообщений.

8. мониторинг

Мы можемcheck how many messages are currently in a given queue, and how many are in flight with the SDK.. Сначала нам нужно создатьGetQueueAttributesRequest. 

Оттуда мы проверим состояние очереди:

GetQueueAttributesRequest getQueueAttributesRequest
  = new GetQueueAttributesRequest(standardQueueUrl)
    .withAttributeNames("All");
GetQueueAttributesResult getQueueAttributesResult
  = sqs.getQueueAttributes(getQueueAttributesRequest);
System.out.println(String.format("The number of messages on the queue: %s",
  getQueueAttributesResult.getAttributes()
    .get("ApproximateNumberOfMessages")));
System.out.println(String.format("The number of messages in flight: %s",
  getQueueAttributesResult.getAttributes()
    .get("ApproximateNumberOfMessagesNotVisible")));

Более глубокий мониторинг может быть достигнут с помощьюAmazon Cloud Watch.

9. Заключение

В этой статье мы увидели, какmanage SQS queues using the AWS Java SDK.

Как обычно, все примеры кода, использованные в статье, можно найтиover on GitHub.