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. + + ]]>