Mit einer Java-Client-Anwendung frage ich eine SQS-Warteschlange nach Nachrichten ab. Die Warteschlange enthält 12.000 Nachrichten als Testeinrichtung. Ich verwende openJDK mit der neuesten Version von aws-java-sdk (software.amazon.awssdk 2.10.62). Pom.xml wird weiter unten angezeigt.
Das Problem, das ich sehe, ist, dass ich trotz der Einstellung von maxNumberOfMessages (10) immer nur 3 bekomme. Ich verstehe, dass dies maximal keine Garantie für die Anzahl der Nachrichten ist, aber es gibt keinen Schwank in der Anzahl der zurückgegebenen Nachrichten. Es ist immer 3.
AWS-Dokumentation: MaxNumberOfMessages Die maximale Anzahl der zurückzugebenden Nachrichten. Amazon SQS gibt niemals mehr Nachrichten als diesen Wert zurück (es werden jedoch möglicherweise weniger Nachrichten zurückgegeben). Gültige Werte: 1 bis 10. Standard: 1. Typ: Ganzzahl Erforderlich: Nein
Nachrichten mit kurzen Abfragen verbrauchen
Wenn Sie Nachrichten aus einer Warteschlange mithilfe einer kurzen Abfrage verwenden, tastet Amazon SQS eine Teilmenge seiner Server ab (basierend auf einer gewichteten Zufallsverteilung) und gibt nur Nachrichten von diesen Servern zurück. Daher gibt eine bestimmte ReceiveMessage-Anforderung möglicherweise nicht alle Ihre Nachrichten zurück. Wenn sich jedoch weniger als 1.000 Nachrichten in Ihrer Warteschlange befinden, werden Ihre Nachrichten durch eine nachfolgende Anforderung zurückgegeben. Wenn Sie weiterhin in Ihren Warteschlangen arbeiten, testet Amazon SQS alle seine Server und Sie erhalten alle Ihre Nachrichten.
Daher haben wir zwei Clients in Java mit dem älteren aws sdk und dem neueren mit den gleichen Ergebnissen getestet. Immer nur 3 Nachrichten zurück.
Interessanterweise erhalten Sie 10 Nachrichten, wenn Sie die Anwendung nicht extern (auf meinem mächtigen Desktop) als AWS Lambda ausführen. Dieser Lambda-Test wurde von einem Kollegen mit JavaScript durchgeführt.
Es bleibt also die Frage, warum wir immer nur 3 Nachrichten pro Anfrage erhalten und scheinbar innerhalb von Lambda 10.
Da es Kosten pro Anfrage gibt, ist die gewichtete Zufallsverteilung basierend auf Amazon Profit =))
SQS-Testmethode:
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>
quelle
Antworten:
Es ist klar, dass Ihr Ziel hier darin besteht, die Kosten zu senken, indem Sie weniger Anforderungen an SQS senden oder SQS zwingen, die maximal verfügbare Anzahl von Nachrichten zuzustellen.
Wie Sie in Ihrer Frage angegeben haben, ist SQS nicht verpflichtet, die maximal verfügbare Anzahl von Nachrichten zuzustellen. Es gibt jedoch etwas, über das ich Sie informieren möchte, vorausgesetzt, Sie wissen es noch nicht.
Lange Umfrage
Im Entwicklerhandbuch des Simple Queue Service von Amazon heißt es:
Die Nachrichten, die Sie an SQS gesendet haben, wurden möglicherweise alle auf separaten Servern gespeichert. Wie in der Dokumentation angegeben, kann nur eine Teilmenge von Servern abgefragt werden, wenn Ihre Warteschlange auf kurze Abfragen eingestellt ist . Ich vermute, dass Sie beim Aufrufen Pech hatten
receiveMessage
und nur3
jedes Mal zurückgegeben wurden.Wenn wir uns die Vorteile einer langen Abfrage auf derselben Dokumentationsseite ansehen , heißt es:
Die zweite Kugel ist hier sehr wichtig. Auch wenn Sie keine leeren Antworten sehen, sind möglicherweise mehr Nachrichten auf Servern gespeichert, die nicht abgefragt werden. Wenn Sie lange Abfragen aktivieren, sollte hoffentlich die Anzahl der zurückgegebenen Nachrichten zunehmen, vorausgesetzt, es gibt insgesamt mehr als 3 Server.
Daher ist mein Vorschlag, lange Abfragen in Ihrer Warteschlange zu aktivieren. Informationen hierzu finden Sie auf der Seite Einrichten langer Abfragen .
Wie DevilCode in seinem Kommentar unten erwähnte , konnte er sein Problem beheben, indem er eine FIFO-Warteschlange anstelle einer Standardwarteschlange verwendete und eine lange Abfrage darauf ermöglichte.
quelle
Ich denke, dies ist eine ähnliche Frage. Wie Jacob betonte, scheinen lange Umfragen die Lösung für das Problem zu sein.
quelle
Lange Umfrage:
quelle