Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

MicroProfile Fault Tolerance in WildFly Swarm

March 8, 2018
Antoine Sabot-Durand
Related topics:
JavaMicroservices

Share:

    Every developer has the goal of building the most resilient application possible. Due to the distributed nature of microservices, resiliency and handling failures gracefully is mandatory. The Java ecosystem has some nice frameworks for fault tolerance, such as Hystrix or Failsafe. However, none of these provide a standard API, so using them means your application will be tightly coupled to that framework. The primary motivation for the MicroProfile specifications is to provide standard APIs that eliminates the tight coupling and improves deployment flexibility. This article will describe the main features of the MicroProfile Fault Tolerance specification, and then demonstrate how it was implemented in WildFly Swarm, the Red Hat MicroProfile implementation.

    About Eclipse MicroProfile Fault Tolerance

    Eclipse MicroProfile Fault Tolerance is one of the Eclipse MicroProfile specifications that provides a standard and easy way to add resiliency to your microservice or other Java EE development.
    Note: see Jeff Mesnil's article on Develop Cloud-native Applications with MicroProfile

    Like most MicroProfile specifications, Fault Tolerance is based on Contexts and Dependency Injection (CDI) and more precisely on the CDI interceptor implementation. It also relies on the MicroProfile Config specification to allow external configuration for Fault Tolerance policies.

    The main idea of the spec is to decouple business logic from Fault Tolerance boilerplate code. To achieve that, the spec defines interceptor binding annotations to apply Fault Tolerance policies on a method execution or on a class (in that case all class methods have the same policy).

    Policies included in the Fault Tolerance specification are the following:

    • Timeout: applied with @Timeout annotation. It adds a timeout to the current operation.
    • Retry: applied with @Retry annotation. It adds retry behavior and allows its configuration on the current operation.
    • Fallback: applied with @Fallback annotation. It defines the code to execute, should the current operation fail.
    • Bulkhead: applied with @Bulkhead annotation. It isolates failures in the current operation to preserve execution of other operations.
    • Circuit Breaker: applied with @CircuitBreaker annotation. It provides an automatic fast failing execution to prevent overloading the system.
    • Asynchronous: applied with @Asynchronous annotation. It makes the current operation asynchronous (i.e. code will be invoked asynchronously).

    Applying one or more of these policies is as easy as adding the required annotations on the method (or the class) for which you'd like to have these policies enabled. So, using Fault Tolerance is rather simple. But this simplicity doesn't prevent flexibility thanks to all the configuration parameters available for each policy.

    Right now the following vendors are providing an implementation for the specification.

    • Red Hat in WildFly Swarm
    • IBM in WebSphere Liberty
    • Payara in Payara Server
    • Apache Safeguard for Hammock and TomEE
    • KumuluzEE for KumuluzEE framework

    In this post we will focus on the WildFly Swarm implementation and usage.

    Using MicroProfile Fault Tolerance in WildFly Swarm

    MicroProfile Fault Tolerance implementation included in WildFly Swarm is based on Hystrix Framework developed by Netflix.

    To add Fault Tolerance to your WildFly Swarm project, you only have to add the Fault Tolerance fraction to your project like this:

    <dependency>
       <groupId>org.wildfly.swarm</groupId>
       <artifactId>microprofile-fault-tolerance</artifactId>
    </dependency>

    No need to add other fractions, the Fault Tolerance fraction will add all its dependencies to the deployment.

    MicroProfile Fault Tolerance in Action

    As we saw above, using Fault Tolerance is quite straightforward. The spec API provides a set of annotations that you have to apply on a class or method to enforce Fault Tolerance policies. This said, you have to keep in mind that these annotations are interceptors binding and thus are only usable on CDI beans, so be careful to define your class as CDI beans before applying Fault Tolerance annotations on them or their methods.

    In the following sections you'll find usage examples for each Fault Tolerance annotation.

    @Asynchronous

    Making an operation asynchronous is as simple as:

    @Asynchronous
    public Future<Connection> service() throws InterruptedException {
        Connection conn = new Connection() {
          {
            Thread.sleep(1000);
          }
        @Override
        public String getData() {
          return "service DATA";
        }
      };
      return CompletableFuture.completedFuture(conn);
    }

    The only constraint is to have the @Asynchronous method returning a Future otherwise the implementation should throw an exception.

    @Retry

    Should the operation fail you can apply the Retry policy to have the operation invoked again. The @Retry annotation can be used on class or method level like this:

    @Retry(maxRetries = 5, maxDuration= 1000, retryOn = {IOException.class})
    public void operationToRetry() {
        ...
    }

    In the example above, the operation should be retried a maximum 5 times only on IOException. If the total duration of all retries lasts more than 1000 ms the operation will be aborted.

    @Fallback

    This annotation can only be applied on a method, annotating a class will give an unexpected result:

    @Retry(maxRetries = 2)
    @Fallback(StringFallbackHandler.class)
    public String shouldFallback() {
    	 ...
    }

    Fallback method is called after the number of retries is reached. In the example above, the method will be retried twice in case of an error, and then the fallback will be used to invoke another piece of code.

    Fallback code can be defined by class implementing FallbackHandler interface (see the code above), or by a method in the current bean.

    @Timeout

    This annotation could be applied on class or method to make sure that an operation doesn't last forever.

    @Timeout(200) 
    public void operationCouldTimeout() {
        ...
    }

    In the example above the operation will be stopped should it last more than 200 ms.

    @CircuitBreaker

    The annotation can be applied on class or method. The circuit breaker pattern was introduced by Martin Fowler to protect execution of an operation by making it fail fast in case of a dysfunction.

    @CircuitBreaker(requestVolumeThreshold = 4, failureRatio=0.75, delay = 1000)
    public void operationCouldBeShortCircuited(){
      ...
    }

    In the above example, the method applies the CircuitBreaker policy. The circuit will be opened if 3 (4 x 0.75) failures occur among the rolling window of 4 consecutive invocations. The circuit will stay open for 1000 ms and then be back to half open. After a successful invocation, the circuit will be back to closed again.

    @Bulkhead

    This annotation can also be applied on class or method to enforce the Bulkhead policy. This pattern isolates failures in the current operation to preserve execution of other operations. The implementation does this by limiting the number of concurrent invocations on a given method.

    @Bulkhead(4)
    public void bulkheadedOperation() {
           ...
    }

    In the code above this method only supports 4 invocations at the same time.
    Bulkhead can also be used with @Asynchronous to limit the thread number in an asynchronous operation.

    Configure Fault Tolerance with MP config

    As we saw in the previous sections, Fault Tolerance policies are applied by using annotations. For most use cases this is enough, but for others this approach may be not be satisfactory because configuration is done at the source code level.

    That's the reason MicroProfile Fault Tolerance annotations' parameters can be overridden using the MicroProfile config.

    The annotation parameters can be overwritten via config properties in the naming convention of: <classname>/<methodname>/<annotation>/<parameter>.

    To override the maxDuration for @Retry on the doSomething method in MyService class, set the config property like this:

    com.redhat.microservice.MyService/doSomething/Retry/maxDuration=3000

    If the parameters for a particular annotation needs to be configured with the same value for a particular class, use the config property: <classname>/<annotation>/<parameter> for configuration.

    For instance, use the following config property to override all maxRetries for the @Retry specified on the class MyService to 100.

    com.redhat.microservice.MyService/Retry/maxRetries=100

    Sometimes, the parameters need to be configured with the same value for the whole micro service (i.e. all occurrences of the annotation in the deployment).

    In this circumstance, the config property <annotation>/<parameter> overrides the corresponding parameter value for the specified annotation. For instance, in order to override all the maxRetries for all the @Retry to be 30, specify the following config property:

    Retry/maxRetries=30

    Conclusion

    This post is only an overview of the specification. To learn everything about it, you can find the MicroProfile Fault Tolerance 1.0 specification document here. Another way to learn how the spec works is by checking its TCK (Technology Compatibility Kit).

    The specification is rather young, and yet it already has 5 implementations. If you'd like to get involved in the spec, you can start by completing an issue on the MicroProfile Fault Tolerance repo, or just start working on one of them.

    You can also help us to enhance Fault Tolerance implementation (or any other MicroProfile implementation) in the WildFly Swarm repo, or report a bug on our Jira server.

    Last updated: October 17, 2018

    Recent Posts

    • Skopeo: The unsung hero of Linux container-tools

    • Automate certificate management in OpenShift

    • Customize RHEL CoreOS at scale: On-cluster image mode in OpenShift

    • How to set up KServe autoscaling for vLLM with KEDA

    • How I used Cursor AI to migrate a Bash test suite to Python

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue