[
https://issues.apache.org/jira/browse/CAMEL-26649?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-26649:
--------------------------------
Fix Version/s: 4.24.0
> camel-aws2-sqs - consumer receives one message per ReceiveMessage and deletes
> messages one by one by default
> ------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26649
> URL: https://issues.apache.org/jira/browse/CAMEL-26649
> Project: Camel
> Issue Type: Improvement
> Components: camel-aws2-sqs
> Affects Versions: 4.18.5, 4.22.2, 4.23.0
> Reporter: Federico Mariani
> Assignee: Federico Mariani
> Priority: Major
> Fix For: 4.24.0
>
>
> h3. Problem
> By default the {{aws2-sqs}} consumer asks SQS for one message per
> {{ReceiveMessage}} call, and it deletes every routed message with its own
> synchronous {{DeleteMessage}} call. Line numbers are on main (7978db3d42dd):
> *
> {{components/camel-aws/camel-aws2-sqs/src/main/java/org/apache/camel/component/aws2/sqs/Sqs2Endpoint.java}}
> line 104: {{maxMessagesPerPoll}} is an {{int}} with no default (0). Its
> javadoc (line 437) and the catalog say "Is default unlimited".
> * {{Sqs2Consumer.java}} line 693: {{Math.max(1,
> endpoint.getMaxMessagesPerPoll())}}, so 0 or a negative value means 1, and
> line 797 sends {{maxNumberOfMessages(1)}}. Values above 10 are already split
> into receives of at most 10 (CAMEL-21031).
> * {{Sqs2Configuration.java}} line 78: {{waitTimeSeconds}} has no default, so
> no {{WaitTimeSeconds}} is sent. The queue attribute
> {{ReceiveMessageWaitTimeSeconds}} then applies, which means short polling
> unless the queue sets it above 0.
> * {{Sqs2Consumer.java}} lines 263-270: {{processCommit}} calls
> {{deleteMessage}} once per exchange. The visibility extender already batches,
> with {{ChangeMessageVisibilityBatch}} (lines 524-544).
> With the defaults ({{delay=500}}, {{greedy=false}}) a consumer thread gets at
> most about 2 messages per second, at 2 billable requests per message. Yet SQS
> returns up to 10 messages per receive (AWS SDK 2.57.7 service model: "Valid
> values: 1 to 10. Default: 1."), and {{DeleteMessageBatch}} takes up to 10
> entries. The effective default has always been 1: before CAMEL-21031 the
> consumer did not send {{MaxNumberOfMessages}} at all, and the SQS default is
> 1. The words "default unlimited" come from the generic batch consumer and are
> wrong here.
> h3. How to reproduce
> These numbers are measured. The route is
> {{from("aws2-sqs://MyQueue?amazonSQSClient=#client&initialDelay=0" +
> options)}}, run on the module's {{AmazonSQSClientMock}} with 30 messages
> queued; it records every request and stops once N messages have been routed:
> ||options||messages routed||ReceiveMessage
> calls||MaxNumberOfMessages||exchanges per poll||DeleteMessage calls||
> |(defaults)|5|5|1|1|5, in 2.1 s|
> |{{maxMessagesPerPoll=0}} or {{-1}}|2|2|1|1|2|
> |{{greedy=true}}|30|31|1|1|30|
> |{{concurrentConsumers=3}}|6|6|1|1|6|
> |{{maxMessagesPerPoll=10}} (control)|30|3|10|10|30|
> |{{maxMessagesPerPoll=25}} (control)|25|3|10, 10, 5|25|25|
> No request carried {{WaitTimeSeconds}}, and {{DeleteMessageBatch}} was never
> called. {{greedy}} only removes the delay between polls, and
> {{concurrentConsumers}} only adds threads; neither changes the batch size.
> h3. Proposed change
> # Default {{maxMessagesPerPoll}} to 10. Fix the javadoc and catalog text: 0
> or a negative value means one message per receive, and above 10 the consumer
> sends several receives of at most 10.
> # Add an opt-in option that collects the receipt handles of completed
> exchanges and sends {{DeleteMessageBatch}} on the existing sync
> {{SqsClient}}. It flushes at 10 handles, at the end of the poll and on
> stop/suspend, and reports failed entries one by one as today. The SDK's
> {{SqsAsyncBatchManager}} does not fit: it needs an {{SqsAsyncClient}}
> ({{Builder.client(SqsAsyncClient)}}), and {{batchManager()}} is generated
> only on the async client.
> # Optionally, document long polling ({{waitTimeSeconds}}), or default to it.
> With short polling SQS samples only some of its servers and can return fewer
> than 10 messages while more are queued. So (1) alone gives up to 10x fewer
> receives, not a guaranteed 10x; long polling is what makes full batches
> reliable.
> Risks:
> * Visibility timeout vs. a batch of 10. The 10 messages of a poll are routed
> one after the other, and the visibility timeout of each one starts at the
> receive. With a slow synchronous route and without
> {{extendMessageVisibility}}, the last messages of a batch can become visible
> again and be delivered twice. With {{extendMessageVisibility=true}} the whole
> batch is extended from the receive since CAMEL-25700 (4.24.0).
> * Deferred deletes widen the window in which a crash leaves already processed
> messages to be delivered again. The extender must keep extending a message
> until its delete is flushed.
> Estimates (not measured against AWS): with full batches, (1) and (2) bring
> billable requests from 2 down to about 0.2 per message.
> h3. Impact / upgrade
> * (1) changes a default, so it needs a {{camel-aws2-sqs}} entry in the 4.24
> upgrade guide. The entry should say that each poll now takes up to 10
> messages, repeat the visibility-timeout point above, and give
> {{maxMessagesPerPoll=1}} to keep the old behaviour.
> * (2) is opt-in and has no upgrade impact.
> * camel-kamelets also needs a change: the {{aws-sqs-source}} Kamelet
> (camel-kamelets 4.23.0) declares {{maxMessagesPerPoll}} with {{default: 1}}
> and {{maximum: 10}} and always passes it. Kamelet users therefore keep one
> message per receive whatever the component default is, and the maximum of 10
> is out of date since CAMEL-21031 started splitting larger values.
> * The same code is on camel-4.18.5, camel-4.22.2 and camel-4.23.0.
> h3. Related
> * CAMEL-21031 (1432192c6ca3) added polling of more than 10 messages and
> {{Math.max(1, ...)}}; its description notes that the consumer receives only 1
> message by default.
> * CAMEL-7590 (2014, resolved as Information Provided) asked for batch
> write/delete through the SDK v1 buffered async client.
> * CAMEL-19656 batched the visibility extender; CAMEL-25700 extends the whole
> batch with {{extendMessageVisibility}}.
> * CAMEL-9592 documented {{maxMessagesPerPoll}} together with
> {{concurrentConsumers}}.
> _Claude Code on behalf of Federico Mariani_
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)