SQS maxNumberOfMessages


11

Використовуючи клієнтську програму Java, я запитую чергу SQS для повідомлень. У черзі 12000 повідомлень як налаштування для тестування. Я використовую 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>

Просто думка, але ви перевірили конфігурацію самої черги на AWS? Можливо, це було налаштування з властивістю maxNumberOfMessages, яка могла б отримати пріоритет над тією, яку ви встановили у клієнті Java? Оскільки це працює у лямбда на JavaScript, це було б дивно, але все ж варто зняти :)
niekname

Відповіді:


9

З огляду на наявність вартості на запит - зважений випадковий розподіл на основі прибутку амазонки =))

Зрозуміло, що ваша мета полягає в тому, щоб знизити витрати, будь то шляхом надсилання меншої кількості запитів до SQS або змушення SQS доставити максимальну кількість доступних повідомлень.

Як ви сказали у своєму запитанні, SQS не зобов’язаний доставляти максимальну кількість доступних повідомлень. Однак є щось, про що я хотів би повідомити вас, припускаючи, що ви цього ще не знаєте.


Довгі опитування

Керівництво розробника з простих станів черзі служби Амазонки:

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

Повідомлення, які ви надіслали до SQS, можливо, всі були збережені на окремих серверах. Як зазначено в документації, запит може бути лише підмножиною серверів, якщо ваша черга встановлена ​​для короткого опитування . Я здогадуюсь, що вам не пощастило під час виклику receiveMessageі лише 3щоразу поверталися.

Якщо ми подивимося на переваги тривалого опитування на одній сторінці документації, у ньому зазначено:

Тривале опитування пропонує такі переваги:

  • Усуньте порожні відповіді, дозволяючи Amazon SQS чекати, поки повідомлення з’явиться у черзі, перш ніж надсилати відповідь. Якщо не вичерпано з'єднання, відповідь на запит ReceiveMessage містить щонайменше одне з доступних повідомлень, до максимальної кількості повідомлень, зазначених у дії ReceiveMessage.

  • Усуньте помилкові порожні відповіді, запитуючи всіх - а не підмножину - серверів Amazon SQS.

Тут дуже важлива друга куля. Незважаючи на те, що ви не бачите порожніх відповідей, на серверах може зберігатися більше повідомлень, які не запитуються. Якщо ви ввімкнете тривале опитування, то, сподіваємось, ви зможете збільшити кількість повернених повідомлень, якщо припустити, що усього понад 3 сервери.

Тому я пропоную включити довгі опитування у вашій черзі. Для цього див . Сторінку Налаштування тривалого опитування .


Як згадував DevilCode у своєму коментарі нижче, він зміг вирішити свою проблему, використовуючи чергу FIFO замість стандартної черги та шляхом довгого опитування на ній.


Ми перевірили те ж саме, тривалим опитуванням і отримали той же результат. У нас було 12 000 повідомлень у черзі, а опитування було встановлено на 20 секунд. У нас залишається лише три повідомлення. Якщо ми отримуємо три повідомлення з довгим і коротким опитуванням, немає причин використовувати довге опитування (за винятком випадків, коли черга порожня, очікуючи на повідомлення). На жаль, ми намагаємось збалансувати вартість та швидкість. На жаль, у нас є лише обмежені теми для читання, які ми можемо використовувати (за рахунок апаратного забезпечення), тому кількість повідомлень, які ми можемо знизити за один виклик, є обмежуючим фактором швидкості їх обробки.
DevilCode

@DevilCode Мені не вдалося відтворити вашу проблему в кінцевому підсумку при ввімкненому тривалому опитуванні. Чи є ваша черга стандартною чергою чи чергою FIFO? Ви також можете відкрити службу підтримки з AWS, щоб побачити, чи можуть вони внести зміни в кінці.
Яків Г.

Це стандартна черга. Ви запускали свій код локально і використовували нас Java?
DevilCode

@DevilCode Я перевірив це за допомогою черги FIFO. І так, я використовую AWS Java SDK v2 для отримання повідомлень з моєї черги SQS. Мій код не працює в межах функції AWS Lambda.
Яків Г.

1
ОК Перевірена черга FIFO, і ми отримуємо 10 повідомлень, де, як і у стандартній черзі, ми отримуємо лише три. Зараз я можу зробити висновок, що документація стосується черги FIFO, а не стандартної черги.
DevilCode

0

Я думаю, що це подібне питання. Як зазначав Яків, тривале опитування, здається, є вирішенням цього питання.


0

Тривале опитування:

        ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queueUrl)
              .withWaitTimeSeconds(10)     // long poll: wait 10 seconds, max is 20 seconds
              .withMaxNumberOfMessages(10);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.