Skip to content

rickhanlonii/lyra

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lyra

High availability RabbitMQ client

Introduction

Dealing with failure is a fact of life in distributed systems. Lyra is a RabbitMQ client that embraces failure, helping you achieve high availability in your services by automatically recovering AMQP resources such as connections, channels and consumers when server or network failures occur. Lyra also supports automatic invocation retries, and exposes a simple, lightweight API built around the Java AMQP client library.

Setup

Add the Lyra dependency:

<dependency>
  <groupId>net.jodah</groupId>
  <artifactId>lyra</artifactId>
  <version>0.3.2</version>
</dependency>

Also add the latest amqp-client dependency:

<dependency>
  <groupId>com.rabbitmq</groupId>
  <artifactId>amqp-client</artifactId>
  <version>3.2.1</version>
</dependency>

Usage

Resource Recovery

The key feature of Lyra is its ability to automatically recover resources such as Connections, Channels and Consumers when unexpected failures occur. To start, create a Config object, specifying a recovery policy:

Config config = new Config()
	.withRecoveryPolicy(new RecoveryPolicy()
		.withMaxAttempts(20)
		.withInterval(Duration.seconds(1))
		.withMaxDuration(Duration.minutes(5)));

With our config, let's create a recoverable Connection along with some Channels and Consumers:

ConnectionOptions options = new ConnectionOptions()
	.withHost("localhost");
Connection connection = Connections.create(options, config);
Channel channel1 = connection.createChannel(1);
Channel channel2 = connection.createChannel(2);
channel1.basicConsume("foo-queue", consumer1);
channel1.basicConsume("bar-queue", consumer2);
channel2.basicConsume("foo-queue", consumer3);
channel2.basicConsume("bar-queue", consumer4);

This results in the resource hierarchy:

<img src="http://jodah.net/lyra/assets/img/rabbit-graph.png"\>

If one of these resources is unexpectedly closed, it will be recovered according to the recovery policy. If the Connection is unexpectedly closed, Lyra will attempt to recover it along with its Channels and Consumers. If a Channel is unexpectedly closed, Lyra will attempt to recover it along with its Consumers.

Invocation Retries

Lyra also supports invocation retries when a retryable failure occurs while creating a Connection or invoking a method against a Connection or Channel. For example:

ConnectionOptions options = new ConnectionOptions()
	.withHost("localhost");
Config config = new Config()
	.withRecoveryPolicy(RecoveryPolicies.recoverAlways())
	.withRetryPolicy(new RetryPolicy()
		.withBackoff(Duration.seconds(1), Duration.seconds(30))
		.withMaxDuration(Duration.minutes(10)));
		
Connection connection = Connections.create(options, config);
Channel channel = connection.createChannel();
channel.basicConsume("foo-queue", myConsumer);

Here we've created a new Connection and Channel, specifying a recovery policy to use in case any of our resources are unexpectedly closed as a result of an invocation failure, and a retry policy that dictates how and when the failed method invocation should be retried. If the Connections.create(), connection.createChannel(), or channel.basicConsume() method invocations fail as the result of a retryable error, Lyra will attempt to recover any resources that were closed according to the recovery policy and retry the invocation according to the retry policy.

Resource Configuration

Lyra allows for resource configuration to be applied at different levels. For example, global recovery and global retry policies can be configured for all resources. These policies can be overriden with specific policies for connection attempts, connections and channels. Lyra also allows for individual connections and channels to be re-configured after creation:

ConfigurableConnection configurableConnection = Config.of(connection);
ConfigurableChannel configurableChannel = Config.of(channel);

Event Listeners

Lyra offers listeners for creation and recovery events:

Config config = new Config();
	.withConnectionListeners(myConnectionListener)
	.withChannelListeners(myChannelListener)
	.withConsumerListeners(myConsumerListener);

Event listeners can be useful for setting up additional resources during recovery, such as auto-deleted exchanges and queues.

Cookbook

See the Lyra cookbook for handling various Rabbit use cases.

Additional Notes

On Recovery and Retry Policies

Recovery and retry policies allow you to specify:

  • The maximum number of attempts to perform
  • The maxmimum duration that attempts should be performed for
  • The interval between attempts
  • The maximum interval between attempts to exponentially backoff to

Lyra allows for recovery and retry policies to be set globally, for individual resource types, and for initial connection attempts.

On Retryable Failures

Lyra will only retry failed invocations that are deemed retryable. These include connection errors that are not related to failed authentication, and channel or connection errors that might be the result of temporary network failures.

On Threading

When a Connection or Channel are closed unexpectedly recovery occurs in a background thread. If the resource was closed as the result of an invocation and a retry policy is configured, the calling thread will block until the Connection/Channel is recovered and the retry can be performed.

On Message Delivery

When a channel is closed and recovered, any messages that were delivered but not acknowledged will be redelivered on the newly recovered channel. Attempts to ack/nack/reject messages that were delivered before the channel was recovered are simply ignored since their delivery tags will be invalid for the newly recovered channel.

Note, since channel recovery happens transparently, in effect when a channel is recovered and message redelivery occurs messages may be seen more than once on the recovered channel.

Docs

JavaDocs are available here.

License

Copyright 2013 Jonathan Halterman - Released under the Apache 2.0 license.

About

High availability RabbitMQ client

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 99.9%
  • Shell 0.1%