My Avatar

(require 'thoughts)

80% engineer, 30% photographer, very good at math.

Configure Hystrix in Clojure

2017-02-12, published at San Francisco

Hystrix is an amazing tool to help stop cascading failure and enable resilience in complex distributed systems. It is pretty straightforward to integrate it with your Clojure web applications, and works well out-of-the-box. However, if you want to modify Hystrix’s default behaviors, this tutorial will show you a few different ways to do so.

In fact, Hystrix leverages its plugin system which gives you full control over how properties are defined for the system. By default it uses Archaius as the default implementation, so the methods mentioned below would apply to any applications using the same for configuration management.

The full example code can be found in this repo.

config.properties File

This is my preferred way to configure Hystrix because it is more explicit. The default location for config.properties file is under resources, for example, if you create resources/config.properties with the following content:

# Hystrix global config
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=6000

# Hystrix config per group / command key
hystrix.command.helloWorld.execution.isolation.thread.timeoutInMilliseconds=8000

Once you start your application, you might see some log lines like this:

2017-02-12 16:26:59 INFO  URLConfigurationSource:127 - URLs to be used as dynamic configuration source: [file:/.../resources/config.properties]
2017-02-12 16:26:59 INFO  DynamicPropertyFactory:266 - DynamicPropertyFactory is initialized with configuration sources: com.netflix.config.ConcurrentCompositeConfiguration@77d2e85

System Properties

Another way to do this is to manipulate System Properties directly. For example, to setup global default timeout:

(System/setProperty "hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds" "2000")

or a command key specific setting:

(System/setProperty "hystrix.command.helloWorld.execution.isolation.thread.timeoutInMilliseconds" "2000")

ConfigurationManager Interface

You can also config Hystrix through the ConfigurationManager, if you prefer to programmatically generating those configs within the application. Here is an example of how it could work:

(ns try-hystrix
  (:import (com.netflix.config ConfigurationManager)))

(defn set-hystrix-config!
  [cmd-key k v]
  (let [key (format "hystrix.command.%s.%s" cmd-key k)]
    (.setProperty (ConfigurationManager/getConfigInstance) key v)))

; Example usage
(set-hystrix-config! "helloWorld" "circuitBreaker.requestVolumeThreshold" 10)
(set-hystrix-config! "helloWorld" "circuitBreaker.errorThresholdPercentage" 60)

And just the same as using system properties, these need to run at the entry point of the application (the -main method as an example).