SQS maxNumberOfMessages - PullRequest
       6

SQS maxNumberOfMessages

11 голосов
/ 13 февраля 2020

Использование клиентского приложения Java Я запрашиваю очередь SQS для сообщений. В очереди 12 000 сообщений в качестве настройки для тестирования. Я использую openJDK с aws - java -sdk последней (software.amazon.awssdk 2.10.62) pom. xml показан ниже.

Проблема, которую я вижу, заключается в том, что несмотря на настройки maxNumberOfMessages (10) Я только когда-либо получаю 3. Я понимаю, что это максимум, а не гарантия количества сообщений, однако колебания в количестве возвращаемых сообщений отсутствуют. Это всегда 3.

AWS Документация: MaxNumberOfMessages Максимальное количество сообщений для возврата. Amazon SQS никогда не возвращает больше сообщений, чем это значение (однако может быть возвращено меньше сообщений). Допустимые значения: от 1 до 10. По умолчанию: 1. Тип: Целочисленный Требуется: Нет

Использование сообщений с использованием короткого опроса

Когда вы используете сообщения из очереди с помощью короткого опроса Amazon SQS выбирает подмножество своих серверов (на основе взвешенного случайного распределения) и возвращает сообщения только от этих серверов. Таким образом, конкретный запрос ReceiveMessage может не вернуть все ваши сообщения. Однако, если в вашей очереди менее 1000 сообщений, последующий запрос вернет ваши сообщения. Если вы продолжаете использовать из своих очередей, Amazon SQS производит выборку всех своих серверов, и вы получаете все свои сообщения. .

Итак, мы протестировали двух клиентов в java, используя как старый aws sdk, так и новый с одинаковыми результатами. Всегда только 3 сообщения назад.

Интересно, что если вместо внешнего запуска приложения (на моем мощном рабочем столе) вы запускаете его как AWS Lambda, вы получаете 10 сообщений. Этот лямбда-тест был выполнен с использованием JavaScript коллегой.

Таким образом, остается вопрос, почему мы получаем 3 сообщения только на один запрос, и, по-видимому, в лямбде вы можете получить 10 *. прибыль =))

SQS Метод испытаний:

public void SQStart()
{
    AwsBasicCredentials awsCreds = AwsBasicCredentials.create("accessKeyID", "secretKeyID");
    AwsCredentialsProvider creds = StaticCredentialsProvider.create(awsCreds);
    SqsClient sqs = SqsClient.builder().credentialsProvider(creds).region(Region.EU_WEST_1).build();
    GetQueueUrlRequest getQueueRequest = GetQueueUrlRequest.builder()
            .queueName(QUEUE_NAME)
            .build();
    String queueUrl = sqs.getQueueUrl(getQueueRequest).queueUrl();

    for (int x =1; x < 100; x++) {
        ReceiveMessageRequest receiveMessageRequest = ReceiveMessageRequest.builder()
                .queueUrl(queueUrl)
                .maxNumberOfMessages(10)
                .build();


        List<Message> messages = sqs.receiveMessage(receiveMessageRequest).messages();
        if (messages.size() > 3 ) {
            System.out.println("YEY More than 3 Messages: "+ messages.size());
        }
    }
}

POM. XML:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>groupId</groupId>
    <artifactId>SQSTest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>2.10.62</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>

            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>sqs</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.9</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.10</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.720</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.6.1</version>
        </dependency>
    </dependencies>
</project>

Ответы [ 3 ]

9 голосов
/ 18 февраля 2020

Принимая во внимание, что цена за запрос является взвешенным случайным распределением, основанным на прибыли амазонки =))

Очевидно, что ваша цель здесь состоит в том, чтобы сократить расходы, будь то путем отправки меньше запросов в SQS или путем принуждения SQS доставлять максимальное количество доступных сообщений.

Как вы указали в своем вопросе, SQS не обязана доставлять максимальное количество доступных сообщений. Однако есть кое-что, о чем я хотел бы сообщить вам, предполагая, что вы еще не знаете об этом.


Длинный опрос

Руководство разработчика Служба простой очереди Amazon сообщает:

Процесс потребления сообщений из очереди зависит от того, используете ли вы короткий или длинный опрос. По умолчанию Amazon SQS использует короткий опрос , который запрашивает только часть своих серверов (на основе взвешенного случайного распределения), чтобы определить, доступны ли какие-либо сообщения для ответа. Вы можете использовать длительный опрос , чтобы сократить ваши расходы, позволяя вашим потребителям получать сообщения, как только они поступят в очередь.

Сообщения, отправленные вами в SQS, могут иметь все хранятся на отдельных серверах. Как указано в документации, может быть запрошено только подмножество серверов, если ваша очередь настроена на использование short polling . Я предполагаю, что вам не повезло при вызове receiveMessage и каждый раз возвращалось только 3.

Если мы посмотрим на преимущества длинного опроса 1031 * на той же странице документации, это состояния:

Длинный опрос предлагает следующие преимущества:

  • Устранить пустые ответы, позволяя Amazon SQS ждать, пока сообщение не станет доступным в очереди, прежде чем отправлять ответ. Если время ожидания соединения не истекло, ответ на запрос ReceiveMessage содержит хотя бы одно из доступных сообщений, вплоть до максимального количества сообщений, указанного в действии ReceiveMessage.

  • Устранить ложные пустые ответы запрашивая все, а не подмножество серверов Amazon SQS.

Второй пункт здесь очень важен. Даже если вы не видите пустых ответов, на серверах может храниться больше сообщений, которые не запрашиваются. Если вы включите длительный опрос, то, надеюсь, вы увидите увеличение количества возвращаемых сообщений, при условии, что общее количество серверов превышает 3.

Поэтому я предлагаю включить длинный опрос в вашей очереди. Для этого перейдите на страницу Настройка длинного опроса .


Как DevilCode упомянул в своем комментарии ниже, он смог решить свою проблему, используя очередь FIFO вместо стандартной и включающая длинный опрос по ней.

0 голосов
/ 24 февраля 2020

Длинный опрос:

        ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queueUrl)
              .withWaitTimeSeconds(10)     // long poll: wait 10 seconds, max is 20 seconds
              .withMaxNumberOfMessages(10);
0 голосов
/ 19 февраля 2020

Я думаю, , этот является аналогичным вопросом. Как указал Джейкоб, длительный опрос, кажется, является решением проблемы.

...