{"id":18429048,"url":"https://github.com/openliberty/guide-microprofile-istio-retry-fallback","last_synced_at":"2025-04-07T17:32:25.669Z","repository":{"id":40350260,"uuid":"200861182","full_name":"OpenLiberty/guide-microprofile-istio-retry-fallback","owner":"OpenLiberty","description":"A guide on how to manage the impact of failures by using MicroProfile and Istio Fault Tolerance to add retry and fallback behaviours to microservices.","archived":false,"fork":false,"pushed_at":"2025-02-13T20:57:18.000Z","size":646,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"prod","last_synced_at":"2025-03-22T21:51:11.712Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://openliberty.io/guides/microprofile-istio-retry-fallback.html","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenLiberty.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-06T13:51:11.000Z","updated_at":"2025-02-13T19:42:44.000Z","dependencies_parsed_at":"2024-01-29T23:47:55.450Z","dependency_job_id":"80649213-7162-49b2-b353-86d3a53c9f11","html_url":"https://github.com/OpenLiberty/guide-microprofile-istio-retry-fallback","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-microprofile-istio-retry-fallback","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-microprofile-istio-retry-fallback/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-microprofile-istio-retry-fallback/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-microprofile-istio-retry-fallback/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenLiberty","download_url":"https://codeload.github.com/OpenLiberty/guide-microprofile-istio-retry-fallback/tar.gz/refs/heads/prod","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247697900,"owners_count":20981270,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T05:15:36.881Z","updated_at":"2025-04-07T17:32:25.644Z","avatar_url":"https://github.com/OpenLiberty.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"// Copyright (c) 2019, 2025 IBM Corporation and others.\n// Licensed under Creative Commons Attribution-NoDerivatives\n// 4.0 International (CC BY-ND 4.0)\n//   https://creativecommons.org/licenses/by-nd/4.0/\n//\n// Contributors:\n//     IBM Corporation\n//\n:projectid: microprofile-istio-retry-fallback\n:page-layout: guide-multipane\n:page-duration: 30 minutes\n:page-releasedate: 2019-09-13\n:page-description: Explore how to use MicroProfile Fault Tolerance together with Istio Fault Tolerance\n:page-tags: ['microprofile', 'kubernetes', 'docker']\n:page-permalink: /guides/{projectid}\n:page-related-guides: ['istio-intro', 'microprofile-fallback', `iguide-retry-timeout`]\n:common-includes: https://raw.githubusercontent.com/OpenLiberty/guides-common/prod\n:source-highlighter: prettify\n:page-seo-title: Building resilient Java microservices using Eclipse MicroProfile and Istio Fault Tolerance\n:page-seo-description: A tutorial on Eclipse MicroProfile Fault Tolerance integrated with Istio Fault Tolerance. Includes an example on how to develop fault-tolerant Java microservices using Istio's Retry policy and MicroProfile Fault Tolerance's Fallback mechanism.\n:guide-author: Open Liberty\n= Developing fault-tolerant microservices with Istio Retry and MicroProfile Fallback\n\n[.hidden]\nNOTE: This repository contains the guide documentation source. To view the guide in published form, view it on the https://openliberty.io/guides/{projectid}.html[Open Liberty website].\n\n\nExplore how to manage the impact of failures by using MicroProfile and Istio Fault Tolerance to add retry and fallback behaviours to microservices.\n\n:kube: Kubernetes\n:istio: Istio\n:win: WINDOWS\n:mac: MAC\n:linux: LINUX\n:docker: Docker\n:minikube: Minikube\n:maven: Maven\n\n\n// =================================================================================================\n// Introduction\n// =================================================================================================\n\n== What you'll learn\n\n\nYou will learn how to combine https://download.eclipse.org/microprofile/microprofile-fault-tolerance-2.0/microprofile-fault-tolerance-spec.html#retry[MicroProfile Retry^] \nand https://download.eclipse.org/microprofile/microprofile-fault-tolerance-2.0/microprofile-fault-tolerance-spec.html#fallback[Fallback^]\npolicies with https://istio.io/docs/concepts/traffic-management/#timeouts-and-retries[Istio Retry^] \nto make your microservices more resilient to common failures, such as network problems.\n\nMicroservices that are created using Eclipse MicroProfile can be freely deployed in a service mesh to reduce the complexity \nassociated with managing microservices. Istio is a service mesh, meaning that it’s a platform for managing how microservices interact with each other and the outside world.\n{istio} consists of a control plane and sidecars that are injected into application pods. The sidecars contain\nthe https://www.envoyproxy.io/[Envoy^] proxy. You can think of Envoy as a sidecar that intercepts\nand controls all the HTTP and TCP traffic to and from your container.\nIf you would like to learn more about Istio, check out the https://openliberty.io/guides/istio-intro.html[Managing microservice traffic using Istio^] guide.\n\nMicroProfile and Istio both provide simple and flexible solutions to build fault-tolerant microservices. \nFault tolerance provides different strategies for building robust behaviour to cope with unexpected failures.\nA few fault tolerance policies that MicroProfile can offer include Retry, Timeout, Circuit Breaker, Bulkhead, and Fallback.\nThere is some overlap that exists between MicroProfile and Istio Fault Tolerance, such as the Retry policy.\nHowever, Istio does not offer any fallback capabilities.\nTo view the available fault tolerance policies in MicroProfile and Istio, refer to the \nhttps://www.eclipse.org/community/eclipse_newsletter/2018/september/MicroProfile_istio.php#faulttolerance[comparison between MicroProfile and Istio fault handling^].\n\nUse retry policies to fail quickly and recover from brief intermittent issues. \nAn application might experience these transient failures when a microservice is undeployed, a database is overloaded by queries, \nthe network connection becomes unstable, or the site host has a brief downtime. In these cases, rather than failing quickly on these transient failures,\na retry policy provides another chance for the request to succeed. \nSimply retrying the request might be all you need to do to make it succeed.\n\nFallback offers an alternative execution path when an execution does not complete successfully.\nYou will use the `@Fallback` annotation from the MicroProfile Fault Tolerance specification to define criteria \nfor when to provide an alternative solution for a failed execution.\n\nYou will develop microservices that demonstrate MicroProfile Fault Tolerance with Istio fault handling.\nBoth MicroProfile and Istio can be used when you want your microservices to have a service mesh architecture with Istio, \nand use MicroProfile to provide the extra fault tolerance policies that do not exist within Istio.\n\nThe application that you will be working with is an `inventory` service, which collects, stores, and returns the system properties. \nIt uses the `system` service to retrieve the system properties for a particular host. \nYou will add fault tolerance to the `inventory` service so that it reacts accordingly when the `system` service is unavailable.\n\n\n// =================================================================================================\n// Prerequisites\n// =================================================================================================\n\ninclude::{common-includes}/kube-prereq.adoc[]\n\n// =================================================================================================\n// Getting Started\n// =================================================================================================\n\n[role='command']\ninclude::{common-includes}/gitclone.adoc[]\n\n// no \"try what you'll build\" section in this guide because it would be too long due to all setup the user will have to do.\n\n// =================================================================================================\n// Preparing your cluster and deploying Istio\n// =================================================================================================\n\n:minikube-start: minikube start --memory=8192 --cpus=4\n:docker-desktop-description: Ensure that you have enough memory allocated to your Docker Desktop enviornment. 8GB is recommended but 4GB should be adequate if you don't have enough RAM.\n:minikube-description: The memory flag allocates 8GB of memory to your Minikube cluster. If you don't have enough RAM, then 4GB should be adequate.\n[role=command]\ninclude::{common-includes}/kube-start.adoc[]\n\n// =================================================================================================\n// Deploying Istio\n// =================================================================================================\n\ninclude::{common-includes}/istio-start.adoc[]\n\n// =================================================================================================\n// Enabling MicroProfile Fault Tolerance\n// =================================================================================================\n\n== Enabling MicroProfile Fault Tolerance\n\nNavigate to the `guide-{projectid}/start` directory to begin.\n\nThe MicroProfile Fault Tolerance API is included in the MicroProfile dependency that is specified in your `pom.xml` file.\nLook for the dependency with the [hotspot=microprofile file=0]`microprofile` artifact ID.\nThis dependency provides a library that allows you to use the fault tolerance policies in your microservices.\n\nThe [hotspot file=1]`InventoryResource.java` file\nmakes a request to the `system` service through the MicroProfile Rest Client API.\nIf you want to learn more about MicroProfile Rest Client,\nyou can follow the https://openliberty.io/guides/microprofile-rest-client.html[Consuming RESTful services with template interfaces^] guide.\n\npom.xml\n[source, xml, linenums, role='code_column']\n----\ninclude::finish/inventory/pom.xml[]\n----\n\nInventoryResource.java\n[source, Java, linenums, role='code_column hide_tags=copyright,mpRetry,fallback,fallbackMethod']\n----\ninclude::finish/inventory/src/main/java/io/openliberty/guides/inventory/InventoryResource.java[]\n----\n\n=== Adding the MicroProfile @Retry annotation\n\nTo simulate that your `system` service is temporarily down due to brief intermittent issues, you will pause the pod that is associated\nwith your `system` service, then try to send requests to the service. When the `system` pod is paused, requests to the service return a `503` status code, \nand the [hotspot=getProperties file=0]`systemClient.getProperties()` in [hotspot file=0]`InventoryResource.java` throws a `WebApplicationException`. \n\nTo retry the requests to your `system` service after a `WebApplicationException` has occurred, add the `@Retry` annotation.\n\n[role=\"code_command hotspot\", subs=\"quotes\"]\n----\n#Update the `InventoryResource.java` file.#\n`inventory/src/main/java/io/openliberty/guides/inventory/InventoryResource.java`\n----\n[role=\"edit_command_text\"]\nTo retry the service request a maximum of 3 times, only when a [hotspot=webApplicationException file=0]`WebApplicationException` occurs,\nadd the [hotspot=mpRetry file=0]`@Retry` annotation before the [hotspot=getPropertiesForHost file=0]`getPropertiesForHost()` method.\n\nInventoryResource.java\n[source, Java, linenums, role='code_column hide_tags=copyright,fallback,fallbackMethod']\n----\ninclude::finish/inventory/src/main/java/io/openliberty/guides/inventory/InventoryResource.java[]\n----\n\n\nA request to a service might fail for many different reasons. The default Retry policy initiates a retry for every `java.lang.Exception`. \nHowever, you can base a Retry policy on a specific exception by using the `retryOn` parameter. You can identify more than one exception \nas an array of values. For example, `@Retry(retryOn = {RuntimeException.class, TimeoutException.class})`.\n\nYou can set limits on the number of retry attempts to avoid overloading a busy service with retry requests.\nThe `@Retry` annotation has the `maxRetries` parameter to limit the number of retry attempts. The default number for `maxRetries` is 3 requests.\nThe integer value must be greater than or equal to -1. A value of -1 indicates to continue retrying indefinitely.\n\n=== Building and running the application\n\nNavigate to the `guide-{projectid}/start` directory and run the following command to build your application and integrate the Retry policy into your microservices:\n\n[role=command]\n```\nmvn package\n```\n\n\n\nNext, run the `docker build` commands to build container images for your application:\n\n[role='command']\n```\ndocker build -t system:1.0-SNAPSHOT system/.\ndocker build -t inventory:1.0-SNAPSHOT inventory/.\n```\n\nThe `-t` flag in the `docker build` command allows the Docker image to be labeled (tagged) in the `name[:tag]` format. \nThe tag for an image describes the specific image version. If the optional `[:tag]` tag is not specified, the `latest` tag is created by default.\n\nTo verify that the images for your `system` and `inventory` microservices are built, run the `docker images` command to list all local Docker images.\n\n[role=command]\n```\ndocker images\n```\n\nYour two images `system` and `inventory` should appear in the list of all Docker images:\n\n[source, role=\"no_copy\"]\n----\nREPOSITORY         TAG         \ninventory          1.0-SNAPSHOT\nsystem             1.0-SNAPSHOT\n----\n\nTo deploy your microservices to the Kubernetes cluster, use the following command:\n\n[role=command]\n```\nkubectl apply -f services.yaml\n```\n\nYou will see an output similar to the following:\n\n[role=\"no_copy\"]\n----\ngateway.networking.istio.io/sys-app-gateway created\nservice/system-service created\nservice/inventory-service created\ndeployment.apps/system-deployment created\ndeployment.apps/inventory-deployment created\n----\n\nThe [hotspot file=1]`traffic.yaml` file contains two virtual services. A virtual service defines how requests are routed to your applications.\n\nDeploy the resources defined in the [hotspot file=1]`traffic.yaml` file:\n\n[role=command]\n```\nkubectl apply -f traffic.yaml\n```\n\nRun the following command to check the status of your pods:\n\n[role=command]\n```\nkubectl get pods\n```\n\nIf all the pods are healthy and running, you will see an output similar to the following:\n\n[source, role=\"no_copy\"]\n----\nNAME                                    READY     STATUS    RESTARTS   AGE\ninventory-deployment-645767664f-nbtd9   2/2       Running   0          30s\nsystem-deployment-6bd97d9bf6-4ccds      2/2       Running   0          30s\n----\n\nCheck that all of the deployments are available. You need to wait until all of your deployments are \nready and available before making requests to your microservices.\n\n[role=command]\n```\nkubectl get deployments\n```\n\n[source, role=\"no_copy\"]\n----\nNAME                     READY     UP-TO-DATE   AVAILABLE   AGE\ninventory-deployment     1/1       1            1           1m\nsystem-deployment        1/1       1            1           1m\n----\n\nYou will make a request to the `system` service from the `inventory` service to access the \nJVM system properties of your running container. The Istio [hotspot=gateway file=0]`gateway` is the entry point for HTTP requests to the cluster. \nAs defined in the [hotspot file=0]`services.yaml` file, the gateway is expecting the \n`Host` header of your `system` service and `inventory` service to be `system.example.com` and `inventory.example.com`, respectively. \nHowever, requests to `system.example.com` and `inventory.example.com` won’t be routed to the appropriate IP address. \nTo ensure that the gateway routes your requests appropriately, ensure that the `Host` header is set appropriately.\nYou can set the `Host` header with the `-H` option of the `curl` command.\n\nservices.yaml\n[source, yaml, linenums, role='code_column hide_tags=invConfig,configHide']\n----\ninclude::finish/services.yaml[]\n----\n\ntraffic.yaml\n[source, yaml, linenums, role='code_column hide_tags=istioRetry']\n----\ninclude::finish/traffic.yaml[]\n----\n\nMake a request to the service by using `curl`:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\n[role=command]\n```\ncurl -H Host:inventory.example.com http://localhost/inventory/systems/system-service -I\n```\n\nIf the `curl` command is unavailable, then use https://www.getpostman.com/[Postman^]. Postman enables you\nto make requests using a graphical interface. To make a request with Postman, enter `\\http://localhost/inventory/systems/system-service`\ninto the URL bar. Next, switch to the `Headers` tab and add a header with key of `Host` and value of `inventory.example.com`.\nFinally, click the blue `Send` button to make the request.\n--\n\n[.tab_content.linux_section]\n--\n[role=command]\n```\nexport INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name==\"http2\")].nodePort}')\ncurl -H Host:inventory.example.com http://`minikube ip`:$INGRESS_PORT/inventory/systems/system-service -I\n```\n--\n\nYou will see the following output:\n\n[source, role=\"no_copy\"]\n----\nHTTP/1.1 200 OK\nx-powered-by: Servlet/4.0\ncontent-type: application/json\ndate: Mon, 19 Aug 2019 19:49:47 GMT\ncontent-language: en-US\nx-envoy-upstream-service-time: 4242\nserver: istio-envoy\ntransfer-encoding: chunked\n----\n\nBecause the `system` service is available, the request to the service is successful and returns a `200` response code.\n\nTo see the number of times that the `system` service was called, check the logs of the `system` pod by using the `kubectl logs` command.\nReplace `[system-pod-name]` with the pod name associated with\nyour `system` service, which you previously saw when running the `kubectl get pods` command.\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.mac_section.linux_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | grep -c system-service:9090\n```\n--\n\n[.tab_content.windows_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | find /C \"system-service:9090\"\n```\n--\n\nYou will see that the `kubectl logs` command returns a value of 1, meaning that 1 request is made to the `system` service:\n\n[source, role=\"no_copy\"]\n----\n1\n----\n\nNow you will make the `system` service unavailable and observe that MicroProfile's Retry policy will take effect.\n\nPause the `system` service pod to simulate that the service is unavailable. \nRemember to replace `[system-pod-name]` with the pod name that is associated with your `system` service.\n\n\n[role=command]\n```\nkubectl exec -it [system-pod-name] -- /opt/ol/wlp/bin/server pause\n```\n\nYou will see the following output:\n\n----\nPausing the defaultServer server.\nPausing the defaultServer server completed.\n----\n\nMake a request to the service by using `curl`:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\n[role=command]\n```\ncurl -H Host:inventory.example.com http://localhost/inventory/systems/system-service -I\n```\n\nIf the `curl` command is unavailable, then use https://www.getpostman.com/[Postman^].\n--\n\n[.tab_content.linux_section]\n--\n[role=command]\n```\ncurl -H Host:inventory.example.com http://`minikube ip`:$INGRESS_PORT/inventory/systems/system-service -I\n```\n--\n\nYou will see the following output:\n\n[source, role=\"no_copy\"]\n----\nHTTP/1.1 503 Service Unavailable\nx-powered-by: Servlet/4.0\ncontent-length: 91\ncontent-type: text/plain\ndate: Thu, 15 Aug 2019 13:21:57 GMT\nserver: istio-envoy\nx-envoy-upstream-service-time: 2929\ncontent-language: en-US\n----\n\nBecause the the `system` service is unavailable, the request returns a `503` response code.\nHowever, the request retried several times, as specified by the MicroProfile `@Retry` annotation.\n\nSee the number of times that the service was retried:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.mac_section.linux_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | grep -c system-service:9090\n```\n--\n\n[.tab_content.windows_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | find /C \"system-service:9090\"\n```\n--\n\nYou will see the following output:\n\n[source, role=\"no_copy\"]\n----\n5\n----\n\nThis command returns 5 because you made a total of 5 requests to the `system` service: the initial request, 3 MicroProfile retry requests, and the successful request that you made before you paused the `system` service.\n\n// =================================================================================================\n// Enabling Istio Fault Tolerance\n// =================================================================================================\n\n== Enabling Istio Fault Tolerance\n\nPreviously, you implemented the Retry policy to retry requests to your `system` service by using MicroProfile Fault Tolerance.\nThis Retry policy can also be implemented with Istio Fault Tolerance.\n\n[role=\"code_command hotspot\", subs=\"quotes\"]\n----\n#Update the `traffic.yaml` file.#\n`traffic.yaml`\n----\ntraffic.yaml\n[source, yaml, linenums, role='code_column']\n----\ninclude::finish/traffic.yaml[]\n----\n[role=\"edit_command_text\"]\nAdd the [hotspot=istioRetry file=0]`retries` field under the [hotspot=route file=0]`route` specification in the [hotspot file=0]`traffic.yaml` file. \nThis tells Istio to retry requests a maximum of 4 times when the request returns any `5xx` response code. \n\nThe [hotspot=attempts file=0]`attempts` field is required in the configuration of the \nhttps://istio.io/docs/reference/config/networking/v1alpha3/virtual-service/#HTTPRetry[Istio Retry^] policy. This field specifies the\nmaximum number of retries that will be attempted for a given request. To retry a request on specific conditions, use the\n[hotspot=retryOn file=0]`retryOn` field. Because your paused `system` service responds with a `503` response code, \nyou set [hotspot=retryOn file=0]`retryOn` to be `5xx`. \nOther https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#x-envoy-retry-on[retry conditions^] \ncan also be specified in [hotspot=retryOn file=0]`retryOn`. Optionally, the `perTryTimeout` field can be added to Istio's Retry policy \nto specify the amount of time that is allocated to each retry attempt. \n\nAfter you configure the number of retries that Istio performs, deploy your microservices again: \n\n[role=command]\n```\nkubectl replace --force -f services.yaml\nkubectl replace --force -f traffic.yaml\n```\n\nWait until all of your deployments are ready and available.\nThe `[system-pod-name]` will be regenerated and is different than the one you used previously.\nRun the `kubectl get pods` command to get the new `[system-pod-name]`.\nPause the `system` service pod to simulate that the service is unavailable.\n\n[role=command]\n```\nkubectl exec -it [system-pod-name] -- /opt/ol/wlp/bin/server pause\n```\n\nMake a request to the service by using `curl`:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\n[role=command]\n```\ncurl -H Host:inventory.example.com http://localhost/inventory/systems/system-service -I\n```\n\nIf the `curl` command is unavailable, then use https://www.getpostman.com/[Postman^].\n--\n\n[.tab_content.linux_section]\n--\n[role=command]\n```\ncurl -H Host:inventory.example.com http://`minikube ip`:$INGRESS_PORT/inventory/systems/system-service -I\n```\n--\n\nBecause the `system` service is unavailable, the request still returns a `503` response code.\nThis time, however, Istio retried the request several more times before failing.\n\nSee the number of times that the service was retried:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.mac_section.linux_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | grep -c system-service:9090\n```\n--\n\n[.tab_content.windows_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | find /C \"system-service:9090\"\n```\n--\n\nYou will see the following output:\n\n[source, role=\"no_copy\"]\n----\n20\n----\n\nInventoryResource.java\n[source, Java, linenums, role='code_column hide_tags=copyright,fallback,fallbackMethod']\n----\ninclude::finish/inventory/src/main/java/io/openliberty/guides/inventory/InventoryResource.java[]\n----\n\nThis command returns a value of 20, indicating that a total of 20 requests were made to the `system` service, including:\n\n* 5 Istio requests: the initial request and 4 retry requests that you enabled in the [hotspot=attempts file=0]`traffic.yaml` file\n* For each of the 5 Istio requests, MicroProfile sent 4 requests:  the initial request and [hotspot=mpRetry file=1]`3` retry requests\n\nNext, you will disable some MicroProfile Fault Tolerance capabilities, so that your `system` service retries with only Istio's Retry policy. \n\n\n// =================================================================================================\n// Turning off MicroProfile Fault Tolerance\n// =================================================================================================\n\n== Turning off MicroProfile Fault Tolerance\n\nWhen both MicroProfile and Istio Fault Tolerance capabilities are enabled, there is a compounding effect that may be unexpected. \nIf both MicroProfile and Istio set their own Retry policies on a service,\nthe maximum number of retries that occur is not equivalent to either of the number of retries specified in MicroProfile or Istio. \nThe number of retries set by MicroProfile and Istio are actually multiplied.\n\nIf you want to use Istio as your service mesh and only its fault tolerance capabilities, \nyou can turn off MicroProfile Fault Tolerance by adding a property. This configuration avoids any overlap in behaviours.\n\nMicroProfile Fault Tolerance offers a config property `MP_Fault_Tolerance_NonFallback_Enabled` that disables all \nMicroProfile Fault Tolerance capabilities except fallback. If `MP_Fault_Tolerance_NonFallback_Enabled` is set to false, only \nthe `@Fallback` behaviour is enabled. The other behaviours specified by the MicroProfile Fault Tolerance annotations, \nincluding `@Retry`, won't take effect.\n\nYou will define the `MP_Fault_Tolerance_NonFallback_Enabled` config property in a ConfigMap.\nConfigMaps store configuration settings about a Kubernetes pod. This configuration is loaded into the pod as an environment variable that is \nused by the pod's containers. The environment variables are defined in the pod's specification by using the `envFrom` field. To learn more about ConfigMaps,\ncheck out the https://openliberty.io/guides/kubernetes-microprofile-config.html[Configuring microservices running in Kubernetes^] guide.\n\nUse the `MP_Fault_Tolerance_NonFallback_Enabled` config property to disable the retries performed by MicroProfile, \nso that only Istio performs retries. \n\n\n[role=\"code_command hotspot\", subs=\"quotes\"]\n----\n#Update the `services.yaml` file.#\n`services.yaml`\n----\nservices.yaml\n[source, yaml, linenums, role='code_column']\n----\ninclude::finish/services.yaml[]\n----\n[role=\"edit_command_text\"]\nAdd a [hotspot=configMap file=0]`ConfigMap` into the [hotspot file=0]`services.yaml` file, and \nset the [hotspot=nonFallback file=0]`MP_Fault_Tolerance_NonFallback_Enabled` config property to false. \nAdd the [hotspot=invConfig file=0]`envFrom` field \nto inject the [hotspot=configMap file=0]`ConfigMap` with the [hotspot=nonFallback file=0]`MP_Fault_Tolerance_NonFallback_Enabled` property into your pods. \n\nThe [hotspot=configName file=0]`name` of the [hotspot=configMap file=0]`ConfigMap`, which is [hotspot=configName file=0]`inventory-config`, \nbecomes the environment variable [hotspot=configName2 file=0]`name` that is specified in the [hotspot=invConfig file=0]`envFrom` field. \n\nDeploy your microservices again to turn off all MicroProfile Fault Tolerance capabilities, except fallback:\n\n[role=command]\n```\nkubectl replace --force -f services.yaml\n```\n\nWait until all of your deployments are ready and available.\nRun the `kubectl get pods` command to get the new `[system-pod-name]`.\nPause the `system` service pod to simulate that the service is unavailable:\n\n[role=command]\n```\nkubectl exec -it [system-pod-name] -- /opt/ol/wlp/bin/server pause\n```\n\nMake a request to the service by using `curl`:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\n[role=command]\n```\ncurl -H Host:inventory.example.com http://localhost/inventory/systems/system-service -I\n```\n\nIf the `curl` command is unavailable, then use https://www.getpostman.com/[Postman^].\n--\n\n[.tab_content.linux_section]\n--\n[role=command]\n```\ncurl -H Host:inventory.example.com http://`minikube ip`:$INGRESS_PORT/inventory/systems/system-service -I\n```\n--\n\nBecause the `system` service is unavailable, the request still returns a `503` response code.\nThis time, however, the request was retried several times with Istio, without any retries from MicroProfile.\n\nSee the number of times that the service was retried:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.mac_section.linux_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | grep -c system-service:9090\n```\n--\n\n[.tab_content.windows_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | find /C \"system-service:9090\"\n```\n--\n\nYou will see the following output:\n\n[source, role=\"no_copy\"]\n----\n5\n----\n\nThis command returns 5, indicating that a total of 5 requests were made to the `system` service.\nBecause MicroProfile's Retry policy is disabled, only Istio's retries are performed.\n\ntraffic.yaml\n[source, yaml, linenums, role='code_column']\n----\ninclude::finish/traffic.yaml[]\n----\n\n// =================================================================================================\n// Using MicroProfile Fallback\n// =================================================================================================\n\n== Using MicroProfile Fallback\n\nservices.yaml\n[source, yaml, linenums, role='code_column']\n----\ninclude::finish/services.yaml[]\n----\n\nSince retrying the requests to the `system` service still does not succeed, you need a \"fall back\" plan. \nYou will create a fallback method as an alternative solution for when retry requests to the `system` service have failed.\n\nAlthough you disabled MicroProfile `@Retry` and other MicroProfile Fault Tolerance policies using the \n[hotspot=nonFallback file=0]`MP_Fault_Tolerance_NonFallback_Enabled` config property, the fallback policy is still available.\nAs mentioned before, Istio does not offer any fallback capabilities, so the MicroProfile Fallback capability can be used to complement it.\n\nThe `@Fallback` annotation dictates a method to call when the original method encounters a failed execution. \nIf your microservices have a Retry policy specified, then the fallback occurs after all of the retries have failed. \n\n[role=\"code_command hotspot file=1\", subs=\"quotes\"]\n----\n#Update the `InventoryResource.java` file.#\n`inventory/src/main/java/io/openliberty/guides/inventory/InventoryResource.java`\n----\nInventoryResource.java\n[source, Java, linenums, role='code_column hide_tags=copyright']\n----\ninclude::finish/inventory/src/main/java/io/openliberty/guides/inventory/InventoryResource.java[]\n----\n[role=\"edit_command_text\"]\nCreate the [hotspot=fallbackMethod file=1]`getPropertiesFallback()` method. \nAdd the [hotspot=fallback file=1]`@Fallback` annotation before the [hotspot=getPropertiesForHost file=1]`getPropertiesForHost()` method, \nto call the [hotspot=fallbackMethod file=1]`getPropertiesFallback()` method when a failure occurs.\n\n\nThe [hotspot=fallbackMethod file=1]`getPropertiesFallback()` method, which is the designated fallback method for the original \n[hotspot=getPropertiesForHost file=1]`getPropertiesForHost()` method, prints out a warning message in the browser that says \nthe `system` service may not be running.\n\n\nRebuild your application to add fallback behaviour to your microservices:\n\n[role=command]\n```\nmvn package\n```\n\nNext, run the `docker build` commands to rebuild the container images for your application:\n\n[role='command']\n```\ndocker build -t inventory:1.0-SNAPSHOT inventory/.\ndocker build -t system:1.0-SNAPSHOT system/.\n```\n\n\nDeploy your microservices again to turn off all MicroProfile Fault Tolerance capabilities, except fallback:\n\n[role=command]\n```\nkubectl replace --force -f services.yaml\nkubectl replace --force -f traffic.yaml\n```\n\nWait until all of your deployments are ready and available.\nRun the `kubectl get pods` command to get the new `[system-pod-name]`.\nPause the `system` service pod to simulate that the service is unavailable:\n\n[role=command]\n```\nkubectl exec -it [system-pod-name] -- /opt/ol/wlp/bin/server pause\n```\n\nMake a request to the service by using `curl`:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\n[role=command]\n```\ncurl -H Host:inventory.example.com http://localhost/inventory/systems/system-service -I\n```\n\nIf the `curl` command is unavailable, then use https://www.getpostman.com/[Postman^].\n--\n\n[.tab_content.linux_section]\n--\n[role=command]\n```\ncurl -H Host:inventory.example.com http://`minikube ip`:$INGRESS_PORT/inventory/systems/system-service -I\n```\n--\n\nYou will see the following output:\n\n[source, role=\"no_copy\"]\n----\nHTTP/1.1 200 OK\nx-powered-by: Servlet/4.0\nx-from-fallback: yes\ncontent-type: application/json\ndate: Mon, 19 Aug 2019 19:49:47 GMT\ncontent-language: en-US\nx-envoy-upstream-service-time: 4242\nserver: istio-envoy\ntransfer-encoding: chunked\n----\n\nYou can see that the request is now successful and returns a `200` response code, with a header called\n`x-from-fallback`, indicating that the fallback method is called when the `system` service is not available.\n\nSee the number of times that the service is retried before the fallback method is called:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.mac_section.linux_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | grep -c system-service:9090\n```\n--\n\n[.tab_content.windows_section]\n--\n[role=command]\n```\nkubectl logs [system-pod-name] -c istio-proxy | find /C \"system-service:9090\"\n```\n--\n\nYou will see the following output:\n\n[source, role=\"no_copy\"]\n----\n1\n----\n\nThis command returns 1, indicating that 1 request was made to the `system` service.\nThe Istio retries that you enabled on the `inventory` service are not performed.\nAlthough the [hotspot=getPropertiesForHost file=1]`getPropertiesForHost()` method failed, the [hotspot=fallbackMethod file=1]`getPropertiesFallback()` fallback method was called.\n\n\n// =================================================================================================\n// Tearing down your environment\n// =================================================================================================\n\n== Tearing down your environment\n\nWhen you are done checking out the MicroProfile and Istio Fault Tolerance features, \nyou might want to tear down all the deployed resources as a cleanup step.\n\nDelete your resources from the cluster:\n\n[role=command]\n```\nkubectl delete -f services.yaml\nkubectl delete -f traffic.yaml\n```\n\nDelete the `istio-injection` label from the default namespace. The hyphen immediately\nafter the label name indicates that the label should be deleted.\n\n[role=command]\n```\nkubectl label namespace default istio-injection-\n```\n\nDelete all {istio} resources from the cluster:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role=command]\n```\nistioctl uninstall --purge\n```\n--\n\n[.tab_content.mac_section]\n--\n[role=command]\n```\nistioctl uninstall --purge\n```\n--\n\n[.tab_content.linux_section]\n--\n[role=command]\n```\nistioctl uninstall --purge\n```\nPerform the following steps to return your environment to a clean state.\n\n. Point the Docker daemon back to your local machine:\n+\n[role=command]\n```\neval $(minikube docker-env -u)\n```\n\n. Stop and delete your Minikube cluster:\n+\n[role=command]\n```\nminikube stop\nminikube delete\n```\n--\n\n\n\n// =================================================================================================\n// finish\n// =================================================================================================\n\n== Great work! You're done!\n\nYou learned how to build resilient microservices by using Istio Retry and MicroProfile Fallback.\nYou also observed how MicroProfile Fault Tolerance integrates with and complements Istio Fault Tolerance.\n\n// Include the below from the guides-common repo to tell users how they can contribute to the guide\n\ninclude::{common-includes}/attribution.adoc[subs=\"attributes\"]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenliberty%2Fguide-microprofile-istio-retry-fallback","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenliberty%2Fguide-microprofile-istio-retry-fallback","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenliberty%2Fguide-microprofile-istio-retry-fallback/lists"}