### Configure Hystrix to use Servo Metrics Publisher and Publish to Graphite Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-servo-metrics-publisher/README.md This example shows how to register the HystrixServoMetricsPublisher with Hystrix plugins and configure minimal Servo settings to publish metrics to Graphite. Ensure Servo's PollScheduler is started and a Poller task is added. ```java // Registry plugin with hystrix HystrixPlugins.getInstance().registerMetricsPublisher(HystrixServoMetricsPublisher.getInstance()); ........ // Minimal Servo configuration for publishing to Graphite final List observers = new ArrayList(); observers.add(new GraphiteMetricObserver(getHostName(), "graphite-server.example.com:2003")); PollScheduler.getInstance().start(); PollRunnable task = new PollRunnable(new MonitorRegistryMetricPoller(), BasicMetricFilter.MATCH_ALL, true, observers); PollScheduler.getInstance().addPoller(task, 5, TimeUnit.SECONDS); ``` -------------------------------- ### Run Hystrix Examples Web App via Gradle Source: https://github.com/netflix/hystrix/blob/master/hystrix-examples-webapp/README.md Clone the Hystrix repository, navigate to the examples web app directory, and run the application using Gradle. The application will be available at http://localhost:8989/hystrix-examples-webapp. ```bash $ git clone git@github.com:Netflix/Hystrix.git $ cd Hystrix/hystrix-examples-webapp $ ../gradlew appRun ``` -------------------------------- ### HystrixCommand Metrics Example Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-metrics-event-stream/README.md Example JSON payload for HystrixCommand metrics. This data is emitted continuously as long as a client connection is maintained. ```json data: { "type": "HystrixCommand", "name": "PlaylistGet", "group": "PlaylistGet", "currentTime": 1355239617628, "isCircuitBreakerOpen": false, "errorPercentage": 0, "errorCount": 0, "requestCount": 121, "rollingCountCollapsedRequests": 0, "rollingCountExceptionsThrown": 0, "rollingCountFailure": 0, "rollingCountFallbackFailure": 0, "rollingCountFallbackRejection": 0, "rollingCountFallbackSuccess": 0, "rollingCountResponsesFromCache": 69, "rollingCountSemaphoreRejected": 0, "rollingCountShortCircuited": 0, "rollingCountSuccess": 121, "rollingCountThreadPoolRejected": 0, "rollingCountTimeout": 0, "currentConcurrentExecutionCount": 0, "latencyExecute_mean": 13, "latencyExecute": { "0": 3, "25": 6, "50": 8, "75": 14, "90": 26, "95": 37, "99": 75, "99.5": 92, "100": 252 }, "latencyTotal_mean": 15, "latencyTotal": { "0": 3, "25": 7, "50": 10, "75": 18, "90": 32, "95": 43, "99": 88, "99.5": 160, "100": 253 }, "propertyValue_circuitBreakerRequestVolumeThreshold": 20, "propertyValue_circuitBreakerSleepWindowInMilliseconds": 5000, "propertyValue_circuitBreakerErrorThresholdPercentage": 50, "propertyValue_circuitBreakerForceOpen": false, "propertyValue_circuitBreakerForceClosed": false, "propertyValue_circuitBreakerEnabled": true, "propertyValue_executionIsolationStrategy": "THREAD", "propertyValue_executionIsolationThreadTimeoutInMilliseconds": 800, "propertyValue_executionIsolationThreadInterruptOnTimeout": true, "propertyValue_executionIsolationThreadPoolKeyOverride": null, "propertyValue_executionIsolationSemaphoreMaxConcurrentRequests": 20, "propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests": 10, "propertyValue_metricsRollingStatisticalWindowInMilliseconds": 10000, "propertyValue_requestCacheEnabled": true, "propertyValue_requestLogEnabled": true, "reportingHosts": 1 } ``` -------------------------------- ### Maven Dependency for Hystrix Examples Source: https://github.com/netflix/hystrix/blob/master/hystrix-examples/README.md Add this Maven dependency to include the Hystrix examples module in your project. ```xml com.netflix.hystrix hystrix-examples 1.0.2 ``` -------------------------------- ### Hystrix Stream Data Example 2 Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-metrics-event-stream-jaxrs/README.md This is another example of Hystrix stream data, showing metrics for the 'CryptexDecrypt' command, including updated reporting hosts and latency values. ```json data: {"rollingCountFailure":0,"propertyValue_executionIsolationThreadInterruptOnTimeout":true,"rollingCountTimeout":0,"rollingCountExceptionsThrown":0,"rollingCountFallbackSuccess":0,"errorCount":0,"type":"HystrixCommand","propertyValue_circuitBreakerEnabled":true,"reportingHosts":3,"latencyTotal":{"0":1,"95":1,"99.5":1,"90":1,"25":1,"99":1,"75":1,"100":1,"50":1},"currentConcurrentExecutionCount":0,"rollingCountSemaphoreRejected":0,"rollingCountFallbackRejection":0,"rollingCountShortCircuited":0,"rollingCountResponsesFromCache":0,"propertyValue_circuitBreakerForceClosed":false,"name":"CryptexDecrypt","propertyValue_executionIsolationThreadPoolKeyOverride":"null","rollingCountSuccess":1,"propertyValue_requestLogEnabled":true,"requestCount":1,"rollingCountCollapsedRequests":0,"errorPercentage":0,"propertyValue_circuitBreakerSleepWindowInMilliseconds":15000,"latencyTotal_mean":1,"propertyValue_circuitBreakerForceOpen":false,"propertyValue_circuitBreakerRequestVolumeThreshold":60,"propertyValue_circuitBreakerErrorThresholdPercentage":150,"propertyValue_executionIsolationStrategy":"THREAD","rollingCountFallbackFailure":0,"isCircuitBreakerOpen":false,"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests":60,"propertyValue_executionIsolationThreadTimeoutInMilliseconds":3000,"propertyValue_metricsRollingStatisticalWindowInMilliseconds":30000,"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests":30,"latencyExecute":{"0":0,"95":0,"99.5":0,"90":0,"25":0,"99":0,"75":0,"100":0,"50":0},"group":"CRYPTEX","latencyExecute_mean":0,"propertyValue_requestCacheEnabled":true,"rollingCountThreadPoolRejected":0} ``` -------------------------------- ### Ivy Dependency for Hystrix Examples Source: https://github.com/netflix/hystrix/blob/master/hystrix-examples/README.md Add this Ivy dependency to include the Hystrix examples module in your project. ```xml ``` -------------------------------- ### Build Hystrix Project with Gradle Source: https://github.com/netflix/hystrix/blob/master/README.md Commands to clone the Hystrix repository and build the project using Gradle. Requires Git and Gradle to be installed. ```bash $ git clone git@github.com:Netflix/Hystrix.git $ cd Hystrix/ $ ./gradlew build ``` -------------------------------- ### HystrixObservableCommand Hello World Example Source: https://github.com/netflix/hystrix/wiki/How-To-Use An equivalent 'Hello World' implementation using HystrixObservableCommand. This is suitable for commands that may emit multiple values or need to be integrated with reactive streams. ```java public class CommandHelloWorld extends HystrixObservableCommand { private final String name; public CommandHelloWorld(String name) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.name = name; } @Override protected Observable construct() { return Observable.create(new Observable.OnSubscribe() { @Override public void call(Subscriber observer) { try { if (!observer.isUnsubscribed()) { // a real example would do work like a network call here observer.onNext("Hello"); observer.onNext(name + "!"); observer.onCompleted(); } } catch (Exception e) { observer.onError(e); } } } ).subscribeOn(Schedulers.io()); } } ``` -------------------------------- ### Implement Request-Scoped HystrixCollapser Source: https://github.com/netflix/hystrix/wiki/How-To-Use Example of a request-scoped collapser that batches requests for a specific key. It defines how to get the request argument, create the batch command, and map the batch response back to individual requests. Requires Hystrix library. ```java public class CommandCollapserGetValueForKey extends HystrixCollapser, String, Integer> { private final Integer key; public CommandCollapserGetValueForKey(Integer key) { this.key = key; } @Override public Integer getRequestArgument() { return key; } @Override protected HystrixCommand> createCommand(final Collection> requests) { return new BatchCommand(requests); } @Override protected void mapResponseToRequests(List batchResponse, Collection> requests) { int count = 0; for (CollapsedRequest request : requests) { request.setResponse(batchResponse.get(count++)); } } private static final class BatchCommand extends HystrixCommand> { private final Collection> requests; private BatchCommand(Collection> requests) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")) .andCommandKey(HystrixCommandKey.Factory.asKey("GetValueForKey"))); this.requests = requests; } @Override protected List run() { ArrayList response = new ArrayList(); for (CollapsedRequest request : requests) { // artificial response for each argument received in the batch response.add("ValueForKey: " + request.getArgument()); } return response; } } } ``` -------------------------------- ### Hystrix Gradle Build Output Source: https://github.com/netflix/hystrix/wiki/Getting-Started Example output of a successful Gradle build for the Hystrix project, showing compilation, testing, and packaging steps. ```text $ ./gradlew build :hystrix-core:compileJava :hystrix-core:processResources UP-TO-DATE :hystrix-core:classes :hystrix-core:jar :hystrix-core:sourcesJar :hystrix-core:signArchives SKIPPED :hystrix-core:assemble :hystrix-core:licenseMain UP-TO-DATE :hystrix-core:licenseTest UP-TO-DATE :hystrix-core:compileTestJava :hystrix-core:processTestResources UP-TO-DATE :hystrix-core:testClasses :hystrix-core:test :hystrix-core:check :hystrix-core:build :hystrix-examples:compileJava :hystrix-examples:processResources UP-TO-DATE :hystrix-examples:classes :hystrix-examples:jar :hystrix-examples:sourcesJar :hystrix-examples:signArchives SKIPPED :hystrix-examples:assemble :hystrix-examples:licenseMain UP-TO-DATE :hystrix-examples:licenseTest UP-TO-DATE :hystrix-examples:compileTestJava :hystrix-examples:processTestResources UP-TO-DATE :hystrix-examples:testClasses :hystrix-examples:test :hystrix-examples:check :hystrix-examples:build BUILD SUCCESSFUL Total time: 30.758 secs ``` -------------------------------- ### Run Hystrix Demo Application Source: https://github.com/netflix/hystrix/blob/master/README.md Instructions to clone the Hystrix repository and run the demo application using Gradle. This will display example command execution outputs. ```bash $ git clone git@github.com:Netflix/Hystrix.git $ cd Hystrix/ ./gradlew runDemo ``` -------------------------------- ### Hystrix Demo Application Output Example Source: https://github.com/netflix/hystrix/blob/master/README.md Sample output from running the Hystrix demo application, illustrating successful and failed command executions, including cached responses and fallback successes. ```text Request => GetUserAccountCommand[SUCCESS][8ms], GetPaymentInformationCommand[SUCCESS][20ms], GetUserAccountCommand[SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][101ms], CreditCardCommand[SUCCESS][1075ms] Request => GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS][2ms], GetPaymentInformationCommand[SUCCESS][22ms], GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][130ms], CreditCardCommand[SUCCESS][1050ms] Request => GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS][4ms], GetPaymentInformationCommand[SUCCESS][19ms], GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][145ms], CreditCardCommand[SUCCESS][1301ms] Request => GetUserAccountCommand[SUCCESS][4ms], GetPaymentInformationCommand[SUCCESS][11ms], GetUserAccountCommand[SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][93ms], CreditCardCommand[SUCCESS][1409ms] ##################################################################################### # CreditCardCommand: Requests: 17 Errors: 0 (0%) Mean: 1171 75th: 1391 90th: 1470 99th: 1486 # GetOrderCommand: Requests: 21 Errors: 0 (0%) Mean: 100 75th: 144 90th: 207 99th: 230 # GetUserAccountCommand: Requests: 21 Errors: 4 (19%) Mean: 8 75th: 11 90th: 46 99th: 51 ``` -------------------------------- ### Hystrix Demo Output Example Source: https://github.com/netflix/hystrix/blob/master/hystrix-examples/README.md Sample output from the Hystrix demo application, illustrating command execution results, success/failure states, response times, and cached responses. ```text Request => GetUserAccountCommand[SUCCESS][8ms], GetPaymentInformationCommand[SUCCESS][20ms], GetUserAccountCommand[SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][101ms], CreditCardCommand[SUCCESS][1075ms] Request => GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS][2ms], GetPaymentInformationCommand[SUCCESS][22ms], GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][130ms], CreditCardCommand[SUCCESS][1050ms] Request => GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS][4ms], GetPaymentInformationCommand[SUCCESS][19ms], GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][145ms], CreditCardCommand[SUCCESS][1301ms] Request => GetUserAccountCommand[SUCCESS][4ms], GetPaymentInformationCommand[SUCCESS][11ms], GetUserAccountCommand[SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][93ms], CreditCardCommand[SUCCESS][1409ms] ##################################################################################### # CreditCardCommand: Requests: 17 Errors: 0 (0%) Mean: 1171 75th: 1391 90th: 1470 99th: 1486 # GetOrderCommand: Requests: 21 Errors: 0 (0%) Mean: 100 75th: 144 90th: 207 99th: 230 # GetUserAccountCommand: Requests: 21 Errors: 4 (19%) Mean: 8 75th: 11 90th: 46 99th: 51 # GetPaymentInformationCommand: Requests: 21 Errors: 0 (0%) Mean: 18 75th: 21 90th: 24 99th: 25 ##################################################################################### Request => GetUserAccountCommand[SUCCESS][10ms], GetPaymentInformationCommand[SUCCESS][16ms], GetUserAccountCommand[SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][51ms], CreditCardCommand[SUCCESS][922ms] Request => GetUserAccountCommand[SUCCESS][12ms], GetPaymentInformationCommand[SUCCESS][12ms], GetUserAccountCommand[SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][68ms], CreditCardCommand[SUCCESS][1257ms] Request => GetUserAccountCommand[SUCCESS][10ms], GetPaymentInformationCommand[SUCCESS][11ms], GetUserAccountCommand[SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][78ms], CreditCardCommand[SUCCESS][1295ms] Request => GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS][6ms], GetPaymentInformationCommand[SUCCESS][11ms], GetUserAccountCommand[FAILURE, FALLBACK_SUCCESS, RESPONSE_FROM_CACHE][0ms]x2, GetOrderCommand[SUCCESS][153ms], CreditCardCommand[SUCCESS][1321ms] ``` -------------------------------- ### Get User by ID with CacheKey Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-javanica/README.md Retrieves a user by ID, using the ID as the cache key. Requires no specific setup. ```java public User getUserById(@CacheKey String id) { return storage.get(id); } ``` -------------------------------- ### HystrixThreadPool Metrics Example Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-metrics-event-stream/README.md Example JSON payload for HystrixThreadPool metrics. This data provides insights into thread pool utilization and task counts. ```json data: { "currentPoolSize": 30, "rollingMaxActiveThreads": 13, "currentActiveCount": 0, "currentCompletedTaskCount": 4459519, "propertyValue_queueSizeRejectionThreshold": 30, "type": "HystrixThreadPool", "reportingHosts": 3, "propertyValue_metricsRollingStatisticalWindowInMilliseconds": 30000, "name": "ABClient", "currentLargestPoolSize": 30, "currentCorePoolSize": 30, "currentQueueSize": 0, "currentTaskCount": 4459519, "rollingCountThreadsExecuted": 919, "currentMaximumPoolSize": 30 } ``` -------------------------------- ### Define a Hystrix Command Source: https://github.com/netflix/hystrix/blob/master/README.md Encapsulate code to be isolated within the run() method of a HystrixCommand. This example defines a simple 'Hello World' command. ```java public class CommandHelloWorld extends HystrixCommand { private final String name; public CommandHelloWorld(String name) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.name = name; } @Override protected String run() { return "Hello " + name + "!"; } } ``` -------------------------------- ### Hystrix Stream Data Example 1 Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-metrics-event-stream-jaxrs/README.md This is an example of the JSON data received from the Hystrix stream endpoint, showing metrics for the 'IdentityCookieAuthSwitchProfile' command. ```json data: {"rollingCountFailure":0,"propertyValue_executionIsolationThreadInterruptOnTimeout":true,"rollingCountTimeout":0,"rollingCountExceptionsThrown":0,"rollingCountFallbackSuccess":0,"errorCount":0,"type":"HystrixCommand","propertyValue_circuitBreakerEnabled":true,"reportingHosts":1,"latencyTotal":{"0":0,"95":0,"99.5":0,"90":0,"25":0,"99":0,"75":0,"100":0,"50":0},"currentConcurrentExecutionCount":0,"rollingCountSemaphoreRejected":0,"rollingCountFallbackRejection":0,"rollingCountShortCircuited":0,"rollingCountResponsesFromCache":0,"propertyValue_circuitBreakerForceClosed":false,"name":"IdentityCookieAuthSwitchProfile","propertyValue_executionIsolationThreadPoolKeyOverride":"null","rollingCountSuccess":0,"propertyValue_requestLogEnabled":true,"requestCount":0,"rollingCountCollapsedRequests":0,"errorPercentage":0,"propertyValue_circuitBreakerSleepWindowInMilliseconds":5000,"latencyTotal_mean":0,"propertyValue_circuitBreakerForceOpen":false,"propertyValue_circuitBreakerRequestVolumeThreshold":20,"propertyValue_circuitBreakerErrorThresholdPercentage":50,"propertyValue_executionIsolationStrategy":"THREAD","rollingCountFallbackFailure":0,"isCircuitBreakerOpen":false,"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests":20,"propertyValue_executionIsolationThreadTimeoutInMilliseconds":1000,"propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000,"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests":10,"latencyExecute":{"0":0,"95":0,"99.5":0,"90":0,"25":0,"99":0,"75":0,"100":0,"50":0},"group":"IDENTITY","latencyExecute_mean":0,"propertyValue_requestCacheEnabled":true,"rollingCountThreadPoolRejected":0} ``` -------------------------------- ### Unsupported: Sync Command, Async Fallback (No @HystrixCommand on Fallback) Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-javanica/README.md This case is unsupported for the same reasons as the previous example. The caller of a sync command expects a direct result, not a Future from an async fallback. ```java @HystrixCommand(fallbackMethod = "fallbackAsync") User getUserById(String id) { throw new RuntimeException("getUserById command failed"); } Future fallbackAsync(String id) { return new AsyncResult() { @Override public User invoke() { return new User("def", "def"); } }; } ``` -------------------------------- ### Hystrix Command Metrics Streams Source: https://github.com/netflix/hystrix/wiki/Metrics-and-Monitoring Observes command execution start and completion events. Requires HystrixCommandKey. ```java Observable observeCommandStartStream(HystrixCommandKey key) Observable observeCommandCompletionStream(HystrixCommandKey key) ``` -------------------------------- ### Hystrix Fallback Exception Propagation Example Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-javanica/README.md Demonstrates how exceptions are propagated when a command has a fallback. Only the first exception that triggers the fallback logic is propagated to the caller. ```java class Service { @HystrixCommand(fallbackMethod = "fallback") Object command(Object o) throws CommandException { throw new CommandException(); } @HystrixCommand Object fallback(Object o) throws FallbackException { throw new FallbackException(); } } // in client code { try { service.command(null); } catch (Exception e) { assert CommandException.class.equals(e.getClass()) } } ``` -------------------------------- ### Hystrix Static Fallback Example Source: https://context7.com/netflix/hystrix/llms.txt Use a static fallback to return a default safe value when the primary command fails. This is useful for simple, predictable defaults. ```java public class GetFeatureFlagCommand extends HystrixCommand { private final String flagName; public GetFeatureFlagCommand(String flagName) { super(HystrixCommandGroupKey.Factory.asKey("FeatureFlags")); this.flagName = flagName; } @Override protected Boolean run() throws Exception { return featureFlagService.isEnabled(flagName); } @Override protected Boolean getFallback() { // Default to safe value return true; } } ``` -------------------------------- ### HystrixRequestContextServletFilter Example Source: https://github.com/netflix/hystrix/wiki/How-To-Use A Servlet Filter implementation to manage the HystrixRequestContext lifecycle for all incoming web requests. It initializes the context before the request and shuts it down afterwards. ```java public class HystrixRequestContextServletFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HystrixRequestContext context = HystrixRequestContext.initializeContext(); try { chain.doFilter(request, response); } finally { context.shutdown(); } } } ``` -------------------------------- ### Get User by Profile Name with CacheKey and HystrixCommand Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-javanica/README.md Retrieves a user by profile name, using a specific key from the User object for caching. Requires @HystrixCommand. ```java @CacheResult @HystrixCommand public void getUserByProfileName(@CacheKey("profile.email") User user) { storage.getUserByProfileName(user.getProfile().getName()); } ``` -------------------------------- ### DefaultProperties Annotation Example Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-javanica/README.md Demonstrates how @DefaultProperties sets default groupKey for Hystrix commands. An explicit groupKey in @HystrixCommand overrides the default. ```java @DefaultProperties(groupKey = "DefaultGroupKey") class Service { @HystrixCommand // hystrix command group key is 'DefaultGroupKey' public Object commandInheritsDefaultProperties() { return null; } @HystrixCommand(groupKey = "SpecificGroupKey") // command overrides default group key public Object commandOverridesGroupKey() { return null; } } ``` -------------------------------- ### Get User by Name with CacheResult and HystrixCommand Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-javanica/README.md Retrieves a user by name, caching the result using a method specified by getUserByNameCacheKey. Requires @HystrixCommand. ```java @CacheResult(cacheKeyMethod = "getUserByNameCacheKey") @HystrixCommand public User getUserByName(String name) { return storage.getByName(name); } private Long getUserByNameCacheKey(String name) { return name; } ``` -------------------------------- ### Unit Test Hystrix Request Cache With Hits Source: https://github.com/netflix/hystrix/wiki/How-To-Use Illustrates testing Hystrix command caching behavior within a request context. This example shows how to verify cache hits and misses, and how cache state resets across different request contexts. ```java @Test public void testWithCacheHits() { HystrixRequestContext context = HystrixRequestContext.initializeContext(); try { CommandUsingRequestCache command2a = new CommandUsingRequestCache(2); CommandUsingRequestCache command2b = new CommandUsingRequestCache(2); assertTrue(command2a.execute()); // this is the first time we've executed this command with // the value of "2" so it should not be from cache assertFalse(command2a.isResponseFromCache()); assertTrue(command2b.execute()); // this is the second time we've executed this command with // the same value so it should return from cache assertTrue(command2b.isResponseFromCache()); } finally { context.shutdown(); } // start a new request context context = HystrixRequestContext.initializeContext(); try { CommandUsingRequestCache command3b = new CommandUsingRequestCache(2); assertTrue(command3b.execute()); // this is a new request context so this // should not come from cache assertFalse(command3b.isResponseFromCache()); } finally { context.shutdown(); } } ``` -------------------------------- ### Handle Network Events in Java Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-network-auditor-agent/README.md Example implementation for handling network events. It checks if the current thread is executing a Hystrix command, increments counters for non-isolated events, and captures stack traces for debugging. ```java @Override public void handleNetworkEvent() { if (Hystrix.getCurrentThreadExecutingCommand() == null) { // increment counter totalNonIsolatedEventsCounter.increment(); // capture the stacktrace and record so network events can be debugged and tracked down StackTraceElement[] stack = Thread.currentThread().getStackTrace(); HystrixNetworkEvent counter = counters.get(stack); if (counter == null) { counter = new HystrixNetworkEvent(stack); HystrixNetworkEvent c = counters.putIfAbsent(Arrays.toString(stack), counter); if (c != null) { // another thread beat us counter = c; } } counter.increment(); } } ``` -------------------------------- ### Setting Thread Pool Properties with @HystrixCommand Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-javanica/README.md Configures both command and thread pool properties using @HystrixCommand. This example sets execution timeout, core size, queue size, and other metrics properties. ```java @HystrixCommand(commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "500") }, threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "30"), @HystrixProperty(name = "maxQueueSize", value = "101"), @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"), @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"), @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"), @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440") }) public User getUserById(String id) { return userResource.getUserById(id); } ``` -------------------------------- ### Construct HystrixCommandKey Source: https://github.com/netflix/hystrix/wiki/How-To-Use Constructs and interns HystrixCommandKey instances using the HystrixCommandKey.Factory.asKey() helper method. This is the recommended way to create command keys. ```java HystrixCommandKey.Factory.asKey("HelloWorld") ``` -------------------------------- ### Test Request Cache Invalidation Behavior Source: https://github.com/netflix/hystrix/wiki/How-To-Use This unit test verifies the Get-Set-Get cache invalidation pattern. It asserts that the initial Get retrieves data, a subsequent Get from cache is confirmed, a Set operation invalidates the cache, and a final Get retrieves the updated data without using the cache. ```java @Test public void getGetSetGet() { HystrixRequestContext context = HystrixRequestContext.initializeContext(); try { assertEquals("ValueBeforeSet_1", new GetterCommand(1).execute()); GetterCommand commandAgainstCache = new GetterCommand(1); assertEquals("ValueBeforeSet_1", commandAgainstCache.execute()); // confirm it executed against cache the second time assertTrue(commandAgainstCache.isResponseFromCache()); // set the new value new SetterCommand(1, "ValueAfterSet_").execute(); // fetch it again GetterCommand commandAfterSet = new GetterCommand(1); // the getter should return with the new prefix, not the value from cache assertFalse(commandAfterSet.isResponseFromCache()); assertEquals("ValueAfterSet_1", commandAfterSet.execute()); } finally { context.shutdown(); } } } ``` -------------------------------- ### Building Hystrix with Gradle Source: https://github.com/netflix/hystrix/wiki/Getting-Started Builds the Hystrix project using Gradle. This command compiles the code, runs tests, and packages the artifacts. ```bash ./gradlew build ``` -------------------------------- ### Executing a Hystrix Command Source: https://github.com/netflix/hystrix/wiki/Getting-Started Demonstrates different ways to execute a Hystrix command: synchronously with 'execute()', asynchronously with 'queue()' returning a Future, or as an Observable with 'observe()'. ```java String s = new CommandHelloWorld("Bob").execute(); Future s = new CommandHelloWorld("Bob").queue(); Observable s = new CommandHelloWorld("Bob").observe(); ``` -------------------------------- ### Configure HystrixRequestContextServletFilter in web.xml Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-request-servlet/README.md Install the HystrixRequestContextServletFilter in your web.xml to initialize and clean up HystrixRequestContext for each HTTP request. ```xml HystrixRequestContextServletFilter HystrixRequestContextServletFilter com.netflix.hystrix.contrib.requestservlet.HystrixRequestContextServletFilter HystrixRequestContextServletFilter /* ``` -------------------------------- ### Configure HystrixRequestLogViaLoggerServletFilter in web.xml Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-request-servlet/README.md Install the HystrixRequestLogViaLoggerServletFilter in your web.xml to log executed Hystrix commands at the end of each request. ```xml HystrixRequestLogViaLoggerServletFilter HystrixRequestLogViaLoggerServletFilter com.netflix.hystrix.contrib.requestservlet.HystrixRequestLogViaLoggerServletFilter HystrixRequestLogViaLoggerServletFilter /* ``` -------------------------------- ### Apache 2.0 License Header for New Files Source: https://github.com/netflix/hystrix/blob/master/CONTRIBUTING.md When adding a new file to the Hystrix project, include this standard Apache 2.0 license header. Ensure all fields are accurate. ```java /** * Copyright 2013 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ ``` -------------------------------- ### JSR107 Cache Removal Example Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-javanica/README.md Demonstrates cache invalidation using JSR107 annotations with a custom cache key generator. ```java @CacheRemove(cacheName = "getUserById", cacheKeyGenerator = UserCacheKeyGenerator.class) @HystrixCommand public void update(@CacheKey User user) { storage.put(user.getId(), user); } public static class UserCacheKeyGenerator implements HystrixCacheKeyGenerator { @Override public HystrixGeneratedCacheKey generateCacheKey(CacheKeyInvocationContext cacheKeyInvocationContext) { CacheInvocationParameter cacheInvocationParameter = cacheKeyInvocationContext.getKeyParameters()[0]; User user = (User) cacheInvocationParameter.getValue(); return new DefaultHystrixGeneratedCacheKey(user.getId()); } } ``` -------------------------------- ### Construct HystrixCommand Object Source: https://github.com/netflix/hystrix/wiki/How-it-Works Instantiate a HystrixCommand for dependencies expected to return a single response. Pass necessary arguments to the constructor. ```java HystrixCommand command = new HystrixCommand(arg1, arg2); ``` -------------------------------- ### Hystrix Thread Pool Metrics Streams Source: https://github.com/netflix/hystrix/wiki/Metrics-and-Monitoring Observes thread pool execution start and completion events. Requires HystrixThreadPoolKey. ```java Observable observeThreadPoolStartStream(HystrixThreadPoolKey key) Observable observeThreadPoolCompletionStream(HystrixThreadPoolKey key) ``` -------------------------------- ### Reactive Execution with HystrixCommand Source: https://context7.com/netflix/hystrix/llms.txt Use `observe()` for hot observables that execute immediately, or `toObservable()` for cold observables that execute on subscription. Subscribe to handle results and combine multiple reactive commands using `Observable.merge()`. ```java public class GetProductCommand extends HystrixCommand { private final String productId; public GetProductCommand(String productId) { super(HystrixCommandGroupKey.Factory.asKey("ProductCatalog")); this.productId = productId; } @Override protected Product run() throws Exception { return productCatalog.getProduct(productId); } @Override protected Product getFallback() { return Product.unavailable(productId); } } // Hot Observable - executes immediately Observable hotObservable = new GetProductCommand("prod-123").observe(); // Cold Observable - executes only when subscribed Observable coldObservable = new GetProductCommand("prod-456").toObservable(); // Subscribe to handle results hotObservable.subscribe( product -> System.out.println("Received: " + product.getName()), error -> System.err.println("Error: " + error.getMessage()), () -> System.out.println("Completed") ); // Combine multiple reactive commands Observable.merge( new GetProductCommand("prod-1").observe(), new GetProductCommand("prod-2").observe(), new GetProductCommand("prod-3").observe() ).subscribe(product -> System.out.println("Product: " + product.getName())); ``` -------------------------------- ### Get Latest Synchronous Mean Source: https://github.com/netflix/hystrix/wiki/Metrics-and-Monitoring Fetch the latest calculated mean value from the bucketing distribution synchronously. Requires Hystrix core. ```java int getLatestMean() ``` -------------------------------- ### Initialize HystrixCommand with Instance Defaults Source: https://github.com/netflix/hystrix/wiki/Configuration Instantiate a HystrixCommand with a group key and a specific default execution timeout. This constructor simplifies setting common initial values. ```java public HystrixCommandInstance(int id) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() .withExecutionTimeoutInMilliseconds(500))); this.id = id; } ``` -------------------------------- ### Enable Hystrix Network Auditor Agent Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-network-auditor-agent/README.md Add this to the JVM command-line to enable the agent. It instruments `java.net` and `java.io` classes. ```bash -javaagent:/var/root/hystrix-network-auditor-agent-x.y.zjar ``` -------------------------------- ### Register Hystrix Codahale Metrics Publisher Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-codahale-metrics-publisher/README.md Plug in the Hystrix Codahale Metrics Publisher by registering it with HystrixPlugins. Ensure you provide an initialized Coda Hale MetricRegistry. ```java HystrixPlugins.getInstance().registerMetricsPublisher(new HystrixCodahaleMetricsPublisher(yourMetricRegistry)); ``` -------------------------------- ### Get Latest Synchronous Histogram Data Source: https://github.com/netflix/hystrix/wiki/Metrics-and-Monitoring Retrieve the most recent histogram data synchronously from bucketing distributions. Useful for immediate state checks. ```java CachedValuesHistogram getLatest() ``` -------------------------------- ### Construct HystrixCommandGroupKey Source: https://github.com/netflix/hystrix/wiki/How-To-Use Constructs and interns HystrixCommandGroupKey instances using the HystrixCommandGroupKey.Factory.asKey() helper method. This is used for grouping commands. ```java HystrixCommandGroupKey.Factory.asKey("ExampleGroup") ``` -------------------------------- ### Observe Bucketed Distributions as a Stream Source: https://github.com/netflix/hystrix/wiki/Metrics-and-Monitoring Treat bucketing distributions as a stream to get the latest aggregate histogram. Requires Hystrix core library. ```java Observable observe() ``` -------------------------------- ### Hystrix Primary-Secondary Command Execution Source: https://github.com/netflix/hystrix/wiki/How-To-Use Demonstrates a Hystrix command that can execute either a primary or secondary logic based on configuration. Includes unit tests for both scenarios. ```java public static class CommandFacadeWithPrimarySecondary extends HystrixCommand { private final int id; public CommandFacadeWithPrimarySecondary(int id) { // call primary or secondary based on configuration super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("PrimarySecondaryGroup")) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() // we default to a 100ms timeout for secondary .withExecutionTimeoutInMilliseconds(100))); this.id = id; } @Override protected String run() { // perform fast 'secondary' service call return "responseFromSecondary-" + id; } } public static class UnitTest { @Test public void testPrimary() { HystrixRequestContext context = HystrixRequestContext.initializeContext(); try { ConfigurationManager.getConfigInstance().setProperty("primarySecondary.usePrimary", true); assertEquals("responseFromPrimary-20", new CommandFacadeWithPrimarySecondary(20).execute()); } finally { context.shutdown(); ConfigurationManager.getConfigInstance().clear(); } } @Test public void testSecondary() { HystrixRequestContext context = HystrixRequestContext.initializeContext(); try { ConfigurationManager.getConfigInstance().setProperty("primarySecondary.usePrimary", false); assertEquals("responseFromSecondary-20", new CommandFacadeWithPrimarySecondary(20).execute()); } finally { context.shutdown(); ConfigurationManager.getConfigInstance().clear(); } } } ``` -------------------------------- ### Execute HystrixCommand Asynchronously Source: https://github.com/netflix/hystrix/wiki/How-To-Use Execute a HystrixCommand asynchronously using the queue() method. Retrieve the result using the Future object's get() method. ```java Future fs = new CommandHelloWorld("World").queue(); ``` ```java String s = fs.get(); ``` ```java assertEquals("Hello World!", new CommandHelloWorld("World").queue().get()); assertEquals("Hello Bob!", new CommandHelloWorld("Bob").queue().get()); ``` ```java Future fWorld = new CommandHelloWorld("World").queue(); Future fBob = new CommandHelloWorld("Bob").queue(); assertEquals("Hello World!", fWorld.get()); assertEquals("Hello Bob!", fBob.get()); ``` ```java String s1 = new CommandHelloWorld("World").execute(); String s2 = new CommandHelloWorld("World").queue().get(); ``` -------------------------------- ### Execute Hystrix Commands Source: https://github.com/netflix/hystrix/wiki/How-it-Works Demonstrates various methods to execute Hystrix commands: execute() for blocking single response, queue() for a Future, observe() for a hot Observable, and toObservable() for a cold Observable. All commands are ultimately backed by an Observable. ```java K value = command.execute(); Future fValue = command.queue(); Observable ohValue = command.observe(); //hot observable Observable ocValue = command.toObservable(); //cold observable ``` -------------------------------- ### Define and Execute Hystrix Command in Clojure Source: https://github.com/netflix/hystrix/blob/master/hystrix-contrib/hystrix-clj/README.md Wrap a function with `defcommand` to make it a Hystrix dependency. Execute it directly or queue for asynchronous processing. ```clojure (defn make-request [arg] ... make the request ...) ; execute the request (make-request "baz") ``` ```clojure (defcommand make-request [arg] ... make the request ...) ; execute the request (make-request "baz") ; or queue for async execution (queue #'make-request "baz") ``` -------------------------------- ### Hystrix Request Stream JSON Output Source: https://github.com/netflix/hystrix/wiki/Metrics-and-Monitoring Example JSON output from the Hystrix request events SSE stream, detailing command names, events, and latencies. ```json data: [[{"name":"GetOrderCommand","events":["SUCCESS"],"latencies":[111]},{"name":"GetPaymentInformationCommand","events":["SUCCESS"],"latencies":[15]},{"name":"GetUserAccountCommand","events":["TIMEOUT","FALLBACK_SUCCESS"],"latencies":[59],"cached":2},{"name":"CreditCardCommand","events":["SUCCESS"],"latencies":[957]}],[{"name":"GetUserAccountCommand","events":["SUCCESS"],"latencies":[3],"cached":2},{"name":"GetOrderCommand","events":["SUCCESS"],"latencies":[77]},{"name":"GetPaymentInformationCommand","events":["SUCCESS"],"latencies":[21]},{"name":"CreditCardCommand","events":["SUCCESS"],"latencies":[1199]}]]) ``` -------------------------------- ### Hystrix Utilization Stream JSON Output Source: https://github.com/netflix/hystrix/wiki/Metrics-and-Monitoring Example JSON output from the Hystrix utilization SSE stream, showing active counts for commands and thread pools. ```json data: {"type":"HystrixUtilization","commands":{"CreditCardCommand":{"activeCount":0},"GetUserAccountCommand":{"activeCount":0},"GetOrderCommand":{"activeCount":1},"GetPaymentInformationCommand":{"activeCount":0}},"threadpools":{"User":{"activeCount":0,"queueSize":0,"corePoolSize":8,"poolSize":2},"CreditCard":{"activeCount":0,"queueSize":0,"corePoolSize":8,"poolSize":1},"Order":{"activeCount":1,"queueSize":0,"corePoolSize":8,"poolSize":2},"PaymentInformation":{"activeCount":0,"queueSize":0,"corePoolSize":8,"poolSize":2}}} ``` -------------------------------- ### Download Hystrix Dependencies using Maven Source: https://github.com/netflix/hystrix/blob/master/README.md Command to execute a Maven build using a specific POM file to download Hystrix core and its dependencies. The JARs will be placed in the './target/dependency/' directory. ```bash mvn -f download-hystrix-pom.xml dependency:copy-dependencies ``` -------------------------------- ### Get Default Command Name Source: https://github.com/netflix/hystrix/wiki/How-To-Use Retrieves the default command name using the class's simple name. This is the default behavior if no explicit name is provided. ```java getClass().getSimpleName(); ``` -------------------------------- ### Primary-Secondary Facade with Hystrix Source: https://context7.com/netflix/hystrix/llms.txt This command routes requests to either a primary or secondary service based on a dynamic configuration property. It uses semaphore isolation and defines distinct thread pools for primary and secondary commands, each with its own timeout. ```java public class PrimarySecondaryFacade extends HystrixCommand { private static final DynamicBooleanProperty usePrimary = DynamicPropertyFactory.getInstance() .getBooleanProperty("service.usePrimary", true); private final String requestId; public PrimarySecondaryFacade(String requestId) { super(Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey("ServiceFacade")) .andCommandKey(HystrixCommandKey.Factory.asKey("PrimarySecondaryFacade")) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() // Use semaphore since we're delegating to other commands .withExecutionIsolationStrategy( HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE))); this.requestId = requestId; } @Override protected String run() throws Exception { if (usePrimary.get()) { return new PrimaryServiceCommand(requestId).execute(); } else { return new SecondaryServiceCommand(requestId).execute(); } } @Override protected String getFallback() { return "static-fallback-" + requestId; } // Primary service command with its own thread pool private static class PrimaryServiceCommand extends HystrixCommand { private final String requestId; PrimaryServiceCommand(String requestId) { super(Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey("ServiceFacade")) .andCommandKey(HystrixCommandKey.Factory.asKey("PrimaryService")) .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("PrimaryServicePool")) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() .withExecutionTimeoutInMilliseconds(1000))); this.requestId = requestId; } @Override protected String run() throws Exception { return primaryService.execute(requestId); } } // Secondary service command with its own thread pool private static class SecondaryServiceCommand extends HystrixCommand { private final String requestId; SecondaryServiceCommand(String requestId) { super(Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey("ServiceFacade")) .andCommandKey(HystrixCommandKey.Factory.asKey("SecondaryService")) .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("SecondaryServicePool")) .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() .withExecutionTimeoutInMilliseconds(500))); // Faster timeout for cache this.requestId = requestId; } @Override protected String run() throws Exception { return secondaryService.execute(requestId); } } } ``` ```java // Usage - automatically routes based on configuration String result = new PrimarySecondaryFacade("request-123").execute(); ``` ```java // Switch to secondary at runtime ConfigurationManager.getConfigInstance() .setProperty("service.usePrimary", false); ```