SQS maxNumberOfMessages


11

Bir Java istemci uygulaması kullanarak mesajlar için bir SQS kuyruğunu sorguluyorum. Kuyrukta test için kurulum olarak 12.000 mesaj var. Aws-java-sdk ile openJDK kullanıyorum (software.amazon.awssdk 2.10.62) pom.xml daha aşağıda gösterilmiştir.

Gördüğüm sorun, maxNumberOfMessages (10) ayarlamasına rağmen ben sadece hiç 3 olsun. Ben mesajların sayısı bir maksimum garanti değil ancak dönen mesajların sayısı bir tereddüt olduğunu anlıyorum. Her zaman 3'tür.

AWS Belgeleri: MaxNumberOfMessages Döndürülecek maksimum ileti sayısı. Amazon SQS hiçbir zaman bu değerden daha fazla ileti döndürmez (ancak daha az ileti döndürülebilir). Geçerli değerler: 1 ila 10. Varsayılan: 1. Tür: Tamsayı Gerekli: Hayır

Kısa Çağırma Kullanarak Mesajları Kullanma

Kısa yoklama kullanarak bir kuyruktan ileti tükettiğinizde, Amazon SQS sunucularının bir alt kümesini (ağırlıklı rasgele dağıtıma dayalı olarak) örnekler ve yalnızca bu sunuculardan gelen iletileri döndürür. Bu nedenle, belirli bir ReceiveMessage isteği tüm iletilerinizi döndürmeyebilir. Ancak, kuyruğunuzda 1.000'den az ileti varsa, sonraki bir istek iletilerinizi döndürür. Kuyruklarınızdan tüketmeye devam ederseniz, Amazon SQS tüm sunucularını örnekler ve tüm iletilerinizi alırsınız.

Java'da iki istemciyi hem eski aws sdk hem de daha yeni olanı kullanarak aynı sonuçlarla test ettik. Her zaman sadece 3 mesaj geri.

İlginçtir, uygulamayı harici olarak çalıştırmak yerine (güçlü masaüstümde) bir AWS Lambda olarak çalıştırırsanız 10 mesaj alırsınız. Bu lambda testi bir iş arkadaşı tarafından JavaScript kullanılarak yapıldı.

Yani soru hala neden sadece istek başına 3 mesaj alıyoruz ve görünüşe göre lambda içinde 10 alabilirsiniz.

Talep başına maliyet olduğu göz önüne alındığında, amazon kârına dayalı ağırlıklı rastgele dağılım =))

SQS Test Yöntemi:

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>

Sadece bir düşünce, ama AWS'de kuyruğun yapılandırmasını kontrol ettiniz mi? Java istemcisinde ayarladığınızdan öncelik alabilecek bir maxNumberOfMessages özelliği ile ayarlanmış olabilir? Javascript
lambda'da

Yanıtlar:


9

Talep başına maliyet olduğu göz önüne alındığında, amazon kârına dayalı ağırlıklı rastgele dağılım =))

Buradaki hedefinizin, SQS'ye daha az istek göndererek veya SQS'yi kullanılabilir maksimum ileti sayısını iletmeye zorlayarak maliyetleri azaltmak olduğu açıktır.

Sorunuzda belirttiğiniz gibi, SQS'nin mümkün olan en fazla ileti iletme yükümlülüğü yoktur. Ancak, zaten farkında olmadığınızı varsayarak, sizi bilgilendirmek istediğim bir şey var.


Uzun Oylama

Geliştirici Kılavuzu Amazon Simple sırası hizmeti devletlerin:

Bir kuyruktan ileti tüketme işlemi, kısa veya uzun yoklama kullanıp kullanmadığınıza bağlıdır. Varsayılan olarak, Amazon SQS, yanıt için herhangi bir iletinin bulunup bulunmadığını belirlemek için sunucularının yalnızca bir alt kümesini (ağırlıklı rastgele dağıtıma dayalı olarak) sorgulayan kısa yoklama kullanır . Maliyetlerinizi azaltmak için uzun oylama kullanabilirsiniz ve tüketicilerin sıraya ulaşır ulaşmaz mesaj almasını sağlayabilirsiniz .

SQS'ye gönderdiğiniz iletilerin tümü ayrı sunucularda depolanmış olabilir. Belgelerin belirttiği gibi, sıranız kısa yoklama kullanacak şekilde ayarlanmışsa, yalnızca bir sunucu alt kümesi sorgulanabilir . Benim tahminim, çağrılırken şanssız olduğun receiveMessageve 3her seferinde geri döndüğün.

Aynı dokümantasyon sayfasında uzun oylamanın avantajlarına baktığımızda şunu belirtiyor:

Uzun yoklama aşağıdaki faydaları sağlar:

  • Yanıt göndermeden önce Amazon SQS'nin bir kuyrukta mesaj bulunana kadar beklemesine izin vererek boş yanıtları ortadan kaldırın. Bağlantı zaman aşımına uğramadıkça, ReceiveMessage isteğine verilen yanıt, ReceiveMessage eyleminde belirtilen maksimum mesaj sayısına kadar mevcut mesajlardan en az birini içerir.

  • Amazon SQS sunucularının bir alt kümesi yerine tümünü sorgulayarak yanlış boş yanıtları ortadan kaldırın.

İkinci mermi burada çok önemli. Boş yanıtlar görmemenize rağmen, sunucularda depolanmayan başka iletiler de olabilir. Uzun yoklamayı etkinleştirirseniz, toplamda 3'ten fazla sunucu olduğu varsayılarak, döndürülen ileti miktarında bir artış görmeniz gerekir.

Bu nedenle, önerim kuyruğunuzda uzun yoklama sağlamaktır. Bunu yapmak için Uzun Çağırma Ayarlama sayfasına bakın.


DevilCode onun belirtildiği gibi açıklama aşağıda, bir FIFO kuyruğu yerine standart bir kuyruk kullanarak ve üzerinde uzun yoklama etkinleştirerek onun sorunu çözmek başardı.


Aynı şeyi uzun yoklama ile test ettik ve aynı sonucu aldık. Kuyrukta 12.000 mesaj vardı ve yoklama 20 saniyeye ayarlandı. Hala sadece üç mesaj alıyoruz. Uzun ve kısa yoklamalı üç mesaj alırsak, uzun yoklamalı kullanmanın bir nedeni yoktur (kuyruk mesajlarda beklemek boşsa hariç). Maalesef maliyeti ve hızı dengelemeye çalışıyoruz. Maalesef kullanabileceğimiz yalnızca sınırlı sayıda okuma parçamız var (donanımdan dolayı), bu yüzden çağrı başına aşağı çekebileceğimiz mesaj sayısı, onu ne kadar hızlı işleyebileceğimiz konusunda sınırlayıcı bir faktördür.
DevilCode

@DevilCode Uzun yoklama etkin durumdayken sorununuzu en sonunda yeniden oluşturamadım. Sıranız standart bir sıra mı yoksa bir FIFO sırası mı? Ayrıca, sonunda değişiklik yapıp yapamayacaklarını görmek için AWS ile bir destek bileti açmak isteyebilirsiniz.
Jacob G.20

Standart bir kuyruktur. Kodunuzu yerel olarak mı çalıştırdınız ve Java mı kullanıyordunuz?
DevilCode

@DevilCode Bir FIFO kuyruğu kullanarak test ettim. Ve evet, SQS kuyruğumdan mesaj almak için AWS Java SDK v2 kullanıyorum. Kodum AWS Lambda işlevi içinde çalışmıyor.
Jacob G.20

1
Tamam FIFO sırasını test ettikten sonra standart mesajda olduğu gibi sadece üç tane aldığımız 10 mesaj alıyoruz. Şimdi sonuçlandırabileceğim tek şey, belgelerin standart sıraya değil, FIFO sırasına atıfta bulunmasıdır.
DevilCode

0

Sanırım bu da benzer bir soru. Yakup'un işaret ettiği gibi, uzun oylama bu sorunun çözümü gibi görünüyor.


0

Uzun oylama:

        ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queueUrl)
              .withWaitTimeSeconds(10)     // long poll: wait 10 seconds, max is 20 seconds
              .withMaxNumberOfMessages(10);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.