How to implement Circuit Breaker Pattern using Hystrix in Spring Cloud Gateway

Introduction

We will see how to implement circuit breaker pattern using Hystrix in Spring Cloud Gateway.

Hystrix is a library from Netflix that implements the circuit breaker pattern. The Hystrix GatewayFilter allows us to introduce circuit breakers to our gateway routes, protecting our services from cascading failures and allowing us to provide fallback responses in the event of downstream failures.

To enable Hystrix GatewayFilters in our project, we need to add a dependency on spring-cloud-starter-netflix-hystrix from Spring Cloud Netflix.

The Hystrix GatewayFilter Factory requires a single name parameter, which is the name of the HystrixCommand.

When Hystrix times out we can optionally provide a fallback so that clients do not just received a 504 (gateway timeout) but something more meaningful. In a production scenario we may return some data from a cache for example, but in our simple example we will just return a response with the body of some meaningful message.

Prerequisites

How to build Spring Cloud Gateway for Microservices

Update build.gradle Script

Now we need to update the build.gradle script to include the required dependency for Hystrix from Netflix library.

implementation("org.springframework.cloud:spring-cloud-starter-netflix-hystrix")

The whole build.gradle script file is given below:

buildscript {
	ext {
		springBootVersion = '2.2.6.RELEASE'
	}
    repositories {
    	mavenLocal()
    	mavenCentral()
    }
    dependencies {
    	classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

plugins {
    id "io.spring.dependency-management" version "1.0.9.RELEASE"
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
    
sourceCompatibility = 12
targetCompatibility = 12

repositories {
	mavenLocal()
    mavenCentral()
}

dependencies {
	implementation("org.springframework.cloud:spring-cloud-starter")
	implementation("org.springframework.cloud:spring-cloud-starter-gateway")
	implementation("org.springframework.cloud:spring-cloud-starter-netflix-hystrix")
	implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client")
}

dependencyManagement {
    imports {
        mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR3'
    }
}

Update application.yml File

Now we will update the src/main/resources/application.yml file to implement the circuit breaker using Hytrix command.

Look at the below configuration file carefully. We have added few configurations.

We have put timeout as 2 seconds for connecting to the service APIs and if the gateway does not connect within 2 seconds or if any service is down, then fallback URI will be called.

hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 2000

server:
   port: 9090
   
spring:
   application:
       name: gateway
   cloud:
       gateway:
           routes:
            - id: currency-conversion-service
              #uri: http://localhost:9100/
              uri: lb://currency-conversion-service/
              predicates:
               - Path=/cc-converter/**
              filters:
               - RewritePath=/cc-converter/from/(?<from>.*)/to/(?<to>.*)/quantity/(?<quantity>.*), /currency-converter/from/$\{from}/to/$\{to}/quantity/$\{quantity}
               - name: Hystrix
                 args:
                    name: hystrixFx
                    fallbackUri: forward:/cc-converter/fallback
            - id: forex-service
              #uri: http://localhost:9000/, http://localhost:9001/
              uri: lb://forex-service/
              predicates:
               - Path=/fx-exchange/**
              filters:
               - RewritePath=/fx-exchange/from/(?<from>.*)/to/(?<to>.*), /forex-exchange/from/$\{from}/to/$\{to}
               - name: Hystrix
                 args:
                    name: hystrixCc
                    fallbackUri: forward:/fx-exchange/fallback
           discovery:
              locator:
                 enabled: true
                 lower-case-service-id: true

eureka:
   client:
      service-url:
         default-zone: http://localhost:8761/eureka

The fallback section added in the above configuration file is similar to the below snippets:

- name: Hystrix
  args:
	name: <command name>
	fallbackUri: forward:<URI>

This wraps the remaining filters in a HystrixCommand with <command name>.

The Hystrix filter can also accept an optional fallbackUri parameter. Currently, only forward: schemed URIs are supported. If the fallback is called, the request will be forwarded to the controller matched by the URI.

Create Fallback Controller

Create a Spring REST controller class with the below source code.

package com.roytuts.spring.cloud.gateway.rest.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import reactor.core.publisher.Mono;

@RestController
public class HystrixFallbackRestController {

	@GetMapping("/fx-exchange/fallback")
	public Mono<String> getFxSvcMsg() {
		return Mono.just("No response fron Forex Service and will be back shortly");
	}

	@GetMapping("/cc-converter/fallback")
	public Mono<String> getCcSvcMsg() {
		return Mono.just("No response fron Currency Conversion Service and will be back shortly");
	}

}

Testing the Application

Make sure your all applications are deployed into the respective servers. The below youtube video will show you the output.

Download

Thanks for reading.

Leave a Comment