Difficulty: beginner
Estimated Time: 15 minutes

In this scenario you will learn more about developing Spring Boot Microservices using the Red Hat OpenShift Application Runtimes platform. You will learn what the Circuit Breaker pattern is and why it's useful in an environment where we have multiple third party services that we need to call. Then we'll take a look at how it's implemented and see the functionality live within the OpenShift environment to really demonstrate the value that we gain from it.

In this scenario you learned about Spring Boot and how it can be used to create Microservices with the Circuit Breaker pattern. We will add additional scenarios that explain more how to build Spring Boot applications on OpenShift shortly, so check back to learn.openshift.com

To summarize: We first started our application with the Circuit Breaker pattern implemented and our circuit in the Closed state. We confirmed this by hitting our secondary external service and getting back our expected response. However we then manually took the service down, forcing the calls to the Name service to fail. We confirmed this by attempting to make the call ourselves, and our circuit responded with our backup response. This meant that our circuit was in the Open state. In order to get our application back into a working state, we restarted the Name service. When we attempted our call again, our circuit checked and saw that the Name service was online and went back into the Closed state, returning our initial value again.

Spring Boot is a powerful and easy to use framework for developing everything from monolithic applications to microservices, but Spring Boot becomes every better when we package it in a container and use an orchestrated platform like OpenShift. When using OpenShift we can, in a very consistent and fast way, deploy our Spring application to multiple environments without worry of environment differences. OpenShift also enables things like Deployment Pipelines and Blue/Green deployments but that was not covered in this scenario.

Additional Resources

More background and related information on Red Hat OpenShift Application Runtimes and Eclipse Vert.x can be found here:

  • Red Hat OpenShift Application Runtimes for Developers - Here you can get started with a project using different boosters and clone that project to your local computer. This also enables you to deploy your application on your own private OpenShift Container Platform or use OpenShift Online that is provided for free from Red Hat.
  • Project Snowdrop homepage - This site has a lot of details of the work that Red Hat is doing to make Spring work great on Kubernetes and OpenShift.

Don’t stop now! The next scenario will only take about 10 minutes to complete.

Fault Tolerance and Resiliency

Step 1 of 3

Step 1

Review the base structure of the application

For your convenience, this scenario has been created using the OpenShift Launcher found here. This launcher will automatically generate a zip file of a project that's in a ready-to-deploy state. We've selected the Circuit Breaker project and will be using the Spring Boot runtime option.

1. Understanding the Application

The project is a simple Greeting application with two services: a Greeting service and a Name service. When you invoke the Greeting service, it makes a call to our secondary Name service. The name service returns the name of the user which our greeting service then greets.

However there is one problem: our greeting service is dependent on the name service. If the name service were to crash or go offline for some amount of time our greeting service would fail for the entire duration Name service is unavailable. This is an issue that can arise when we have multiple microservices communicating with one another and one solution is to use something called a Circuit Breaker pattern.

2. The Circuit Breaker Pattern

The Circuit Breaker pattern's purpose is to make sure that failing remote calls don't crash a system or cause unwarranted behavior. They do this by wrapping the desired function call into a circuit breaker object that monitors the attempted calls. When there is a failure, or the failures reach some boundary the user created, the circuit will trip (entering the Open state) and no further calls will be made to our remote service. Instead we can send back some default value or some response alerting the user what's happened.

Once the circuit is tripped no calls can be made to the failing service. However if we were to keep the circuit in this state we could never call the remote service again. In order to work around this issue, we can poll after some defined interval to see if the remote service is responding yet. If it responds, it means that the issue has been fixed and the circuit is again in the Closed state. If not, we can keep the circuit closed and wait for another interval to try again. Sometimes this in-between state of not knowing if the service is up is called a Half-Open state.

You can read more about the Circuit Breaker pattern and see some helpful diagrams here.

3. Implementation of the Circuit Breaker pattern

Our two-service application is currently implementing this pattern. If we take a look at our fruit-service/src/main/java/io/openshift/booster/service/FruitController.java file, we see that our simple controller is simply calling our NameService. Below we will add some code to the project. Click the Copy to Editor button to do this automatically

    @RequestMapping("/api/greeting")
    public Fruit getFruit() throws Exception {
        String result = String.format("You've picked %s!", nameService.getName());
        handler.sendMessage(nameService.getState());
        return new Fruit(result);
    }

If we take a look at the NameService class fruit-service/src/main/java/io/openshift/booster/service/NameService.java We see that we're using something called Hystrix. Hystrix is a Java library created by Netflix that is used to handle cascading failures and provide fallback options. We use it here to handle our circuit breaking pattern. If we take a look at the code, we see that we're setting a timeout for the given Hystrix command:

    @HystrixCommand(commandKey = "NameService", fallbackMethod = "getFallbackName", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")
    })

We're telling Hystrix to call a given fallback method (getFallbackName) if our execution takes longer than the given timeout allotment and return that value instead. This means that on a timeout, we will be returning the value Fallback instead of the given name. We can see that function below:

    private String getFallbackName() {
        return "banana from fallback";
    }

So if our circuit is Closed, we expect to see a message similar to You've picked apple!. If we have an Open circuit we will see You've picked banana from fallback!.

Congratulations

You have now successfully executed the first step in this scenario. We learned about the Circuit Breaker pattern and saw how we could implement the pattern in our application. In the next step we will log in to OpenShift so we can deploy our application.

To learn more about Hystrix, view their Github wiki page here.

Terminal
Local Web Browser
OpenShift Console