activemq-artemis/docs/user-manual/send-guarantees.adoc

75 lines
6.9 KiB
Plaintext
Raw Normal View History

ARTEMIS-4383 migrate user docs to AsciiDoc Markdown, which is currently used for user-facing documentation, is good for a lot of things. However, it's not great for the kind of complex documentation we have and our need to produce both multi-page HTML and single-page PDF output via Maven. Markdown lacks features which would make the documentation easier to read, easier to navigate, and just look better overall. The current tool-chain uses honkit and a tool called Calibre. Honkit is written in TypeScript and is installed via NPM. Calibre is a native tool so it must be installed via an OS-specific package manager. All this complexity makes building, releasing, uploading, etc. a pain. AsciiDoc is relatively simple like Markdown, but it has more features for presentation and navigation not to mention Java-based Maven tooling to generate both HTML and PDF. Migrating will improve both the appearance of the documentation as well as the processes to generate and upload it. This commit contains the following changes: - Convert all the Markdown for the User Manual, Migration Guide, and Hacking guide to AsciiDoc via kramdown [1]. - Update the `artemis-website` build to use AsciiDoctor Maven tooling. - Update `RELEASING.md` with simplified instructions. - Update Hacking Guide with simplified instructions. - Use AsciiDoc link syntax in Artemis Maven doc plugin. - Drop EPUB & MOBI docs for User Manual as well as PDF for the Hacking Guide. All docs will be HTML only except for the User Manual which will have PDF. - Move all docs up out of their respective "en" directory. This was a hold-over from when we had docs in different languages. - Migration & Hacking Guides are now single-page HTML since they are relatively short. - Refactor README.md to simplify and remove redundant content. Benefits of the change: - Much simplified tooling. No more NPM packages or native tools. - Auto-generated table of contents for every chapter. - Auto-generated anchor links for every sub-section. - Overall more appealing presentation. - All docs will use the ActiveMQ favicon. - No more manual line-wrapping! AsciiDoc recommends one sentence per line and paragraphs are separated by a blank line. - AsciiDoctor plugins for IDEA are quite good. - Resulting HTML is less than *half* of the previous size. All previous links/bookmarks should continue to work. [1] https://github.com/asciidoctor/kramdown-asciidoc
2023-07-27 23:45:17 -04:00
= Guarantees of Sends and Commits
:idprefix:
:idseparator: -
== Transaction Completion
When committing or rolling back a transaction with Apache ActiveMQ Artemis, the request to commit or rollback is sent to the server, and the call will block on the client side until a response has been received from the server that the commit or rollback was executed.
When the commit or rollback is received on the server, it will be committed to the journal, and depending on the value of the parameter `journal-sync-transactional` the server will ensure that the commit or rollback is durably persisted to storage before sending the response back to the client.
If this parameter has the value `false` then commit or rollback may not actually get persisted to storage until some time after the response has been sent to the client.
In event of server failure this may mean the commit or rollback never gets persisted to storage.
The default value of this parameter is `true` so the client can be sure all transaction commits or rollbacks have been persisted to storage by the time the call to commit or rollback returns.
Setting this parameter to `false` can improve performance at the expense of some loss of transaction durability.
This parameter is set in `broker.xml`
== Non Transactional Message Sends
If you are sending messages to a server using a non transacted session, Apache ActiveMQ Artemis can be configured to block the call to send until the message has definitely reached the server, and a response has been sent back to the client.
This can be configured individually for durable and non-durable messages, and is determined by the following two URL parameters:
blockOnDurableSend::
If this is set to `true` then all calls to send for durable messages on non transacted sessions will block until the message has reached the server, and a response has been sent back.
The default value is `true`.
blockOnNonDurableSend::
If this is set to `true` then all calls to send for non-durable messages on non transacted sessions will block until the message has reached the server, and a response has been sent back.
The default value is `false`.
Setting block on sends to `true` can reduce performance since each send requires a network round trip before the next send can be performed.
This means the performance of sending messages will be limited by the network round trip time (RTT) of your network, rather than the bandwidth of your network.
For better performance we recommend either batching many messages sends together in a transaction since with a transactional session, only the commit / rollback blocks not every send, or, using Apache ActiveMQ Artemis's advanced _asynchronous send acknowledgements feature_ described in Asynchronous Send Acknowledgements.
When the server receives a message sent from a non transactional session, and that message is durable and the message is routed to at least one durable queue, then the server will persist the message in permanent storage.
If the journal parameter `journal-sync-non-transactional` is set to `true` the server will not send a response back to the client until the message has been persisted and the server has a guarantee that the data has been persisted to disk.
The default value for this parameter is `true`.
== Non Transactional Acknowledgements
If you are acknowledging the delivery of a message at the client side using a non transacted session, Apache ActiveMQ Artemis can be configured to block the call to acknowledge until the acknowledge has definitely reached the server, and a response has been sent back to the client.
This is configured with the parameter `BlockOnAcknowledge`.
If this is set to `true` then all calls to acknowledge on non transacted sessions will block until the acknowledge has reached the server, and a response has been sent back.
You might want to set this to `true` if you want to implement a strict _at most once_ delivery policy.
The default value is `false`
== Asynchronous Send Acknowledgements
If you are using a non transacted session but want a guarantee that every message sent to the server has reached it, then, as discussed in Guarantees of Non Transactional Message Sends, you can configure Apache ActiveMQ Artemis to block the call to send until the server has received the message, persisted it and sent back a response.
This works well but has a severe performance penalty - each call to send needs to block for at least the time of a network round trip (RTT) - the performance of sending is thus limited by the latency of the network, _not_ limited by the network bandwidth.
Let's do a little bit of maths to see how severe that is.
We'll consider a standard 1Gib ethernet network with a network round trip between the server and the client of 0.25 ms.
With a RTT of 0.25 ms, the client can send _at most_ 1000/ 0.25 = 4000 messages per second if it blocks on each message send.
If each message is < 1500 bytes and a standard 1500 bytes MTU (Maximum Transmission Unit) size is used on the network, then a 1GiB network has a _theoretical_ upper limit of (1024 * 1024 * 1024 / 8) / 1500 = 89478 messages per second if messages are sent without blocking!
These figures aren't an exact science but you can clearly see that being limited by network RTT can have serious effect on performance.
To remedy this, Apache ActiveMQ Artemis provides an advanced new feature called _asynchronous send acknowledgements_.
With this feature, Apache ActiveMQ Artemis can be configured to send messages without blocking in one direction and asynchronously getting acknowledgement from the server that the messages were received in a separate stream.
By de-coupling the send from the acknowledgement of the send, the system is not limited by the network RTT, but is limited by the network bandwidth.
Consequently better throughput can be achieved than is possible using a blocking approach, while at the same time having absolute guarantees that messages have successfully reached the server.
The window size for send acknowledgements is determined by the confirmation-window-size parameter on the connection factory or client session factory.
Please see xref:client-failover.adoc#core-client-failover[Client Failover] for more info on this.
To use the feature using the core API, you implement the interface `org.apache.activemq.artemis.api.core.client.SendAcknowledgementHandler` and set a handler instance on your `ClientSession`.
Then, you just send messages as normal using your `ClientSession`, and as messages reach the server, the server will send back an acknowledgement of the send asynchronously, and some time later you are informed at the client side by Apache ActiveMQ Artemis calling your handler's `sendAcknowledged(ClientMessage message)` method, passing in a reference to the message that was sent.
To enable asynchronous send acknowledgements you must make sure `confirmationWindowSize` is set to a positive integer value, e.g. 10MiB
Please see xref:examples.adoc#examples[the examples chapter] for a full working example.