diff --git a/src/docbkx/amqp.xml b/src/docbkx/amqp.xml
index 9fde8ffe..ea989577 100644
--- a/src/docbkx/amqp.xml
+++ b/src/docbkx/amqp.xml
@@ -219,22 +219,26 @@
that exists only within our "spring-rabbit" module since at this point,
RabbitMQ is the only supported implementation.
- The central component for managing a connection to the RabbitMQ
- broker is the ConnectionFactory interface.
- The responsibility of a ConnectionFactory
- implementation is to provide an instance of
- com.rabbitmq.client.Connection. The simplest
- implementation we provide is
- SingleConnectionFactory which establishes a single
- connection that can be shared by the application. Sharing of the
- connection is possible since the "unit of work" for messaging with AMQP is
- actually a "channel" (in some ways, this is similar to the relationship
- between a Connection and a Session in JMS). As you can imagine, the
- connection instance provides a createChannel
- method. When creating an instance of
- SingleConnectionFactory, the 'hostname' can be
- provided via the constructor. The 'username' and 'password' properties
- should be provided as well.
+ The central component for managing a connection to the
+ RabbitMQ broker is the
+ ConnectionFactory interface. The
+ responsibility of a
+ ConnectionFactory implementation is
+ to provide an instance of
+ org.springframework.amqp.rabbit.connection.Connection
+ which is a wrapper for
+ com.rabbitmq.client.Connection. The
+ simplest implementation we provide is
+ SingleConnectionFactory which establishes a
+ single connection that can be shared by the application. Sharing
+ of the connection is possible since the "unit of work" for
+ messaging with AMQP is actually a "channel" (in some ways, this is
+ similar to the relationship between a Connection and a Session in
+ JMS). As you can imagine, the connection instance provides a
+ createChannel method. When creating an
+ instance of SingleConnectionFactory, the
+ 'hostname' can be provided via the constructor. The 'username' and
+ 'password' properties should be provided as well.
]]>
-
- There is also a
-
- CachingConnectionFactory
-
- implementation, which is superior to the
-
- SingleConnectionFactory
-
- in terms of performance and resilience. The
-
- CachingConnectionFactory
-
- should be considered the default for most practical usage, and
-
- SingleConnectionFactory
-
- as useful for simple tests and maybe as a building block for extending the framework.
- A ConnectionFactory can be created
- quickly and conveniently using the rabbit namespace: ]]>
- In most cases this will be preferable since the framework can choose the
- best defaults for you, and it will always choose a
+ There is also a
+ CachingConnectionFactory implementation,
+ which is superior to the
+ SingleConnectionFactory in terms of
+ performance and resilience. The
+ CachingConnectionFactory should be
+ considered the default for most practical usage, and
+ SingleConnectionFactory as useful for
+ simple tests and maybe as a building block for extending the
+ framework. A ConnectionFactory can
+ be created quickly and conveniently using the rabbit namespace:
+ ]]> In most cases this
+ will be preferable since the framework can choose the best
+ defaults for you, and it will always choose a
CachingConnectionFactory.
@@ -946,7 +942,7 @@ public class ExampleExternalTransactionAmqpConfiguration {
AMQP transactions only apply to messages and acks sent to the
broker, so when there is a rollback of a Spring transaction and a
- message has been received, wheat Spring AMQP has to do is not just
+ message has been received, what Spring AMQP has to do is not just
rollback the transaction, but also manually reject the message (sort of
a nack, but that's not what the specification calls it). Such messages
(and any that are unacked when a channel is closed or aborts) go to the
@@ -1081,4 +1077,118 @@ public class ExampleExternalTransactionAmqpConfiguration {
+
+
+ Resilience: Recovering from Errors and Broker Failures
+
+ Some of the key (and most popular) high-level features that
+ Spring AMQP provides are to do with recovery and automatic
+ re-connection in the event of a protocol error or broker failure.
+ We have seen all the relevant components already in this guide,
+ but it should help to bring them all together here and call out
+ the features and recovery scenarios individually.
+
+ The most important practical step if you want to take
+ advantage of these features is to use the
+ CachingConnectionFactory. It is also often
+ beneficial to use the RabbitAdmin
+ auto-declaration features. In addition, if you care about
+ guaranteed delivery, you probably also need to use the
+ channelTransacted flag in
+ RabbitTemplate and
+ SimpleMessageListenerContainer and also the
+ AcknowledgeMode.AUTO (or manual if you do the acks
+ yourself) in the
+ SimpleMessageListenerContainer.
+
+
+ Automatic Declararation of Exchanges, Queues and
+ Bindings
+
+ The RabbitAdmin component can
+ declare exchanges, queues and bindings on startup. It does this
+ lazily, through a ConnectionListener, so
+ if the broker is not present on startup it doesn't matter. The
+ first time a Connection is useed (e.g. by
+ sending a message) the listener will fire and the admin features
+ will be applied. A further benefit of doing the auto
+ declarations in a listener is that if the connection is dropped
+ for any reason (e.g. broker death, network glitch, etc.) they
+ will be applied again the next time they are needed.
+
+
+
+
+ Failures in Synchronous Operations and Options for Retry
+
+ If you lose your connection to the broker in a synchronous
+ sequence using RabbitTemplate (for
+ instance), then Spring AMQP will throw an
+ AmqpException (usually but not always
+ AmqpIOException). We don't try to hide
+ the fact that there was a problem, so you have to be able to
+ catch and respond to the exception. The easiest thing to do if
+ you suspect that the connection was lost, and it wasn't your
+ fault, is to simply try the operation again. You can do this
+ manually, or you could look at using Spring Retry to handle the
+ retry (imperatively or declaratively).
+
+ Spring Retry provides a couple of AOP interceptors and a
+ great deal of flexibility to specify the parameters of the retry
+ (number of attempts, exception types, backoff algorithm etc.).
+ Spring AMQP also provides some convenience factory beans for
+ creating Spring Retry interceptors in a convenient form for AMQP
+ use cases, with strongly typed callback interfaces for you to
+ implement custom recovery logic. See the Javadocs and
+ properties of
+ StatefulRetryOperationsInterceptor and
+ StatelessRetryOperationsInterceptor for
+ more detail. Stateless retry is appropriate if there is no
+ transaction or if a transaction is started inside the retry
+ callback. Note that stateless retry is simpler to configure and
+ analyse than stateful retry, but it is not usually appropriate
+ if there is an ongoing transaction which must be rolled back or
+ definitely is going to roll back. A dropped connection in the
+ middle of a transaction should have the same effect as a
+ rollback, so for reconnection where the transaction is started
+ higher up uthe stack, stateful retry is usually the best
+ choice.
+
+
+
+
+ Message Listeners and the Asynchronous Case
+
+ If a MessageListener fails because
+ of a business exception, the exception is handled by the message
+ listener container and then it goes back to listening for
+ another message. If the failure is caused by a dropped
+ conection (not a business exception), then the consumer that is
+ collecting messages for the listener has to be cancelled and
+ restarted. The
+ SimpleMessageListenerContainer handles
+ this seamlessly, and leaves a log to say that the listener is
+ being restarted. In fact it loops endlessly trying to restart
+ the consumer, and only if the consumer is very badly behaved
+ indeed will it give up. One side effect is that if the broker
+ is down when the container starts, it will just keep trying
+ until a connection can be established.
+
+ Business exception handling, as opposed to protocol errors
+ and dropped connections, might need more thought and some custom
+ configuration, especially if transactions and/or container acks
+ are in use. AMQP has no definition of dead letter behaviour, so
+ by default a message that is rejected or rolled back because of
+ a business exception can be redelivered ad infinitum. To put a
+ limit in the client on the number of re-deliveries your best
+ choice is a
+ StatefulRetryOperationsInterceptor in the
+ advice chain of the listener. The interceptor can have a
+ recovery callback that implements a custom dead letter action:
+ whatever is appropriate for your particular environment.
+
+
+
+
+
diff --git a/src/docbkx/index.xml b/src/docbkx/index.xml
index 482cc954..098b513a 100644
--- a/src/docbkx/index.xml
+++ b/src/docbkx/index.xml
@@ -39,19 +39,18 @@
-
Reference
diff --git a/src/docbkx/si-amqp.xml b/src/docbkx/si-amqp.xml
index 116f5da5..816114cc 100644
--- a/src/docbkx/si-amqp.xml
+++ b/src/docbkx/si-amqp.xml
@@ -8,19 +8,16 @@
Introduction
The Spring Integration project
- will include AMQP Channel Adapters and Gateways that build upon the Spring AMQP project as soon
- as the Spring AMQP project has a GA release. For now, those adapters are under development in the
- Spring Integration sandbox.
+ includes AMQP Channel Adapters and Gateways that build upon the Spring AMQP project. Those adapters are developed and released in the
+ Spring Integration project.
In Spring Integration, "Channel Adapters" are unidirectional (one-way) whereas "Gateways" are
- bidirectional (request-reply). Ultimately, we will be providing an inbound-channel-adapter,
- outbound-channel-adapter, inbound-gateway, and outbound-gateway. As of the time of the Spring AMQP 1.0
- Milestone 1 release, the 2 Channel Adapters are available. As mentioned, they are still in the "sandbox"
- and as such are subject to change and should not be depended upon in a production environment. That said,
- if you check out the project, you should be able to build it with Maven and experiment for yourself.
+ bidirectional (request-reply). We provide an inbound-channel-adapter,
+ outbound-channel-adapter, inbound-gateway, and outbound-gateway.
- When the AMQP adapters are part of an official Spring Integration release, the documentation
- will be available as part of the Spring Integration distribution. In the meantime, we will just
- provide a quick overview of the current state of that development here.
+ Since the AMQP adapters are part of the Spring Integration
+ release, the documentation will be available as part of the Spring
+ Integration distribution. As a taster, we just provide a quick
+ overview of the main features here.
@@ -48,13 +45,33 @@
Inbound Gateway
- Coming Soon
+ To receive an AMQP Message from a Queue, and respond to an
+ Exchange, configure an <inbound-gateway>. A
+ 'routing-key' may optionally be provided in addition to the
+ exchange name.
+
+ ]]>
+
Outbound Gateway
- Coming Soon
+ To send AMQP Messages to an Exchange and receive back a
+ response from a remote client, configure an
+ <outbound-gateway>. A 'routing-key' may optionally be
+ provided in addition to the exchange name.
+
+ ]]>