## Failover Protocol

### Overview

The failover protocol overlays reconnect logic on top of any of the other transports. The failover URI is composed of multiple URIs that represent different broker endpoints. By default, the protocol randomly chooses a URI from the list and attempts to establish a connection to it. If it does not succeed, or if it subsequently fails, a new connection is established to one of the other URIs in the list.

### Configuration syntax

A `failover` URI must conform to the following syntax:

    failover://(uri1,...,uriN)?TransportOptions

Where the URI list, `uri1``,...,``uriN`, is a comma-separated list containing one or more broker endpoint URIs. The transport options, `?``TransportOptions`, are specified in the form of a query list (where the supported options are described in Table 6.1 ). If no transport options are required, you can use the following alternative syntax:

    failover://uri1,...,uriN

### Transport options

The failover protocol supports the transport options described in Table 6.1 .

Table 6.1. Failover Transport Options

Option Name | Default | Description
--- | --- | ---
`initialReconnectDelay` | `10` | How long to wait before the first reconnect attempt (in ms).
`maxReconnectDelay` | `30000` | The maximum amount of time to wait between reconnect attempts (in ms).
`useExponentialBackOff` | `true` | If `true`, use an exponential back-off between reconnect attempts.
`backOffMultiplier` | `2` | The exponent used in the exponential back-off algorithm.
`maxReconnectAttempts` | `0` | If not `0`, this is the maximum number of reconnect attempts before an error is sent back to the client.
`randomize` | `true` | If `true`, choose a URI at random from the list provided.

### Sample URI

The following is an example of a failover URI that randomly connects to one of two message brokers:

    failover://(tcp://localhost:61616,tcp://remotehost:61616)?initialReconnectDelay=100

### Example of using the failover protocol

To try out the failover protocol, perform the following steps:

1. Start up broker A .

2. Start up consumer A .

3. Start up broker B .

4. Start up consumer B .

5. Start up a producer with failover URL .

6. Kill the active broker .

### Start up broker A

Assuming that you have already configured a simple broker cluster as described in Configuring a Simple Broker Cluster , start broker A by running the relevant script. For example:

    broker_a

### Start up consumer A

Start a consumer that consumes messages from the `TEST.FOO` queue on broker A. The consumer tool is located in the `example` directory of the FUSE Message Broker install directory, `InstallDir`. Assuming that broker A’s TCP connector is listening on port `61716` on the local host, open a new command window and start consumer A as follows:

    cd InstallDir/example
    ant consumer -Durl=tcp://localhost:61716 -Dmax=100

The consumer tool should log output similar to the following as it starts up:

    Buildfile: build.xmlinit:compile:consumer:     [echo] Running consumer
    against server at $url = tcp://localhost:61716 for subject $subject = TEST.FOO
       [java] Connecting to URL: tcp://localhost:61716     [java] Consuming
    queue: TEST.FOO     [java] Using a non-durable subscription     [java] We
    are about to wait until we consume: 100 message(s) then we will shutdown

### Start up broker B

Start broker B by running the relevant script. For example, open a new command window and enter:

    broker_b

### Start up consumer B

Start a consumer that consumes messages from the `TEST.FOO` queue on broker B. Assuming that broker B’s TCP connector is listening on port `61816` on the local host, open a new command window and start consumer B as follows:

    cd InstallDir/example
    ant consumer -Durl=tcp://localhost:61816 -Dmax=100

### Start up a producer with failover URL

Start a producer with a failover URL such that it can connect either to broker A or to broker B. Open a new command window and start the producer as follows:

    cd InstallDir/example
    ant producer -Durl="failover://(tcp://localhost:61716,tcp://localhost:61816)?initialReconnectDelay=100"
    -DsleepTime=5000

It is important to include the double quotes around the failover URL, otherwise the comma-separated list would be parsed as two arguments. The sleep time is set to 5 seconds between messages, in order to give you enough time to perform the next step.

### Kill the active broker

After starting the producer, observe which of the consumers is receiving messages. If consumer A is receiving messages, the producer must be connected to broker A, in which case broker A is the active broker. If consumer B is receiving messages, broker B is the active broker.

To test the failover functionality on the producer side, kill the active broker (not consumer!) by switching focus to the relevant broker window and typing `Ctrl-C`. If the producer is still producing messages (it produces ten in total), it will attempt to reconnect to the other broker. You should see output similar to the following in the producer log:

         [java] 13:50:31 WARN  Transport failed, attempting to automatically reconnect due to: java.io.EOFException
         [java] java.io.EOFException
         [java]     at java.io.DataInputStream.readInt(DataInputStream.java:358) ...
         [java] Sending message: Message: 7 sent at: Wed Oct 10 13:50:31 BST 2007  ...
         [java] 13:50:32 INFO  Successfully reconnected to tcp://localhost:61716