SQS maxNumberOfMessages


11

Sử dụng một ứng dụng máy khách Java Tôi đang truy vấn hàng đợi SQS cho các tin nhắn. Hàng đợi có 12.000 tin nhắn khi thiết lập để thử nghiệm. Tôi đang sử dụng openJDK với aws-java-sdk mới nhất (software.amazon.awssdk 2.10.62) pom.xml được hiển thị thêm.

Vấn đề tôi đang gặp phải là mặc dù đã cài đặt maxNumberOfMessages (10) tôi chỉ nhận được 3. Tôi hiểu rằng đó không phải là sự đảm bảo tối đa về số lượng tin nhắn tuy nhiên không có sự thay đổi nào về số lượng tin nhắn được trả về. Nó luôn luôn là 3.

Tài liệu AWS: MaxNumberOfMessages Số lượng tin nhắn tối đa sẽ trả về. Amazon SQS không bao giờ trả lại nhiều tin nhắn hơn giá trị này (tuy nhiên, có thể trả lại ít tin nhắn hơn). Giá trị hợp lệ: 1 đến 10. Mặc định: 1. Loại: Số nguyên bắt buộc: Không

Tin nhắn tiêu dùng sử dụng bỏ phiếu ngắn

Khi bạn tiêu thụ thư từ hàng đợi bằng cách bỏ phiếu ngắn, Amazon SQS lấy mẫu một tập hợp con các máy chủ của nó (dựa trên phân phối ngẫu nhiên có trọng số) và trả về tin nhắn từ chỉ những máy chủ đó. Do đó, một yêu cầu receiveMessage cụ thể có thể không trả về tất cả các tin nhắn của bạn. Tuy nhiên, nếu bạn có ít hơn 1.000 tin nhắn trong hàng đợi của mình, một yêu cầu tiếp theo sẽ trả về tin nhắn của bạn. Nếu bạn tiếp tục tiêu thụ từ hàng đợi của mình, Amazon SQS sẽ lấy mẫu tất cả các máy chủ của nó và bạn sẽ nhận được tất cả các tin nhắn của mình.

Vì vậy, chúng tôi đã thử nghiệm hai máy khách trong java bằng cách sử dụng cả sdk aws cũ và máy khách mới hơn có cùng kết quả. Luôn chỉ có 3 tin nhắn trở lại.

Thật thú vị nếu thay vì chạy ứng dụng bên ngoài (trên máy tính để bàn hùng mạnh của tôi), bạn chạy nó dưới dạng AWS Lambda, bạn nhận được 10 tin nhắn. Thử nghiệm lambda này được thực hiện bằng JavaScript bởi một đồng nghiệp.

Vì vậy, câu hỏi vẫn là tại sao chúng ta chỉ nhận được 3 tin nhắn cho mỗi yêu cầu và dường như trong lambda bạn có thể nhận được 10 tin nhắn.

Cho rằng có một chi phí cho mỗi yêu cầu là phân phối ngẫu nhiên có trọng số dựa trên lợi nhuận của amazon =))

Phương pháp kiểm tra 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>

Chỉ là một suy nghĩ, nhưng bạn đã kiểm tra cấu hình của hàng đợi trên AWS chưa? Có lẽ nó đã được thiết lập với thuộc tính maxNumberOfMessages có thể được ưu tiên hơn thuộc tính bạn đặt trong máy khách java? Vì nó hoạt động trong lambda javascript, điều này sẽ kỳ lạ, nhưng vẫn đáng để thử :)
niekname

Câu trả lời:


9

Cho rằng có một chi phí cho mỗi yêu cầu là phân phối ngẫu nhiên có trọng số dựa trên lợi nhuận của amazon =))

Rõ ràng rằng mục tiêu của bạn ở đây là giảm chi phí, cho dù đó là bằng cách gửi ít yêu cầu hơn tới SQS hoặc bằng cách buộc SQS gửi số lượng tin nhắn tối đa có sẵn.

Như bạn đã nêu trong câu hỏi của mình, SQS không có nghĩa vụ cung cấp số lượng tin nhắn tối đa có sẵn. Tuy nhiên, có một vài điều tôi muốn thông báo cho bạn, giả sử bạn chưa biết về nó.


Bỏ phiếu dài

Các nhà phát triển Hướng dẫn của Simple Queue Service tiểu bang của Amazon:

Quá trình tiêu thụ thư từ hàng đợi phụ thuộc vào việc bạn sử dụng bỏ phiếu ngắn hay dài. Theo mặc định, Amazon SQS sử dụng bỏ phiếu ngắn , chỉ truy vấn một tập hợp con các máy chủ của nó (dựa trên phân phối ngẫu nhiên có trọng số) để xác định xem có bất kỳ thông báo nào có sẵn cho phản hồi hay không. Bạn có thể sử dụng bỏ phiếu dài để giảm chi phí trong khi cho phép người tiêu dùng của bạn nhận được tin nhắn ngay khi họ đến hàng đợi.

Các tin nhắn mà bạn đã gửi tới SQS có thể đã được lưu trữ trên các máy chủ riêng biệt. Như tài liệu nêu, chỉ một tập hợp con của máy chủ có thể được truy vấn nếu hàng đợi của bạn được đặt để sử dụng bỏ phiếu ngắn . Tôi đoán là bạn đã không may mắn khi gọi receiveMessagevà chỉ 3được trả lại mỗi lần.

Nếu chúng ta xem xét lợi ích của việc bỏ phiếu dài trên cùng một trang tài liệu, nó nói:

Bỏ phiếu dài cung cấp các lợi ích sau:

  • Loại bỏ các phản hồi trống bằng cách cho phép Amazon SQS đợi cho đến khi có tin nhắn trong hàng đợi trước khi gửi phản hồi. Trừ khi hết thời gian kết nối, phản hồi cho yêu cầu receiveMessage chứa ít nhất một trong số các tin nhắn khả dụng, tối đa số lượng tin nhắn tối đa được chỉ định trong hành động receiveMessage.

  • Loại bỏ các phản hồi trống bằng cách truy vấn tất cả các đơn vị thay vì một tập hợp con của các máy chủ SQS của Amazon.

Viên đạn thứ hai rất quan trọng ở đây. Mặc dù bạn không thấy phản hồi trống, có thể tồn tại nhiều thư được lưu trữ trên các máy chủ không được truy vấn. Nếu bạn kích hoạt bỏ phiếu dài, bạn hy vọng sẽ thấy số lượng tin nhắn được trả về tăng lên, giả sử có tổng cộng hơn 3 máy chủ.

Do đó, đề xuất của tôi là cho phép bỏ phiếu dài trên hàng đợi của bạn. Để thực hiện việc này, hãy xem trang Thiết lập Bỏ phiếu dài .


Như DevilCode đã đề cập trong bình luận của mình bên dưới, anh ta có thể giải quyết vấn đề của mình bằng cách sử dụng hàng đợi FIFO thay vì hàng đợi tiêu chuẩn và bằng cách cho phép bỏ phiếu dài trên đó.


Chúng tôi đã thử nghiệm tương tự với bỏ phiếu dài và nhận được kết quả tương tự. Chúng tôi đã có 12.000 tin nhắn trong hàng đợi và cuộc bỏ phiếu được đặt thành 20 giây. Chúng tôi vẫn chỉ nhận được ba tin nhắn. Nếu chúng tôi nhận được ba tin nhắn dài và bỏ phiếu ngắn thì không có lý do gì để sử dụng bỏ phiếu dài (trừ khi hàng đợi trống trong tin nhắn). Thật không may, chúng tôi đang cố gắng cân bằng giữa chi phí và tốc độ. Thật không may, chúng tôi chỉ giới hạn các luồng đọc mà chúng tôi có thể sử dụng (do phần cứng) nên số lượng tin nhắn chúng tôi có thể kéo xuống trên mỗi cuộc gọi là một yếu tố hạn chế trong việc chúng tôi có thể xử lý nhanh như thế nào.
DevilCode

@DevilCode Tôi không thể tái tạo vấn đề của bạn khi kết thúc bỏ phiếu dài. Hàng đợi của bạn là hàng đợi tiêu chuẩn hay hàng đợi FIFO? Bạn cũng có thể muốn mở một vé hỗ trợ với AWS để xem liệu họ có thể thay đổi kết thúc hay không.
Jacob G.

Đó là một hàng đợi tiêu chuẩn. Bạn đã chạy mã của mình cục bộ và chúng tôi có sử dụng Java không?
DevilCode

@DevilCode Tôi đã kiểm tra nó bằng cách sử dụng hàng đợi FIFO. Và vâng, tôi đang sử dụng AWS Java SDK v2 để nhận tin nhắn từ hàng đợi SQS của tôi. Mã của tôi không chạy trong chức năng AWS Lambda.
Jacob G.

1
OK Đã kiểm tra hàng đợi FIFO và chúng tôi nhận được 10 tin nhắn trong đó như trong hàng đợi tiêu chuẩn, chúng tôi chỉ nhận được ba tin nhắn. Tất cả những gì tôi có thể kết luận bây giờ là tài liệu đề cập đến hàng đợi FIFO chứ không phải hàng đợi tiêu chuẩn.
DevilCode

0

Tôi nghĩ rằng đây là một câu hỏi tương tự. Được Jacob chỉ ra, bỏ phiếu dài dường như là giải pháp cho vấn đề này.


0

Bỏ phiếu dài:

        ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queueUrl)
              .withWaitTimeSeconds(10)     // long poll: wait 10 seconds, max is 20 seconds
              .withMaxNumberOfMessages(10);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.