Usando um aplicativo cliente Java, estou consultando uma fila SQS para obter mensagens. A fila possui 12.000 mensagens como configuração para teste. Estou usando o openJDK com o aws-java-sdk mais recente (software.amazon.awssdk 2.10.62) pom.xml é mostrado mais abaixo.
O problema que estou vendo é que, apesar de definir maxNumberOfMessages (10) , apenas recebo 3. Entendo que é uma garantia máxima do número de mensagens, no entanto, não há oscilação no número de mensagens retornadas. É sempre 3.
Documentação da AWS: MaxNumberOfMessages O número máximo de mensagens a serem retornadas. O Amazon SQS nunca retorna mais mensagens que esse valor (no entanto, menos mensagens podem ser retornadas). Valores válidos: 1 a 10. Padrão: 1. Tipo: Inteiro Necessário: Não
Consumindo mensagens usando sondagens curtas
Quando você consome mensagens de uma fila usando sondagens curtas, o Amazon SQS mostra um subconjunto de seus servidores (com base em uma distribuição aleatória ponderada) e retorna mensagens apenas desses servidores. Portanto, uma solicitação ReceiveMessage específica pode não retornar todas as suas mensagens. No entanto, se você tiver menos de 1.000 mensagens em sua fila, uma solicitação subsequente retornará suas mensagens. Se você continuar consumindo em suas filas, o Amazon SQS fará uma amostra de todos os seus servidores e você receberá todas as suas mensagens.
Portanto, testamos dois clientes em java usando o aws sdk mais antigo e o mais novo com os mesmos resultados. Sempre apenas 3 mensagens de volta.
O interessante é que, em vez de executar o aplicativo externamente (na minha poderosa área de trabalho), você o executa como um AWS Lambda, recebe 10 mensagens. Este teste lambda foi realizado usando JavaScript por um colega.
Portanto, a questão permanece: por que só recebemos 3 mensagens por solicitação e, aparentemente, no lambda, você pode obter 10.
Dado que existe um custo por solicitação, a distribuição aleatória ponderada é baseada no lucro da amazon =))
Método de Teste 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>
fonte
Respostas:
É claro que seu objetivo aqui é reduzir custos, enviando menos solicitações ao SQS ou forçando o SQS a entregar a quantidade máxima de mensagens disponíveis.
Como você afirmou em sua pergunta, o SQS não tem obrigação de entregar a quantidade máxima de mensagens disponíveis. No entanto, há algo que eu gostaria de informar, supondo que você ainda não esteja ciente disso.
Votação longa
O Guia do desenvolvedor do Serviço de fila simples da Amazon declara:
As mensagens enviadas para o SQS podem ter sido armazenadas em servidores separados. Como a documentação declara, apenas um subconjunto de servidores pode ser consultado se sua fila estiver configurada para usar uma pesquisa curta . Meu palpite é que você teve azar ao invocar
receiveMessage
e só3
foi devolvido todas as vezes.Se olharmos para os benefícios da pesquisa longa na mesma página de documentação, ele afirma:
A segunda bala é muito importante aqui. Mesmo que você não esteja vendo respostas vazias, pode haver mais mensagens armazenadas em servidores que não estão sendo consultados. Se você ativar a sondagem longa, esperamos ver um aumento na quantidade de mensagens retornadas, supondo que haja mais de 3 servidores no total.
Portanto, minha sugestão é ativar a pesquisa longa na sua fila. Para fazer isso, consulte a página Configuração da pesquisa longa .
Como o DevilCode mencionou em seu comentário abaixo, ele foi capaz de resolver seu problema usando uma fila FIFO em vez de uma fila padrão e permitindo uma pesquisa longa.
fonte
Acho que essa é uma pergunta semelhante. Como apontado por Jacob, pesquisas longas parecem ser a solução para o problema.
fonte
Votação longa:
fonte