Commit Graph

128 Commits

Author SHA1 Message Date
Loïc Hoguin 5aefd919d3
make: Additional cleanup of RabbitMQ components
Because of the monorepo most components do not need to be
listed. Only the community plugins and third party dependencies.

Community plugins can now be fetched and acted on from the top
level Makefile by adding COMMUNITY_PLUGINS=1 to the command line
or the environment. This will fetch and build community plugins:

  make COMMUNITY_PLUGINS=1

Once fetched they can be targeted directly as usual:

  make -C deps/rabbitmq_metronome

This cleanup has a net positive effect on build performance,
especially the performance of the top-level Makefile:

  make nope  0,04s user 0,02s system 106% cpu 0,061 total
  make nope  0,02s user 0,01s system 104% cpu 0,033 total

But also a minor improvement for application Makefiles:

  make -C deps/rabbit nope  0,02s user 0,00s system 98% cpu 0,022 total
  make -C deps/rabbit nope  0,01s user 0,00s system 98% cpu 0,020 total

And that improvement adds up when going through dependencies:

  make -C deps/rabbitmq_management  0,59s user 0,23s system 100% cpu 0,808 total
  make -C deps/rabbitmq_management  0,60s user 0,19s system 101% cpu 0,780 total
2024-08-29 15:19:32 +02:00
Loïc Hoguin d4222f8216
make: Remove emptied rabbitmq-tools.mk 2024-08-29 15:19:14 +02:00
Simon Unge 2766122836 Move shovel prometheus to its own plugin 2024-08-08 01:26:49 -04:00
Luke Bakken 3733ebc7d6 Fix elixir warning on build
This is the warning:
```
warning: single-quoted strings represent charlists. Use ~c"" if you indeed want a charlist or use "" instead
```
2024-07-11 22:15:33 -04:00
Loïc Hoguin 54a0ac8e2b
make: Remove mk/topic-branches.mk
This appears to be unused and was properly only necessary
in the early days of the monorepo.
2024-07-01 14:01:54 +02:00
Loïc Hoguin 6e26616141
make: Honor PLUGINS when using run-broker
The PLUGINS variable is a more natural space-separated
list of plugins, vs the RABBITMQ_ENABLED_PLUGINS which
is comma separated. Both can now be used, but PLUGINS
is more convenient.

Example usage:

  make run-broker PLUGINS="rabbitmq_management rabbitmq_web_mqtt"

This is only for the top-level Makefile. When using
application Makefiles only the application's plugin
is started.
2024-06-26 20:27:34 +02:00
Loïc Hoguin a64d1e67fc
Remove looking_glass
It has largely been superseded by `perf`. It is no longer
generally useful. It can always be added to BUILD_DEPS for
the rare cases it is needed, or installed locally and
pointed to by setting its path to ERL_LIBS.
2024-06-26 09:56:46 +02:00
Loïc Hoguin 9f15e978b1
make: Remove xrefr
It is no longer used by Erlang.mk.
2024-06-25 13:08:08 +02:00
Loïc Hoguin 7e9cac3d00
make: Remove Travis-specific targets/config
This should no longer be used.
2024-06-24 14:12:02 +02:00
Loïc Hoguin ba0d28cec8
make: Don't run Elixir inconditionally in top-level Makefile
We only need Elixir libs in ERL_LIBS for `xref` so don't
do this work if we're not running `xref`.

  make nope  0,55s user 0,23s system 274% cpu 0,283 total
  make nope  0,05s user 0,03s system 105% cpu 0,070 total
2024-06-10 09:42:33 +02:00
Loïc Hoguin 5d731ae327
make: Calc PROJECT_VERSION once in top-level Makefile
The optimisation that worked well for subfolders made things
worse for the top-level Makefile. This should be corrected:

  make nope  0,74s user 0,58s system 172% cpu 0,769 total
  make nope  0,55s user 0,23s system 274% cpu 0,283 total
2024-06-10 09:42:33 +02:00
Rin Kuryloski a6874e39cc
Turn off BuildBuddy integration (#11343)
Builds now execute on the github actions workers, using Google Cloud Storage (GCS) as a cache
2024-06-06 11:37:10 +02:00
Rin Kuryloski 4ec33c8678
Fix some dialyzer build system errors in make (#11014)
* make amqp10_common dialyze green in make

* make rabbitmq_ct_client_helpers dialyze green with make

* fixup rabbitmq_prelaunch path ref

* Cleanup unused dep_* vars

* Fixup xref for rabbitmq_ct_helpers

I could not figure out how to make xref aware of the cli code without
also checking the cli code as well, and reporting additional errors

* remove unused file

* fix make diaylze for rabbitmq_stream_common

* update deps/oauth2_client/Makefile to match Bazel
2024-04-16 13:26:51 +02:00
David Ansari 8cb313d5a1 Support AMQP 1.0 natively
## What

Similar to Native MQTT in #5895, this commits implements Native AMQP 1.0.
By "native", we mean do not proxy via AMQP 0.9.1 anymore.

  ## Why

Native AMQP 1.0 comes with the following major benefits:
1. Similar to Native MQTT, this commit provides better throughput, latency,
   scalability, and resource usage for AMQP 1.0.
   See https://blog.rabbitmq.com/posts/2023/03/native-mqtt for native MQTT improvements.
   See further below for some benchmarks.
2. Since AMQP 1.0 is not limited anymore by the AMQP 0.9.1 protocol,
   this commit allows implementing more AMQP 1.0 features in the future.
   Some features are already implemented in this commit (see next section).
3. Simpler, better understandable, and more maintainable code.

Native AMQP 1.0 as implemented in this commit has the
following major benefits compared to AMQP 0.9.1:
4. Memory and disk alarms will only stop accepting incoming TRANSFER frames.
   New connections can still be created to consume from RabbitMQ to empty queues.
5. Due to 4. no need anymore for separate connections for publishers and
   consumers as we currently recommended for AMQP 0.9.1. which potentially
   halves the number of physical TCP connections.
6. When a single connection sends to multiple target queues, a single
   slow target queue won't block the entire connection.
   Publisher can still send data quickly to all other target queues.
7. A publisher can request whether it wants publisher confirmation on a per-message basis.
   In AMQP 0.9.1 publisher confirms are configured per channel only.
8. Consumers can change their "prefetch count" dynamically which isn't
   possible in our AMQP 0.9.1 implementation. See #10174
9. AMQP 1.0 is an extensible protocol

This commit also fixes dozens of bugs present in the AMQP 1.0 plugin in
RabbitMQ 3.x - most of which cannot be backported due to the complexity
and limitations of the old 3.x implementation.

This commit contains breaking changes and is therefore targeted for RabbitMQ 4.0.

 ## Implementation details

1. Breaking change: With Native AMQP, the behaviour of
```
Convert AMQP 0.9.1 message headers to application properties for an AMQP 1.0 consumer
amqp1_0.convert_amqp091_headers_to_app_props = false | true (default false)
Convert AMQP 1.0 Application Properties to AMQP 0.9.1 headers
amqp1_0.convert_app_props_to_amqp091_headers = false | true (default false)
```
will break because we always convert according to the message container conversions.
For example, AMQP 0.9.1 x-headers will go into message-annotations instead of application properties.
Also, `false` won’t be respected since we always convert the headers with message containers.

2. Remove rabbit_queue_collector

rabbit_queue_collector is responsible for synchronously deleting
exclusive queues. Since the AMQP 1.0 plugin never creates exclusive
queues, rabbit_queue_collector doesn't need to be started in the first
place. This will save 1 Erlang process per AMQP 1.0 connection.

3. 7 processes per connection + 1 process per session in this commit instead of
   7 processes per connection + 15 processes per session in 3.x
Supervision hierarchy got re-designed.

4. Use 1 writer process per AMQP 1.0 connection
AMQP 0.9.1 uses a separate rabbit_writer Erlang process per AMQP 0.9.1 channel.
Prior to this commit, AMQP 1.0 used a separate rabbit_amqp1_0_writer process per AMQP 1.0 session.
Advantage of single writer proc per session (prior to this commit):
* High parallelism for serialising packets if multiple sessions within
  a connection write heavily at the same time.

This commit uses a single writer process per AMQP 1.0 connection that is
shared across all AMQP 1.0 sessions.
Advantages of single writer proc per connection (this commit):
* Lower memory usage with hundreds of thousands of AMQP 1.0 sessions
* Less TCP and IP header overhead given that the single writer process
  can accumulate across all sessions bytes before flushing the socket.

In other words, this commit decides that a reader / writer process pair
per AMQP 1.0 connection is good enough for bi-directional TRANSFER flows.
Having a writer per session is too heavy.
We still ensure high throughput by having separate reader, writer, and
session processes.

5. Transform rabbit_amqp1_0_writer into gen_server
Why:
Prior to this commit, when clicking on the AMQP 1.0 writer process in
observer, the process crashed.
Instead of handling all these debug messages of the sys module, it's better
to implement a gen_server.
There is no advantage of using a special OTP process over gen_server
for the AMQP 1.0 writer.
gen_server also provides cleaner format status output.

How:
Message callbacks return a timeout of 0.
After all messages in the inbox are processed, the timeout message is
handled by flushing any pending bytes.

6. Remove stats timer from writer
AMQP 1.0 connections haven't emitted any stats previously.

7. When there are contiguous queue confirmations in the session process
mailbox, batch them. When the confirmations are sent to the publisher, a
single DISPOSITION frame is sent for contiguously confirmed delivery
IDs.
This approach should be good enough. However it's sub optimal in
scenarios where contiguous delivery IDs that need confirmations are rare,
for example:
* There are multiple links in the session with different sender
  settlement modes and sender publishes across these links interleaved.
* sender settlement mode is mixed and sender publishes interleaved settled
  and unsettled TRANSFERs.

8. Introduce credit API v2
Why:
The AMQP 0.9.1 credit extension which is to be removed in 4.0 was poorly
designed since basic.credit is a synchronous call into the queue process
blocking the entire AMQP 1.0 session process.

How:
Change the interactions between queue clients and queue server
implementations:
* Clients only request a credit reply if the FLOW's `echo` field is set
* Include all link flow control state held by the queue process into a
  new credit_reply queue event:
  * `available` after the queue sends any deliveries
  * `link-credit` after the queue sends any deliveries
  * `drain` which allows us to combine the old queue events
    send_credit_reply and send_drained into a single new queue event
    credit_reply.
* Include the consumer tag into the credit_reply queue event such that
  the AMQP 1.0 session process can process any credit replies
  asynchronously.

Link flow control state `delivery-count` also moves to the queue processes.

The new interactions are hidden behind feature flag credit_api_v2 to
allow for rolling upgrades from 3.13 to 4.0.

9. Use serial number arithmetic in quorum queues and session process.

10. Completely bypass the rabbit_limiter module for AMQP 1.0
flow control. The goal is to eventually remove the rabbit_limiter module
in 4.0 since AMQP 0.9.1 global QoS will be unsupported in 4.0. This
commit lifts the AMQP 1.0 link flow control logic out of rabbit_limiter
into rabbit_queue_consumers.

11. Fix credit bug for streams:
AMQP 1.0 settlements shouldn't top up link credit,
only FLOW frames should top up link credit.

12. Allow sender settle mode unsettled for streams
since AMQP 1.0 acknowledgements to streams are no-ops (currently).

13. Fix AMQP 1.0 client bugs
Auto renewing credits should not be related to settling TRANSFERs.
Remove field link_credit_unsettled as it was wrong and confusing.
Prior to this commit auto renewal did not work when the sender uses
sender settlement mode settled.

14. Fix AMQP 1.0 client bugs
The wrong outdated Link was passed to function auto_flow/2

15. Use osiris chunk iterator
Only hold messages of uncompressed sub batches in memory if consumer
doesn't have sufficient credits.
Compressed sub batches are skipped for non Stream protocol consumers.

16. Fix incoming link flow control
Always use confirms between AMQP 1.0 queue clients and queue servers.
As already done internally by rabbit_fifo_client and
rabbit_stream_queue, use confirms for classic queues as well.

17. Include link handle into correlation when publishing messages to target queues
such that session process can correlate confirms from target queues to
incoming links.

18. Only grant more credits to publishers if publisher hasn't sufficient credits
anymore and there are not too many unconfirmed messages on the link.

19. Completely ignore `block` and `unblock` queue actions and RabbitMQ credit flow
between classic queue process and session process.

20. Link flow control is independent between links.
A client can refer to a queue or to an exchange with multiple
dynamically added target queues. Multiple incoming links can also fan
in to the same queue. However the link topology looks like, this
commit ensures that each link is only granted more credits if that link
isn't overloaded.

21. A connection or a session can send to many different queues.
In AMQP 0.9.1, a single slow queue will lead to the entire channel, and
then entire connection being blocked.
This commit makes sure that a single slow queue from one link won't slow
down sending on other links.
For example, having link A sending to a local classic queue and
link B sending to 5 replica quorum queue, link B will naturally
grant credits slower than link A. So, despite the quorum queue being
slower in confirming messages, the same AMQP 1.0 connection and session
can still pump data very fast into the classic queue.

22. If cluster wide memory or disk alarm occurs.
Each session sends a FLOW with incoming-window to 0 to sending client.
If sending clients don’t obey, force disconnect the client.

If cluster wide memory alarm clears:
Each session resumes with a FLOW defaulting to initial incoming-window.

23. All operations apart of publishing TRANSFERS to RabbitMQ can continue during cluster wide alarms,
specifically, attaching consumers and consuming, i.e. emptying queues.
There is no need for separate AMQP 1.0 connections for publishers and consumers as recommended in our AMQP 0.9.1 implementation.

24. Flow control summary:
* If queue becomes bottleneck, that’s solved by slowing down individual sending links (AMQP 1.0 link flow control).
* If session becomes bottleneck (more unlikely), that’s solved by AMQP 1.0 session flow control.
* If connection becomes bottleneck, it naturally won’t read fast enough from the socket causing TCP backpressure being applied.
Nowhere will RabbitMQ internal credit based flow control (i.e. module credit_flow) be used on the incoming AMQP 1.0 message path.

25. Register AMQP sessions
Prefer local-only pg over our custom pg_local implementation as
pg is a better process group implementation than pg_local.
pg_local was identified as bottleneck in tests where many MQTT clients were disconnected at once.

26. Start a local-only pg when Rabbit boots:
> A scope can be kept local-only by using a scope name that is unique cluster-wide, e.g. the node name:
> pg:start_link(node()).
Register AMQP 1.0 connections and sessions with pg.

In future we should remove pg_local and instead use the new local-only
pg for all registered processes such as AMQP 0.9.1 connections and channels.

27. Requeue messages if link detached
Although the spec allows to settle delivery IDs on detached links, RabbitMQ does not respect the 'closed'
field of the DETACH frame and therefore handles every DETACH frame as closed. Since the link is closed,
we expect every outstanding delivery to be requeued.
In addition to consumer cancellation, detaching a link therefore causes in flight deliveries to be requeued.
Note that this behaviour is different from merely consumer cancellation in AMQP 0.9.1:
"After a consumer is cancelled there will be no future deliveries dispatched to it. Note that there can
still be "in flight" deliveries dispatched previously. Cancelling a consumer will neither discard nor requeue them."
[https://www.rabbitmq.com/consumers.html#unsubscribing]
An AMQP receiver can first drain, and then detach to prevent "in flight" deliveries

28. Init AMQP session with BEGIN frame
Similar to how there can't be an MQTT processor without a CONNECT
frame, there can't be an AMQP session without a BEGIN frame.
This allows having strict dialyzer types for session flow control
fields (i.e. not allowing 'undefined').

29. Move serial_number to AMQP 1.0 common lib
such that it can be used by both AMQP 1.0 server and client

30. Fix AMQP client to do serial number arithmetic.

31. AMQP client: Differentiate between delivery-id and transfer-id for better
understandability.

32. Fix link flow control in classic queues
This commit fixes
```
java -jar target/perf-test.jar -ad false -f persistent -u cq -c 3000 -C 1000000 -y 0
```
followed by
```
./omq -x 0 amqp -T /queue/cq -D 1000000 --amqp-consumer-credits 2
```
Prior to this commit, (and on RabbitMQ 3.x) the consuming would halt after around
8 - 10,000 messages.

The bug was that in flight messages from classic queue process to
session process were not taken into account when topping up credit to
the classic queue process.
Fixes #2597

The solution to this bug (and a much cleaner design anyway independent of
this bug) is that queues should hold all link flow control state including
the delivery-count.

Hence, when credit API v2 is used the delivery-count will be held by the
classic queue process, quorum queue process, and stream queue client
instead of managing the delivery-count in the session.

33. The double level crediting between (a) session process and
rabbit_fifo_client, and (b) rabbit_fifo_client and rabbit_fifo was
removed. Therefore, instead of managing 3 separate delivery-counts (i. session,
ii. rabbit_fifo_client, iii. rabbit_fifo), only 1 delivery-count is used
in rabbit_fifo. This is a big simplification.

34. This commit fixes quorum queues without bumping the machine version
nor introducing new rabbit_fifo commands.

Whether credit API v2 is used is solely determined at link attachment time
depending on whether feature flag credit_api_v2 is enabled.

Even when that feature flag will be enabled later on, this link will
keep using credit API v1 until detached (or the node is shut down).

Eventually, after feature flag credit_api_v2 has been enabled and a
subsequent rolling upgrade, all links will use credit API v2.

This approach is safe and simple.

The 2 alternatives to move delivery-count from the session process to the
queue processes would have been:

i. Explicit feature flag credit_api_v2 migration function
* Can use a gen_server:call and only finish migration once all delivery-counts were migrated.
Cons:
* Extra new message format just for migration is required.
* Risky as migration will fail if a target queue doesn’t reply.

ii. Session always includes DeliveryCountSnd when crediting to the queue:
Cons:
* 2 delivery counts will be hold simultaneously in session proc and queue proc;
could be solved by deleting the session proc’s delivery-count for credit-reply
* What happens if the receiver doesn’t provide credit for a very long time? Is that a problem?

35. Support stream filtering in AMQP 1.0 (by @acogoluegnes)
Use the x-stream-filter-value message annotation
to carry the filter value in a published message.
Use the rabbitmq:stream-filter and rabbitmq:stream-match-unfiltered
filters when creating a receiver that wants to filter
out messages from a stream.

36. Remove credit extension from AMQP 0.9.1 client

37. Support maintenance mode closing AMQP 1.0 connections.

38. Remove AMQP 0.9.1 client dependency from AMQP 1.0 implementation.

39. Move AMQP 1.0 plugin to the core. AMQP 1.0 is enabled by default.
    The old rabbitmq_amqp1_0 plugin will be kept as a no-op plugin to prevent deployment
    tools from failing that execute:
```
rabbitmq-plugins enable rabbitmq_amqp1_0
rabbitmq-plugins disable rabbitmq_amqp1_0
```

40. Breaking change: Remove CLI command `rabbitmqctl list_amqp10_connections`.
Instead, list both AMQP 0.9.1 and AMQP 1.0 connections in `list_connections`:
```
rabbitmqctl list_connections protocol
Listing connections ...
protocol
{1, 0}
{0,9,1}
```

 ## Benchmarks

 ### Throughput & Latency

Setup:
* Single node Ubuntu 22.04
* Erlang 26.1.1

Start RabbitMQ:
```
make run-broker PLUGINS="rabbitmq_management rabbitmq_amqp1_0" FULL=1 RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="+S 3"
```

Predeclare durable classic queue cq1, durable quorum queue qq1, durable stream queue sq1.

Start client:
https://github.com/ssorj/quiver
https://hub.docker.com/r/ssorj/quiver/tags (digest 453a2aceda64)
```
docker run -it --rm --add-host host.docker.internal:host-gateway ssorj/quiver:latest
bash-5.1# quiver --version
quiver 0.4.0-SNAPSHOT
```

1. Classic queue
```
quiver //host.docker.internal//amq/queue/cq1 --durable --count 1m --duration 10m --body-size 12 --credit 1000
```

This commit:
```
Count ............................................. 1,000,000 messages
Duration ............................................... 73.8 seconds
Sender rate .......................................... 13,548 messages/s
Receiver rate ........................................ 13,547 messages/s
End-to-end rate ...................................... 13,547 messages/s

Latencies by percentile:

          0% ........ 0 ms       90.00% ........ 9 ms
         25% ........ 2 ms       99.00% ....... 14 ms
         50% ........ 4 ms       99.90% ....... 17 ms
        100% ....... 26 ms       99.99% ....... 24 ms
```

RabbitMQ 3.x (main branch as of 30 January 2024):
```
---------------------- Sender -----------------------  --------------------- Receiver ----------------------  --------
Time [s]      Count [m]  Rate [m/s]  CPU [%]  RSS [M]  Time [s]      Count [m]  Rate [m/s]  CPU [%]  RSS [M]  Lat [ms]
-----------------------------------------------------  -----------------------------------------------------  --------
     2.1        130,814      65,342        6     73.6       2.1          3,217       1,607        0      8.0       511
     4.1        163,580      16,367        2     74.1       4.1          3,217           0        0      8.0         0
     6.1        229,114      32,767        3     74.1       6.1          3,217           0        0      8.0         0
     8.1        261,880      16,367        2     74.1       8.1         67,874      32,296        8      8.2     7,662
    10.1        294,646      16,367        2     74.1      10.1         67,874           0        0      8.2         0
    12.1        360,180      32,734        3     74.1      12.1         67,874           0        0      8.2         0
    14.1        392,946      16,367        3     74.1      14.1         68,604         365        0      8.2    12,147
    16.1        458,480      32,734        3     74.1      16.1         68,604           0        0      8.2         0
    18.1        491,246      16,367        2     74.1      18.1         68,604           0        0      8.2         0
    20.1        556,780      32,767        4     74.1      20.1         68,604           0        0      8.2         0
    22.1        589,546      16,375        2     74.1      22.1         68,604           0        0      8.2         0
receiver timed out
    24.1        622,312      16,367        2     74.1      24.1         68,604           0        0      8.2         0
quiver:  error: PlanoProcessError: Command 'quiver-arrow receive //host.docker.internal//amq/queue/cq1 --impl qpid-proton-c --duration 10m --count 1m --rate 0 --body-size 12 --credit 1000 --transaction-size 0 --timeout 10 --durable --output /tmp/quiver-otujr23y' returned non-zero exit status 1.
Traceback (most recent call last):
  File "/usr/local/lib/quiver/python/quiver/pair.py", line 144, in run
    _plano.wait(receiver, check=True)
  File "/usr/local/lib/quiver/python/plano/main.py", line 1243, in wait
    raise PlanoProcessError(proc)
plano.main.PlanoProcessError: Command 'quiver-arrow receive //host.docker.internal//amq/queue/cq1 --impl qpid-proton-c --duration 10m --count 1m --rate 0 --body-size 12 --credit 1000 --transaction-size 0 --timeout 10 --durable --output /tmp/quiver-otujr23y' returned non-zero exit status 1.
```

2. Quorum queue:
```
quiver //host.docker.internal//amq/queue/qq1 --durable --count 1m --duration 10m --body-size 12 --credit 1000
```
This commit:
```
Count ............................................. 1,000,000 messages
Duration .............................................. 101.4 seconds
Sender rate ........................................... 9,867 messages/s
Receiver rate ......................................... 9,868 messages/s
End-to-end rate ....................................... 9,865 messages/s

Latencies by percentile:

          0% ....... 11 ms       90.00% ....... 23 ms
         25% ....... 15 ms       99.00% ....... 28 ms
         50% ....... 18 ms       99.90% ....... 33 ms
        100% ....... 49 ms       99.99% ....... 47 ms
```

RabbitMQ 3.x:
```
---------------------- Sender -----------------------  --------------------- Receiver ----------------------  --------
Time [s]      Count [m]  Rate [m/s]  CPU [%]  RSS [M]  Time [s]      Count [m]  Rate [m/s]  CPU [%]  RSS [M]  Lat [ms]
-----------------------------------------------------  -----------------------------------------------------  --------
     2.1        130,814      65,342        9     69.9       2.1         18,430       9,206        5      7.6     1,221
     4.1        163,580      16,375        5     70.2       4.1         18,867         218        0      7.6     2,168
     6.1        229,114      32,767        6     70.2       6.1         18,867           0        0      7.6         0
     8.1        294,648      32,734        7     70.2       8.1         18,867           0        0      7.6         0
    10.1        360,182      32,734        6     70.2      10.1         18,867           0        0      7.6         0
    12.1        425,716      32,767        6     70.2      12.1         18,867           0        0      7.6         0
receiver timed out
    14.1        458,482      16,367        5     70.2      14.1         18,867           0        0      7.6         0
quiver:  error: PlanoProcessError: Command 'quiver-arrow receive //host.docker.internal//amq/queue/qq1 --impl qpid-proton-c --duration 10m --count 1m --rate 0 --body-size 12 --credit 1000 --transaction-size 0 --timeout 10 --durable --output /tmp/quiver-b1gcup43' returned non-zero exit status 1.
Traceback (most recent call last):
  File "/usr/local/lib/quiver/python/quiver/pair.py", line 144, in run
    _plano.wait(receiver, check=True)
  File "/usr/local/lib/quiver/python/plano/main.py", line 1243, in wait
    raise PlanoProcessError(proc)
plano.main.PlanoProcessError: Command 'quiver-arrow receive //host.docker.internal//amq/queue/qq1 --impl qpid-proton-c --duration 10m --count 1m --rate 0 --body-size 12 --credit 1000 --transaction-size 0 --timeout 10 --durable --output /tmp/quiver-b1gcup43' returned non-zero exit status 1.
```

3. Stream:
```
quiver-arrow send //host.docker.internal//amq/queue/sq1 --durable --count 1m -d 10m --summary --verbose
```

This commit:
```
Count ............................................. 1,000,000 messages
Duration ................................................ 8.7 seconds
Message rate ........................................ 115,154 messages/s
```

RabbitMQ 3.x:
```
Count ............................................. 1,000,000 messages
Duration ............................................... 21.2 seconds
Message rate ......................................... 47,232 messages/s
```

 ### Memory usage

Start RabbitMQ:
```
ERL_MAX_PORTS=3000000 RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="+P 3000000 +S 6" make run-broker PLUGINS="rabbitmq_amqp1_0" FULL=1 RABBITMQ_CONFIG_FILE="rabbitmq.conf"
```

```
/bin/cat rabbitmq.conf

tcp_listen_options.sndbuf  = 2048
tcp_listen_options.recbuf  = 2048
vm_memory_high_watermark.relative = 0.95
vm_memory_high_watermark_paging_ratio = 0.95
loopback_users = none
```

Create 50k connections with 2 sessions per connection, i.e. 100k session in total:

```go
package main

import (
	"context"
	"log"
	"time"

	"github.com/Azure/go-amqp"
)

func main() {
	for i := 0; i < 50000; i++ {
		conn, err := amqp.Dial(context.TODO(), "amqp://nuc", &amqp.ConnOptions{SASLType: amqp.SASLTypeAnonymous()})
		if err != nil {
			log.Fatal("dialing AMQP server:", err)
		}
		_, err = conn.NewSession(context.TODO(), nil)
		if err != nil {
			log.Fatal("creating AMQP session:", err)
		}
		_, err = conn.NewSession(context.TODO(), nil)
		if err != nil {
			log.Fatal("creating AMQP session:", err)
		}
	}
	log.Println("opened all connections")
	time.Sleep(5 * time.Hour)
}
```

This commit:
```
erlang:memory().
[{total,4586376480},
 {processes,4025898504},
 {processes_used,4025871040},
 {system,560477976},
 {atom,1048841},
 {atom_used,1042841},
 {binary,233228608},
 {code,21449982},
 {ets,108560464}]

erlang:system_info(process_count).
450289
```
7 procs per connection + 1 proc per session.
(7 + 2*1) * 50,000 = 450,000 procs

RabbitMQ 3.x:
```
erlang:memory().
[{total,15168232704},
 {processes,14044779256},
 {processes_used,14044755120},
 {system,1123453448},
 {atom,1057033},
 {atom_used,1052587},
 {binary,236381264},
 {code,21790238},
 {ets,391423744}]

erlang:system_info(process_count).
1850309
```
7 procs per connection + 15 per session
(7 + 2*15) * 50,000 = 1,850,000 procs

50k connections + 100k session require
with this commit: 4.5 GB
in RabbitMQ 3.x: 15 GB

 ## Future work

1. More efficient parser and serializer
2. TODO in mc_amqp: Do not store the parsed message on disk.
3. Implement both AMQP HTTP extension and AMQP management extension to allow AMQP
clients to create RabbitMQ objects (queues, exchanges, ...).
2024-02-28 14:15:20 +01:00
Michal Kuratczyk 9373661a33
Revert "Remove Elixir json dep in a few more places #9926"
This reverts commit 50e1fed344.
2023-11-17 13:08:26 +01:00
Michael Klishin 50e1fed344
Remove Elixir json dep in a few more places #9926
(cherry picked from commit d419b0a431)
2023-11-16 10:59:42 -05:00
Rin Kuryloski 6209180f80 Use pkg_files rules to avoid extra tars
in package-generic-unix and source_archive macros
2023-03-14 23:18:00 +01:00
Rin Kuryloski 019766f34f Exclude bazel related files from `make source-dist` 2023-02-24 12:55:03 +01:00
Rin Kuryloski 609171ec70 Rename the tanzu cli scope to vmware
And update other references to commercial editions
2023-02-16 13:49:54 +01:00
Loïc Hoguin fa6b9f0767
Ignore the Elixir protocol related warnings 2022-05-31 14:19:54 +02:00
Loïc Hoguin dc70cbf281
Update Erlang.mk and switch to new xref code 2022-05-31 13:51:12 +02:00
Michael Klishin f7d32d69f8 Introduce a new CLI tool (scope), rabbitmq-tanzu
For Tanzu (commercial) plugins to attach their commands to instead of
polluting rabbitmqctl.

Pair: @pjk25
(cherry picked from commit 6e0f2436fa)
2021-11-30 14:54:09 +00:00
Gerhard Lazu db35a3409b
Add bazel-test make target so that we can run tests in bazel quickly (#3138)
* Add bazel-test make target so that we can run tests in bazel quickly

Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>

Co-authored-by: Philip Kuryloski <kuryloskip@vmware.com>
2021-07-20 11:53:39 +02:00
Gerhard Lazu c8c055e158
Delete stats make target
None was using it, and I haven't used it in many months

Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2021-06-23 17:07:57 +01:00
Gerhard Lazu 0cbef999cc
Add make target for cleaning deps of deps, like ra, osiris, etc.
This is helpful when we want to ensure a clean slate, which is what
happens when deps of deps go out of sync, and builds / tests start
failing for unexpected reasons.

Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2021-06-22 11:26:46 +01:00
Jean-Sébastien Pédron 63689dd658 Makefile: Don't copy `rabbit/ebin` when running "make install" on Windows
`rabbit` is now packaged as any plugins and `rabbit_common`. There is no
need for a second copy of its beam files.

At the same time, we stop copying the `priv` directory and headers for
the same reason.
2021-04-13 14:43:32 +02:00
Jean-Sébastien Pédron cc433b72cb Makefile: Use `core_native_path` on filenames passed to Erlang
... in the source dist recipe.

This is required when running the recipe in MSYS2 because Erlang runs
with regular Windows paths, not the MSYS2 namespace.
2021-04-13 14:43:32 +02:00
Jean-Sébastien Pédron 6b337b49c7 Use {MIX,HEX}_HOME variables to prepare offline cache
We used to use $HOME for both tools, but they now support dedicated
variables. As an added bonus, this makes the recipe work on Microsoft
Windows.
2021-04-13 14:43:32 +02:00
Gabriele Santomaggio ba8fd1c125 Add the rabbitmq-streams command 2021-03-22 14:18:08 +01:00
Loïc Hoguin d5e3bdd623
Add ADDITIONAL_PLUGINS variable
This allows including additional applications or third party
plugins when creating a release, running the broker locally,
or just building from the top-level Makefile.

To include Looking Glass in a release, for example:

$ make package-generic-unix ADDITIONAL_PLUGINS="looking_glass"

A Docker image can then be built using this release and will
contain Looking Glass:

$ make docker-image

Beware macOS users! Applications such as Looking Glass include
NIFs. NIFs must be compiled in the right environment. If you
are building a Docker image then make sure to build the NIF
on Linux! In the two steps above, this corresponds to Step 1.

To run the broker with Looking Glass available:

$ make run-broker ADDITIONAL_PLUGINS="looking_glass"

This commit also moves Looking Glass dependency information
into rabbitmq-components.mk so it is available at all times.
2021-03-12 12:29:28 +01:00
Philip Kuryloski a3cfac3232 Move most packaging goal implementations to rabbitmq-packaging 2021-02-26 11:39:01 +01:00
Jean-Sébastien Pédron ed112773e3
Makefile: Exclude more things from the source archive
In particular, the temporary `licensing` directory was never cleaned up.
2020-11-16 12:56:53 +01:00
Jean-Sébastien Pédron 4568ab0fb9
packaging/docker-image: Move Docker files to their own directory
Like other packaging files, they should not be part of RabbitMQ itself.
One day, they will probably be moved to a dedicated repository, like
other packaging files.
2020-11-16 12:18:39 +01:00
Philip Kuryloski 2259039b17 Ensure that `make distclean` does not remove vendored deps
More precisely, it will leave the deps dir intact
2020-11-13 14:41:22 +01:00
Philip Kuryloski e32b93b3e6 Add support for bringing topic branches into the monorepo
Once the monorepo is built, from within it one can run `make
fetch-topic-branch-${TOPIC_BRANCH}` then `make
topic-branch-${TOPIC_BRANCH}` to rebase the commits from all the
sources back onto the monorepo
2020-11-13 14:41:22 +01:00
Philip Kuryloski 44b77e8b1e Monorepo GitHub Actions
Add GitHub Actions workflows for Erlang/OTP 22.3 & 23.0.

The workflows run tests for each component that is now part of this
repo, with test suite parallelization specifically for the rabbit
erlang application.
2020-11-13 14:41:22 +01:00
Gerhard Lazu d4f20ff1d2
Bump OTP to 22.3 for Docker image
Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2020-03-17 11:55:05 +00:00
Philip Kuryloski 5be133f49e
Use `J` tar flag for extracting `.tar.xz`
When making `docker-image`

Ubuntu 18 fails to build the image unless tar is invoked with the capital J
2020-03-16 11:50:04 +01:00
Gerhard Lazu 28f00e066d
Speed-up Docker image builds by re-using generic-unix package archive
Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2020-03-12 12:09:05 +00:00
Gerhard Lazu 26d8101202
Bump OTP to 22.2.8 for Docker image
Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2020-03-12 11:47:38 +00:00
Gerhard Lazu bc4059be59
Use PROJECT_VERSION in Docker image build
Because we set the PROJECT_VERSION when we build the Docker image, this
change saves us having to search for the RABBITMQ_VERSION to
PROJECT_VERSION mapping that happens at the top of the Makefile in order
to understand how this ends up in the final Docker image.

Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2020-02-20 18:03:54 +00:00
Gerhard Lazu 6612884764
Package generic-unix before building Docker image
Otherwise this target will fail. It's worth making this target slower
but always working rather than fast but it may not work if the dependent
generic-unix version wasn't built before.

Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2020-02-20 18:00:43 +00:00
Gerhard Lazu 427a20fd6f
Bump OTP to 22.2.7 when building Docker image
Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2020-02-20 18:00:25 +00:00
Jean-Sébastien Pédron 2d9fd9e581
Makefile: Ignore `docker` subdirectory when creating source archive
rabbitmq-prometheus has such a directory. In this case, it is quite
large and does not contain files used at build time.
2020-02-17 15:02:54 +01:00
Gerhard Lazu f96937f34d
Fix make target for building Docker image using local RabbitMQ dev
make package-generic-unix PROJECT_VERSION=3.9.0-20200207
    make docker-image PROJECT_VERSION=3.9.0-20200207
    docker run -it --rm pivotalrabbitmq/rabbitmq:3.9.0-20200207

Re 53a34fc368

cc @dcorbacho

Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2020-02-07 19:24:40 +00:00
Gerhard Lazu 53a34fc368
Add make target to build docker image using the local RabbitMQ dev
make package-generic-unix NO_CLEAN=true PROJECT_VERSION=3.9.0-20200207
   make docker-image PROJECT_VERSION=3.9.0-20200207
   docker run -it --rm rabbitmq:3.9.0-20200207

Based on
7734a5a34f/Dockerfile
which in turn is based on https://github.com/docker-library/rabbitmq/blob/master/Dockerfile-ubuntu.template

cc @dcorbacho

[finishes #171153463]

Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2020-02-07 19:16:04 +00:00
Gerhard Lazu 7f9c45ac00
Do not use tar flags for reproducible builds on macOS
Some of the flags that we currently use are not recognised, so rather
than adding a third set of flags, let's just ignore everything for now
and circle back to this when it becomes an issue.

Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
2020-02-07 19:16:04 +00:00
Jean-Sébastien Pédron 52e6c65e00
Makefile: Improve Hex cache export
We hit the case where the exported Hex cache could not be read again
using `file:consult/2` when we try to restore the ETS table. The problem
was some string generated with `io_lib:format("~p")` which had invalid
Unicode characters according to `file:consult/1`.

The error returned by `file:consult/1` was:

    {51,file_io_server,invalid_unicode}

We are now using `~w` instead of `~p` so string detection is skipped by
io_lib. The result is readable by `file:consult/1`, though the text file
is barely readable by a human now.
2020-02-07 19:30:59 +01:00
Jean-Sébastien Pédron 6a610a594c
Makefile: Don't copy rabbit's `ebin` and `priv` dirs to install dir
They are unused now, since rabbit is provided as an .ez archive.

While here, don't copy include files as well: they are not enough to
build a RabbitMQ plugin anyway.
2019-12-05 15:53:42 +01:00
Jean-Sébastien Pédron ba938ae16b
Makefile: cuttlefish(1) is gone
We can do because Cuttlefish is now used as a library and configuration
is managed at runtime by the RabbitMQ node, not by a preliminary
execution of cuttlefish(1).
2019-12-05 15:52:19 +01:00