This document refers to functionality only available in brokers
using AMQP. Other brokers may implement some functionality, see their
respective documentation for more information, or contact the
Mailing list.

A message consists of headers and a body. Celery uses headers to store
the content type of the message and its content encoding. The
content type is usually the serialization format used to serialize the
message. The body contains the name of the task to execute, the
task id (UUID), the arguments to execute it with and some additional
metadata – like the number of retries or an ETA.

The exchange type defines how the messages are routed through the exchange.
The exchange types defined in the standard are direct, topic,
fanout and headers. Also non-standard exchange types are available
as plug-ins to RabbitMQ, like the last-value-cache plug-in by Michael
Bridgen.

Declaring does not necessarily mean “create”. When you declare you
assert that the entity exists and that it’s operable. There is no
rule as to whom should initially create the exchange/queue/binding,
whether consumer or producer. Usually the first one to need it will
be the one to create it.

Celery comes with a tool called camqadm (short for Celery AMQ Admin).
It’s used for command-line access to the AMQP API, enabling access to
administration tasks like creating/deleting queues and exchanges, purging
queues or sending messages.

You can write commands directly in the arguments to camqadm,
or just start with no arguments to start it in shell-mode:

Here 1> is the prompt. The number 1, is the number of commands you
have executed so far. Type help for a list of commands available.
It also supports auto-completion, so you can start typing a command and then
hit the tab key to show a list of possible matches.

AMQP uses acknowledgment to signify that a message has been received
and processed successfully. If the message has not been acknowledged
and consumer channel is closed, the message will be delivered to
another consumer.

Note the delivery tag listed in the structure above; Within a connection
channel, every received message has a unique delivery tag,
This tag is used to acknowledge the message. Also note that
delivery tags are not unique across connections, so in another client
the delivery tag 1 might point to a different message than in this channel.

You can acknowledge the message we received using basic.ack:

6> basic.ack 1
ok.

To clean up after our test session we should delete the entities we created:

It is considered best practice to not hard-code these settings, but rather
leave that as configuration options by using Routers;
This is the most flexible approach, but sensible defaults can still be set
as task attributes.