Utilizando una aplicación cliente Java, estoy consultando una cola SQS para mensajes. La cola tiene 12,000 mensajes como configuración para la prueba. Estoy usando openJDK con aws-java-sdk latest (software.amazon.awssdk 2.10.62) pom.xml se muestra más abajo.
El problema que estoy viendo es que, a pesar de establecer maxNumberOfMessages (10) , solo recibo 3. Entiendo que es un máximo, no una garantía de la cantidad de mensajes, sin embargo, no hay vacilación en la cantidad de mensajes devueltos. Siempre es 3.
Documentación de AWS: MaxNumberOfMessages El número máximo de mensajes a devolver. Amazon SQS nunca devuelve más mensajes que este valor (sin embargo, podrían devolverse menos mensajes). Valores válidos: de 1 a 10. Valor predeterminado: 1. Tipo: Entero Requerido: No
Consumir mensajes usando sondeo corto
Cuando consume mensajes de una cola utilizando sondeos cortos, Amazon SQS muestrea un subconjunto de sus servidores (en función de una distribución aleatoria ponderada) y devuelve mensajes solo de esos servidores. Por lo tanto, una solicitud de ReceiveMessage en particular podría no devolver todos sus mensajes. Sin embargo, si tiene menos de 1,000 mensajes en su cola, una solicitud posterior devolverá sus mensajes. Si sigue consumiendo de sus colas, Amazon SQS muestrea todos sus servidores y recibe todos sus mensajes.
Por lo tanto, hemos probado dos clientes en Java utilizando tanto el aws sdk anterior como el nuevo con los mismos resultados. Siempre solo 3 mensajes de vuelta.
Curiosamente, si en lugar de ejecutar la aplicación externamente (en mi poderoso escritorio) la ejecutas como AWS Lambda, obtienes 10 mensajes. Esta prueba lambda fue realizada usando JavaScript por un colega.
Entonces, la pregunta sigue siendo por qué solo recibimos 3 mensajes por solicitud y aparentemente dentro de lambda puede obtener 10.
Dado que hay un costo por solicitud, la distribución aleatoria ponderada se basa en el beneficio de Amazon =))
Método de prueba 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>
fuente
Respuestas:
Está claro que su objetivo aquí es reducir los costos, ya sea enviando menos solicitudes a SQS o forzando a SQS a entregar la cantidad máxima de mensajes disponibles.
Como ha indicado en su pregunta, SQS no tiene la obligación de entregar la cantidad máxima de mensajes disponibles. Sin embargo, hay algo sobre lo que me gustaría informarle, suponiendo que aún no lo sepa.
Sondeo largo
La Guía para desarrolladores del Servicio de cola simple de Amazon establece:
Los mensajes que envió a SQS pueden haberse almacenado en servidores separados. Como se indica en la documentación, solo se puede consultar un subconjunto de servidores si su cola está configurada para utilizar sondeos cortos . Supongo que tuvo mala suerte al invocar
receiveMessage
y solo3
fue devuelto cada vez.Si observamos los beneficios de las encuestas largas en la misma página de documentación, dice:
La segunda viñeta es muy importante aquí. Aunque no esté viendo respuestas vacías, puede haber más mensajes almacenados en servidores que no se están consultando. Si habilita el sondeo largo, es de esperar que vea un aumento en la cantidad de mensajes devueltos, suponiendo que haya más de 3 servidores en total.
Por lo tanto, mi sugerencia es habilitar un sondeo largo en su cola. Para hacerlo, consulte la página Configuración de sondeo largo .
Como DevilCode mencionó en su comentario a continuación, pudo resolver su problema mediante el uso de una cola FIFO en lugar de una cola estándar, y al permitir un sondeo largo en él.
fuente
Creo que esta es una pregunta similar. Como señaló Jacob, las encuestas largas parecen ser la solución al problema.
fuente
Sondeo largo:
fuente