Skip to content

Netflix Hystrix & Eureka with Redis Cache

Furkan Kürşat Danışmaz edited this page Sep 21, 2018 · 6 revisions

Source Folder: hystrix

Tech Stack:

  • spring-boot
  • spring-mvc
  • spring-data-redis
  • netflix-hystrix
  • netflix-eureka
  • log4j2 (slf4j impl)
  • project lombok

This is a sample project demonstrating a resilient backend with Netflix Hystrix & service discovery with Netflix Eureka. Also REDIS is used as an external cache in this project.

NOTE Before reading this, I suggesst you to take a look on eureka and Caching with Redis

Scenario

  • A client makes a request
  • Main request handler needs to call another service to answer the client's request.
    • Main request handler calls the other service
    • The other service responds successfully.
    • Main request handler puts the response to REDIS in case the other service might not be available in the future
      • What if the external cache system is not available?
        • The response is not cached
        • Main request handler returns response.
    • What if the other service is down?
      • Main request handler calls the other service
      • The other service is not available
      • Main request handler looks to the cache
      • The main request handler reads requested data from cache
        • What if the external cache system is not available?
          • The main request handler fails silent and returns null

This architecture will return null in cases:

  • If the REST endpoint is not available AND (there is no related data in the cache OR cache is not available)

It will return data on the other hand:

  • If the REST endpoint is available (whether or not the cache is avaible)
  • If the REST endpoint is not available but the requested data exists in the cache

System Components

In this project, we have 4 modules:

  • Eureka Server: The service registry
  • Eureka Client: An application containing a RESTful Web Service
  • Eureka Feign Client: The actual application that the client knows and interacts
  • REDIS: The external caching system

Circuit Breaker Pattern

  • A failure in a service dependency should not take down entire system.
  • An API should automatically take corrective action when one of its dependencies fails.
  • Fallback, fail silent, fail fast

Steps to be taken:

  • Wrap all calls to external systems in a HystrixCommand or HystrixObservableCommand
  • Time out the calls that take longer than your threshold
  • Enable circuit breaker
  • Perform fallback when a request to an external system fails

Some Important Notes

  • To enable hystrix request scoped features like caching we must manage HystrixRequestContext lifecycle.
// Before request
HystrixRequestContext context = HystrixRequestContext.initializeContext();

// After request
context.shutdown();

This can easily implemented with Servlet Filters:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) 
  throws IOException, ServletException {
        log.debug("Initializing HystrixRequestContext");
        HystrixRequestContext hystrixRequestContext = HystrixRequestContext.initializeContext();
        try {
            filterChain.doFilter(request, response);
        }
        finally {
            log.debug("Shutting down HystrixRequestContext");
            hystrixRequestContext.shutdown();
        }
    }
  • Set aggressive timeouts to improve UX
  • You can use @HystrixCommand annotation with Javanica (comes with spring-cloud-starter-hystrix)
  • Set spring.redis.timeout so that your system does not wait too much while REDIS is not available

References: