February 12, 2017
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.
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
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")
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).