À l'aide d'une application client Java, j'interroge une file d'attente SQS pour les messages. La file d'attente contient 12 000 messages comme configuration pour les tests. J'utilise openJDK avec aws-java-sdk dernier (software.amazon.awssdk 2.10.62) pom.xml est affiché plus bas.
Le problème que je vois est que, malgré la définition de maxNumberOfMessages (10), je n'en reçois que 3. Je comprends que ce n'est pas un maximum de garantie du nombre de messages, mais il n'y a pas de vacillement dans le nombre de messages renvoyés. C'est toujours 3.
Documentation AWS: MaxNumberOfMessages Nombre maximal de messages à renvoyer. Amazon SQS ne renvoie jamais plus de messages que cette valeur (cependant, moins de messages peuvent être renvoyés). Valeurs valides: 1 à 10. Valeur par défaut: 1. Type: entier requis: non
Consommation de messages à l'aide d'une interrogation courte
Lorsque vous consommez des messages d'une file d'attente à l'aide d'une interrogation courte, Amazon SQS échantillonne un sous-ensemble de ses serveurs (basé sur une distribution aléatoire pondérée) et renvoie des messages provenant uniquement de ces serveurs. Ainsi, une demande particulière de ReceiveMessage peut ne pas renvoyer tous vos messages. Cependant, si vous avez moins de 1 000 messages dans votre file d'attente, une demande ultérieure renverra vos messages. Si vous continuez à consommer à partir de vos files d'attente, Amazon SQS échantillonne tous ses serveurs et vous recevez tous vos messages.
Nous avons donc testé deux clients en java en utilisant à la fois l'ancien aws sdk et le plus récent avec les mêmes résultats. Toujours seulement 3 messages en retour.
Fait intéressant, si au lieu d'exécuter l'application en externe (sur mon puissant bureau), vous l'exécutez en tant que AWS Lambda, vous obtenez 10 messages. Ce test lambda a été effectué en utilisant JavaScript par un collègue.
La question reste donc de savoir pourquoi nous ne recevons que 3 messages par demande et apparemment, dans lambda, vous pouvez en obtenir 10.
Étant donné qu'il existe un coût par demande, la distribution aléatoire pondérée est basée sur le bénéfice d'Amazon =))
Méthode de test 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>
la source
Réponses:
Il est clair que votre objectif ici est de réduire les coûts, que ce soit en envoyant moins de demandes à SQS ou en forçant SQS à fournir le nombre maximal de messages disponibles.
Comme vous l'avez indiqué dans votre question, SQS n'a aucune obligation de fournir le nombre maximum de messages disponibles. Cependant, il y a quelque chose que j'aimerais vous informer, en supposant que vous n'en êtes pas déjà au courant.
Interrogation longue
Le Guide du développeur du service Simple Queue d'Amazon stipule:
Les messages que vous avez envoyés à SQS ont peut-être tous été stockés sur des serveurs distincts. Comme l'indique la documentation, seul un sous-ensemble de serveurs peut être interrogé si votre file d'attente est configurée pour utiliser l' interrogation courte . Je suppose que vous n'avez pas eu de chance lors de l'invocation
receiveMessage
et que vous avez3
été renvoyé à chaque fois.Si nous examinons les avantages de l' interrogation longue sur la même page de documentation, il indique:
La deuxième puce est très importante ici. Même si vous ne voyez pas de réponses vides, il peut exister plus de messages stockés sur des serveurs qui ne sont pas interrogés. Si vous activez l'interrogation longue, vous devriez, espérons-le, voir une augmentation de la quantité de messages retournés, en supposant qu'il y a plus de 3 serveurs au total.
Par conséquent, ma suggestion est d'activer l'interrogation longue sur votre file d'attente. Pour ce faire, consultez la page Configuration de l'interrogation longue .
Comme DevilCode l'a mentionné dans son commentaire ci-dessous, il a pu résoudre son problème en utilisant une file d'attente FIFO au lieu d'une file d'attente standard et en activant une longue interrogation sur celle-ci.
la source
Je pense que c'est un question.As similaire pointé par Jacob, à long polling semble être la solution à la question.
la source
Interrogation longue:
la source