From 37844bcd0cec42b972d9ab231c0a5bf7ff86772b Mon Sep 17 00:00:00 2001 From: Hannah Hunter Date: Fri, 11 Nov 2022 19:00:20 -0600 Subject: [PATCH] updates per resiliency example Signed-off-by: Hannah Hunter --- .../en/getting-started/quickstarts/_index.md | 2 +- .../quickstarts/resiliency-quickstart.md | 158 --- .../quickstarts/resiliency/_index.md | 7 + .../resiliency-serviceinvo-quickstart.md | 1204 +++++++++++++++++ .../resiliency/resiliency-state-quickstart.md | 900 ++++++++++++ 5 files changed, 2112 insertions(+), 159 deletions(-) delete mode 100644 daprdocs/content/en/getting-started/quickstarts/resiliency-quickstart.md create mode 100644 daprdocs/content/en/getting-started/quickstarts/resiliency/_index.md create mode 100644 daprdocs/content/en/getting-started/quickstarts/resiliency/resiliency-serviceinvo-quickstart.md create mode 100644 daprdocs/content/en/getting-started/quickstarts/resiliency/resiliency-state-quickstart.md diff --git a/daprdocs/content/en/getting-started/quickstarts/_index.md b/daprdocs/content/en/getting-started/quickstarts/_index.md index c0a189dc0..67380fa87 100644 --- a/daprdocs/content/en/getting-started/quickstarts/_index.md +++ b/daprdocs/content/en/getting-started/quickstarts/_index.md @@ -27,4 +27,4 @@ Hit the ground running with our Dapr quickstarts, complete with code samples aim | [State Management]({{< ref statemanagement-quickstart.md >}}) | Store a service's data as key/value pairs in supported state stores. | | [Bindings]({{< ref bindings-quickstart.md >}}) | Work with external systems using input bindings to respond to events and output bindings to call operations. | | [Secrets Management]({{< ref secrets-quickstart.md >}}) | Securely fetch secrets. | -| [Resiliency]({{< ref resiliency-quickstart.md >}}) | Define and apply fault-tolernce policies to your Dapr APIs requests. | +| [Resiliency]({{< ref resiliency >}}) | Define and apply fault-tolerance policies to your Dapr API requests. | diff --git a/daprdocs/content/en/getting-started/quickstarts/resiliency-quickstart.md b/daprdocs/content/en/getting-started/quickstarts/resiliency-quickstart.md deleted file mode 100644 index 0d2764803..000000000 --- a/daprdocs/content/en/getting-started/quickstarts/resiliency-quickstart.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -type: docs -title: "Quickstart: Resiliency" -linkTitle: "Resiliency" -weight: 72 -description: "Get started with Dapr's resiliency capabilities" ---- -Diagram showing the resiliency applied to Dapr APIs - -{{% alert title="Note" color="primary" %}} - Resiliency is currently a preview feature. -{{% /alert %}} - -In this Quickstart, you will observe Dapr resiliency capabilities by simulating a system failure. You will execute a microservice application that continuously persists and retrieves state via Dapr's state management API. When operations to the state store begin to fail, Dapr resiliency policies are applied. - -The resiliency policies used in this example are defined and applied via the [resiliency spec]() located in the components directory. - -### Pre-requisites - -For this example, you will need: - -- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). -- [Latest Node.js installed](https://nodejs.org/download/). - -- [Docker Desktop](https://www.docker.com/products/docker-desktop) - - -### Step 1: Set up the environment - -Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/resiliency). - -```bash -git clone https://github.com/dapr/quickstarts.git -``` - -In a terminal window, navigate to the `order-processor` directory. - -```bash -cd quickstart/resiliency/javascript/order-processor -``` - -Install dependencies - -```bash -npm install -``` - -### Step 2: Run the application with resiliency enabled - -Run the `order-processor` service alongside a Dapr sidecar. The `--config` parameter applies a Dapr configuration that enables the resiliency feature. - -The resilency spec is located in the components directory and is automatically discovered by the Dapr sidecar when run in standalone mode. - -```bash -dapr run --app-id order-processor --config ../config.yaml --components-path ../components/ -- npm start -``` - -Once the application has started, the `order-processor`service writes and reads `orderId` key/value pairs to the `statestore` redis instance [defined in the `statestore.yaml` component]({{< ref "#statestoreyaml-component-file" >}}). - -```bash -== APP == Saving Order: { orderId: '1' } -== APP == Getting Order: { orderId: '1' } -== APP == Saving Order: { orderId: '2' } -== APP == Getting Order: { orderId: '2' } -== APP == Saving Order: { orderId: '3' } -== APP == Getting Order: { orderId: '3' } -== APP == Saving Order: { orderId: '4' } -== APP == Getting Order: { orderId: '4' } -``` -While the application is running continue to the next section. - -### Step 3: Introduce a fault - -For example purposes, you will simulate a fault by stopping the Redis container that was initalized when executing `dapr init` on your development machine. - -The Redis instance is configured as the state store component for the order-processor microservice. Once the redis instance is stopped, write and read operations from the order-processor service will begin to fail. - -Since the `statestore` component is definied as a target in the resiliency spec applied to the order-processor service, all failed requests will apply retry and circuit breaker policies: - -```yaml - targets: - components: - statestore: - outbound: - retry: retryForever - circuitBreaker: simpleCB -``` - -```bash -docker stop dapr_redis -``` - -Once the first request fails, the retry policy titled `retryForever` is applied: - -```bash -INFO[0006] Error processing operation component[statestore] output. Retrying... -``` - -```yaml -retryForever: - policy: constant - maxInterval: 5s - maxRetries: -1 -``` - -Retries will continue for each failed request indefinitely, while waiting 5 seconds in between trying again. Once 5 consecutive retries have failed, the circuit breaker policy `simpleCB` is tripped and the breaker opens haulting all requests: - -```bash -INFO[0026] Circuit breaker "simpleCB-statestore" changed state from closed to open -``` - -```yaml -circuitBreakers: - simpleCB: - maxRequests: 1 - timeout: 5s - trip: consecutiveFailures >= 5 -``` - -After 5 seconds has surpassed, the circuit breaker will switch to a half-open state allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. This behavior will continue for as long as the Redis container is stopped. - -```bash -INFO[0031] Circuit breaker "simpleCB-statestore" changed state from open to half-open -INFO[0031] Circuit breaker "simpleCB-statestore" changed state from half-open to open -INFO[0036] Circuit breaker "simpleCB-statestore" changed state from open to half-open -INFO[0036] Circuit breaker "simpleCB-statestore" changed state from half-open to closed -``` - -### Step 3: Remove the fault -Restart the redis container on your machine and the application will recover seamlessly, picking up where it left off with writing and reading orders to the Redis state store component. - -```bash -docker start dapr_redis -``` - -```bash -INFO[0036] Recovered processing operation component[statestore] output. -== APP == Saving Order: { orderId: '5' } -== APP == Getting Order: { orderId: '5' } -== APP == Saving Order: { orderId: '6' } -== APP == Getting Order: { orderId: '6' } -== APP == Saving Order: { orderId: '7' } -== APP == Getting Order: { orderId: '7' } -== APP == Saving Order: { orderId: '8' } -== APP == Getting Order: { orderId: '8' } -== APP == Saving Order: { orderId: '9' } -== APP == Getting Order: { orderId: '9' } -``` - -## Tell us what you think! -We're continuously working to improve our Quickstart examples and value your feedback. Did you find this quickstart helpful? Do you have suggestions for improvement? - -Join the discussion in our [discord channel](https://discord.com/channels/778680217417809931/953427615916638238). - -## Next steps -Visit [this](https://docs.dapr.io/operations/resiliency/resiliency-overview//) link for more information about Dapr resiliency. - -{{< button text="Explore Dapr tutorials >>" page="getting-started/tutorials/_index.md" >}} diff --git a/daprdocs/content/en/getting-started/quickstarts/resiliency/_index.md b/daprdocs/content/en/getting-started/quickstarts/resiliency/_index.md new file mode 100644 index 000000000..3156dfa9d --- /dev/null +++ b/daprdocs/content/en/getting-started/quickstarts/resiliency/_index.md @@ -0,0 +1,7 @@ +--- +type: docs +title: "Resiliency Quickstarts" +linkTitle: "Resiliency" +weight: 100 +description: "Get started with Dapr's resiliency component" +--- \ No newline at end of file diff --git a/daprdocs/content/en/getting-started/quickstarts/resiliency/resiliency-serviceinvo-quickstart.md b/daprdocs/content/en/getting-started/quickstarts/resiliency/resiliency-serviceinvo-quickstart.md new file mode 100644 index 000000000..1954befa1 --- /dev/null +++ b/daprdocs/content/en/getting-started/quickstarts/resiliency/resiliency-serviceinvo-quickstart.md @@ -0,0 +1,1204 @@ +--- +type: docs +title: "Quickstart: Service-to-service resiliency" +linkTitle: "Resiliency: Service Invocation" +weight: 120 +description: "Get started with Dapr's resiliency capabilities via the service invocation API" +--- + +{{% alert title="Note" color="primary" %}} + Resiliency is currently a preview feature. +{{% /alert %}} + +Observe Dapr resiliency capabilities by simulating a system failure. In this Quickstart, you will: + +- Run two microservice applications, `checkout` and `order-processor`. `checkout` will continuously make Dapr service invocation requests to `order-processor`. +- Trigger the resiliency spec by simulating a system failure. +- Remove the failure to allow the microservice application to resume. + +Diagram showing the resiliency applied to Dapr APIs + +Select your preferred language-specific Dapr SDK before proceeding with the Quickstart. + +{{< tabs "Python" "JavaScript" ".NET" "Java" "Go" >}} + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- [Python 3.7+ installed](https://www.python.org/downloads/). + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/service_invocation). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +### Step 2: Run `order-processor` service + +In a terminal window, from the root of the Quickstart clone directory +navigate to `order-processor` directory. + +```bash +cd ../service_invocation/python/http/order-processor +``` + +Install the dependencies: + +```bash +pip3 install -r requirements.txt +``` + +Run the `order-processor` service alongside a Dapr sidecar. + +```bash +dapr run --app-port 8001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- python3 app.py +``` + +### Step 3: Run the `checkout` service application with resiliency enabled + +In a new terminal window, from the root of the Quickstart clone directory +navigate to the `checkout` directory. + +```bash +cd ../service_invocation/python/http/checkout +``` + +Install the dependencies: + +```bash +pip3 install -r requirements.txt +``` + +Run the `checkout` service alongside a Dapr sidecar. The `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-id checkout --config ../config.yaml --components-path ../../../components/ --app-protocol http --dapr-http-port 3500 -- python3 app.py +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - checkout + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB + ``` + +### Step 4: View the Service Invocation outputs + +Dapr invokes an application on any Dapr instance. In the code, the sidecar programming model encourages each application to talk to its own instance of Dapr. The Dapr instances then discover and communicate with one another. + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 1} +== APP == Order passed: {"orderId": 2} +== APP == Order passed: {"orderId": 3} +== APP == Order passed: {"orderId": 4} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 1} +== APP == Order received: {"orderId": 2} +== APP == Order received: {"orderId": 3} +== APP == Order received: {"orderId": 4} +``` + +### Step 5: Introduce a fault + +Simulate a fault by stopping the `order-processor` service. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `order-processor` service as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB +``` + +In the `order-processor` window, stop the service: + +{{< tabs "MacOs" "Windows" >}} + + + +{{% codetab %}} + +```script +CMD + C +``` + +{{% /codetab %}} + + + +{{% codetab %}} + +```script +CTRL + C +``` + +{{% /codetab %}} + +{{< /tabs >}} + + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0005] Error processing operation endpoint[order-processor, order-processor:orders]. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0025] Circuit breaker "order-processor:orders" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 6: Remove the fault + +Once you restart the `order-processor` service, the application will recover seamlessly, picking up where it left off. + +In the `order-processor` service terminal, restart the application: + +```bash +dapr run --app-port 8001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- python3 app.py +``` + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 5} +== APP == Order passed: {"orderId": 6} +== APP == Order passed: {"orderId": 7} +== APP == Order passed: {"orderId": 8} +== APP == Order passed: {"orderId": 9} +== APP == Order passed: {"orderId": 10} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 5} +== APP == Order received: {"orderId": 6} +== APP == Order received: {"orderId": 7} +== APP == Order received: {"orderId": 8} +== APP == Order received: {"orderId": 9} +== APP == Order received: {"orderId": 10} +``` + +{{% /codetab %}} + + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- [Latest Node.js installed](https://nodejs.org/download/). + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/service_invocation). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +### Step 2: Run the `order-processor` service + +In a terminal window, from the root of the Quickstart clone directory +navigate to `order-processor` directory. + +```bash +cd ../service_invocation/javascript/http/order-processor +``` + +Install the dependencies: + +```bash +npm install +``` + +Run the `order-processor` service alongside a Dapr sidecar. + +```bash +dapr run --app-port 5001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- npm start +``` + +### Step 3: Run the `checkout` service application with resiliency enabled + +In a new terminal window, from the root of the Quickstart clone directory +navigate to the `checkout` directory. + +```bash +cd service_invocation/javascript/http/checkout +``` + +Install the dependencies: + +```bash +npm install +``` + +Run the `checkout` service alongside a Dapr sidecar. The `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-port 5001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- npm start +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - checkout + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB + ``` + +### Step 4: View the Service Invocation outputs + +Dapr invokes an application on any Dapr instance. In the code, the sidecar programming model encourages each application to talk to its own instance of Dapr. The Dapr instances then discover and communicate with one another. + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 1} +== APP == Order passed: {"orderId": 2} +== APP == Order passed: {"orderId": 3} +== APP == Order passed: {"orderId": 4} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 1} +== APP == Order received: {"orderId": 2} +== APP == Order received: {"orderId": 3} +== APP == Order received: {"orderId": 4} +``` + +### Step 5: Introduce a fault + +Simulate a fault by stopping the `order-processor` service. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `order-processor` service as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB +``` + +In the `order-processor` window, stop the service: + +{{< tabs "MacOs" "Windows" >}} + + + +{{% codetab %}} + +```script +CMD + C +``` + +{{% /codetab %}} + + + +{{% codetab %}} + +```script +CTRL + C +``` + +{{% /codetab %}} + +{{< /tabs >}} + + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0005] Error processing operation endpoint[order-processor, order-processor:orders]. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0025] Circuit breaker "order-processor:orders" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 6: Remove the fault + +Once you restart the `order-processor` service, the application will recover seamlessly, picking up where it left off. + +In the `order-processor` service terminal, restart the application: + +```bash +dapr run --app-port 5001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- npm start +``` + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 5} +== APP == Order passed: {"orderId": 6} +== APP == Order passed: {"orderId": 7} +== APP == Order passed: {"orderId": 8} +== APP == Order passed: {"orderId": 9} +== APP == Order passed: {"orderId": 10} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 5} +== APP == Order received: {"orderId": 6} +== APP == Order received: {"orderId": 7} +== APP == Order received: {"orderId": 8} +== APP == Order received: {"orderId": 9} +== APP == Order received: {"orderId": 10} +``` + +{{% /codetab %}} + + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- [.NET SDK or .NET 6 SDK installed](https://dotnet.microsoft.com/download). + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/service_invocation). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +### Step 2: Run the `order-processor` service + +In a terminal window, from the root of the Quickstart clone directory +navigate to `order-processor` directory. + +```bash +cd ../service_invocation/csharp/http/order-processor +``` + +Install the dependencies: + +```bash +dotnet restore +dotnet build +``` + +Run the `order-processor` service alongside a Dapr sidecar. + +```bash +dapr run --app-port 7001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- dotnet run +``` + +### Step 3: Run the `checkout` service application with resiliency enabled + +In a new terminal window, from the root of the Quickstart clone directory +navigate to the `checkout` directory. + +```bash +cd ../service_invocation/csharp/http/checkout +``` + +Install the dependencies: + +```bash +dotnet restore +dotnet build +``` + +Run the `checkout` service alongside a Dapr sidecar. The `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-id checkout --config ../config.yaml --components-path ../../../components/ --app-protocol http --dapr-http-port 3500 -- dotnet run +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - checkout + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB + ``` + +### Step 4: View the Service Invocation outputs + +Dapr invokes an application on any Dapr instance. In the code, the sidecar programming model encourages each application to talk to its own instance of Dapr. The Dapr instances then discover and communicate with one another. + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 1} +== APP == Order passed: {"orderId": 2} +== APP == Order passed: {"orderId": 3} +== APP == Order passed: {"orderId": 4} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 1} +== APP == Order received: {"orderId": 2} +== APP == Order received: {"orderId": 3} +== APP == Order received: {"orderId": 4} +``` + +### Step 5: Introduce a fault + +Simulate a fault by stopping the `order-processor` service. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `order-processor` service as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB +``` + +In the `order-processor` window, stop the service: + +{{< tabs "MacOs" "Windows" >}} + + + +{{% codetab %}} + +```script +CMD + C +``` + +{{% /codetab %}} + + + +{{% codetab %}} + +```script +CTRL + C +``` + +{{% /codetab %}} + +{{< /tabs >}} + + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0005] Error processing operation endpoint[order-processor, order-processor:orders]. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0025] Circuit breaker "order-processor:orders" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 6: Remove the fault + +Once you restart the `order-processor` service, the application will recover seamlessly, picking up where it left off. + +In the `order-processor` service terminal, restart the application: + +```bash +dapr run --app-port 7001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- dotnet run +``` + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 5} +== APP == Order passed: {"orderId": 6} +== APP == Order passed: {"orderId": 7} +== APP == Order passed: {"orderId": 8} +== APP == Order passed: {"orderId": 9} +== APP == Order passed: {"orderId": 10} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 5} +== APP == Order received: {"orderId": 6} +== APP == Order received: {"orderId": 7} +== APP == Order received: {"orderId": 8} +== APP == Order received: {"orderId": 9} +== APP == Order received: {"orderId": 10} +``` + +{{% /codetab %}} + + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- Java JDK 11 (or greater): + - [Oracle JDK](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11), or + - OpenJDK +- [Apache Maven](https://maven.apache.org/install.html), version 3.x. + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/service_invocation). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +### Step 2: Run the `order-processor` service + +In a terminal window, from the root of the Quickstart clone directory +navigate to `order-processor` directory. + +```bash +cd ../service_invocation/java/http/order-processor +``` + +Install the dependencies: + +```bash +mvn clean install +``` + +Run the `order-processor` service alongside a Dapr sidecar. + +```bash +dapr run --app-id order-processor --app-port 9001 --app-protocol http --dapr-http-port 3501 -- java -jar target/OrderProcessingService-0.0.1-SNAPSHOT.jar +``` + +### Step 3: Run the `checkout` service application with resiliency enabled + +In a new terminal window, from the root of the Quickstart clone directory +navigate to the `checkout` directory. + +```bash +cd ../service_invocation/java/http/checkout +``` + +Install the dependencies: + +```bash +mvn clean install +``` + +Run the `checkout` service alongside a Dapr sidecar. The `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-id checkout --config ../config.yaml --components-path ../../../components/ --app-protocol http --dapr-http-port 3500 -- java -jar target/CheckoutService-0.0.1-SNAPSHOT.jar +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - checkout + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB + ``` + +### Step 4: View the Service Invocation outputs + +Dapr invokes an application on any Dapr instance. In the code, the sidecar programming model encourages each application to talk to its own instance of Dapr. The Dapr instances then discover and communicate with one another. + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 1} +== APP == Order passed: {"orderId": 2} +== APP == Order passed: {"orderId": 3} +== APP == Order passed: {"orderId": 4} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 1} +== APP == Order received: {"orderId": 2} +== APP == Order received: {"orderId": 3} +== APP == Order received: {"orderId": 4} +``` + +### Step 5: Introduce a fault + +Simulate a fault by stopping the `order-processor` service. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `order-processor` service as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB +``` + +In the `order-processor` window, stop the service: + +{{< tabs "MacOs" "Windows" >}} + + + +{{% codetab %}} + +```script +CMD + C +``` + +{{% /codetab %}} + + + +{{% codetab %}} + +```script +CTRL + C +``` + +{{% /codetab %}} + +{{< /tabs >}} + + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0005] Error processing operation endpoint[order-processor, order-processor:orders]. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0025] Circuit breaker "order-processor:orders" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 6: Remove the fault + +Once you restart the `order-processor` service, the application will recover seamlessly, picking up where it left off. + +In the `order-processor` service terminal, restart the application: + +```bash +dapr run --app-id order-processor --app-port 9001 --app-protocol http --dapr-http-port 3501 -- java -jar target/OrderProcessingService-0.0.1-SNAPSHOT.jar +``` + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 5} +== APP == Order passed: {"orderId": 6} +== APP == Order passed: {"orderId": 7} +== APP == Order passed: {"orderId": 8} +== APP == Order passed: {"orderId": 9} +== APP == Order passed: {"orderId": 10} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 5} +== APP == Order received: {"orderId": 6} +== APP == Order received: {"orderId": 7} +== APP == Order received: {"orderId": 8} +== APP == Order received: {"orderId": 9} +== APP == Order received: {"orderId": 10} +``` + +{{% /codetab %}} + + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- [Latest version of Go](https://go.dev/dl/). + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/service_invocation). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +### Step 2: Run the `order-processor` service + +In a terminal window, from the root of the Quickstart clone directory +navigate to `order-processor` directory. + +```bash +cd ../service_invocation/go/http/order-processor +``` + +Install the dependencies: + +```bash +go build . +``` + +Run the `order-processor` service alongside a Dapr sidecar. + +```bash +dapr run --app-port 6001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- go run . +``` + +### Step 3: Run the `checkout` service application with resiliency enabled + +In a new terminal window, from the root of the Quickstart clone directory +navigate to the `checkout` directory. + +```bash +cd ../service_invocation/go/http/checkout +``` + +Install the dependencies: + +```bash +go build . +``` + +Run the `checkout` service alongside a Dapr sidecar. The `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-id checkout --config ../config.yaml --components-path ../../../components/ --app-protocol http --dapr-http-port 3500 -- go run . +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - checkout + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB + ``` + +### Step 4: View the Service Invocation outputs + +Dapr invokes an application on any Dapr instance. In the code, the sidecar programming model encourages each application to talk to its own instance of Dapr. The Dapr instances then discover and communicate with one another. + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 1} +== APP == Order passed: {"orderId": 2} +== APP == Order passed: {"orderId": 3} +== APP == Order passed: {"orderId": 4} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 1} +== APP == Order received: {"orderId": 2} +== APP == Order received: {"orderId": 3} +== APP == Order received: {"orderId": 4} +``` + +### Step 5: Introduce a fault + +Simulate a fault by stopping the `order-processor` service. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `order-processor` service as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB +``` + +In the `order-processor` window, stop the service: + +{{< tabs "MacOs" "Windows" >}} + + + +{{% codetab %}} + +```script +CMD + C +``` + +{{% /codetab %}} + + + +{{% codetab %}} + +```script +CTRL + C +``` + +{{% /codetab %}} + +{{< /tabs >}} + + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0005] Error processing operation endpoint[order-processor, order-processor:orders]. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0025] Circuit breaker "order-processor:orders" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +INFO[0030] Circuit breaker "order-processor:orders" changed state from open to half-open +INFO[0030] Circuit breaker "order-processor:orders" changed state from half-open to open +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 6: Remove the fault + +Once you restart the `order-processor` service, the application will recover seamlessly, picking up where it left off. + +In the `order-processor` service terminal, restart the application: + +```bash +dapr run --app-port 6001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- go run . +``` + +`checkout` service output: + +``` +== APP == Order passed: {"orderId": 5} +== APP == Order passed: {"orderId": 6} +== APP == Order passed: {"orderId": 7} +== APP == Order passed: {"orderId": 8} +== APP == Order passed: {"orderId": 9} +== APP == Order passed: {"orderId": 10} +``` + +`order-processor` service output: + +``` +== APP == Order received: {"orderId": 5} +== APP == Order received: {"orderId": 6} +== APP == Order received: {"orderId": 7} +== APP == Order received: {"orderId": 8} +== APP == Order received: {"orderId": 9} +== APP == Order received: {"orderId": 10} +``` + +{{% /codetab %}} + +{{< /tabs >}} + +## Tell us what you think! +We're continuously working to improve our Quickstart examples and value your feedback. Did you find this quickstart helpful? Do you have suggestions for improvement? + +Join the discussion in our [discord channel](https://discord.com/channels/778680217417809931/953427615916638238). + +## Next steps +Visit [this](https://docs.dapr.io/operations/resiliency/resiliency-overview//) link for more information about Dapr resiliency. + +{{< button text="Explore Dapr tutorials >>" page="getting-started/tutorials/_index.md" >}} diff --git a/daprdocs/content/en/getting-started/quickstarts/resiliency/resiliency-state-quickstart.md b/daprdocs/content/en/getting-started/quickstarts/resiliency/resiliency-state-quickstart.md new file mode 100644 index 000000000..c4df04973 --- /dev/null +++ b/daprdocs/content/en/getting-started/quickstarts/resiliency/resiliency-state-quickstart.md @@ -0,0 +1,900 @@ +--- +type: docs +title: "Quickstart: Service-to-component resiliency" +linkTitle: "Resiliency: State Management" +weight: 110 +description: "Get started with Dapr's resiliency capabilities via the state management API" +--- + +{{% alert title="Note" color="primary" %}} + Resiliency is currently a preview feature. +{{% /alert %}} + +Observe Dapr resiliency capabilities by simulating a system failure. In this Quickstart, you will: + +- Execute a microservice application with resiliency enabled that continuously persists and retrieves state via Dapr's state management API. +- Trigger the resiliency spec by simulating a system failure. +- Remove the failure to allow the microservice application to resume. + +Diagram showing the resiliency applied to Dapr APIs + +Select your preferred language-specific Dapr SDK before proceeding with the Quickstart. + +{{< tabs "Python" "JavaScript" ".NET" "Java" "Go" >}} + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- [Python 3.7+ installed](https://www.python.org/downloads/). + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/resiliency). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +In a terminal window, navigate to the `order-processor` directory. + +```bash +cd ../state_management/python/sdk/order-processor +``` + +Install dependencies + +```bash +pip3 install -r requirements.txt +``` + +### Step 2: Run the application with resiliency enabled + +Run the `order-processor` service alongside a Dapr sidecar. In the `dapr run` command below the `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-id order-processor ../config.yaml --components-path ../../../components/ -- python3 +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - checkout + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB + ``` + +Once the application has started, the `order-processor`service writes and reads `orderId` key/value pairs to the `statestore` Redis instance [defined in the `statestore.yaml` component]({{< ref "statemanagement-quickstart.md#statestoreyaml-component-file" >}}). + +```bash +== APP == Saving Order: { orderId: '1' } +== APP == Getting Order: { orderId: '1' } +== APP == Saving Order: { orderId: '2' } +== APP == Getting Order: { orderId: '2' } +== APP == Saving Order: { orderId: '3' } +== APP == Getting Order: { orderId: '3' } +== APP == Saving Order: { orderId: '4' } +== APP == Getting Order: { orderId: '4' } +``` + +### Step 3: Introduce a fault + +Simulate a fault by stopping the Redis `statestore.yaml` instance that was initalized when executing `dapr init` on your development machine. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `statestore.yaml` component as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + components: + statestore: + outbound: + retry: retryForever + circuitBreaker: simpleCB +``` + +In a new terminal window, run the following command: + +```bash +docker stop dapr_redis +``` + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0006] Error processing operation component[statestore] output. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0026] Circuit breaker "simpleCB-statestore" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from half-open to open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from half-open to closed +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 3: Remove the fault + +Once you restart the Redis container on your machine, the application will recover seamlessly, picking up where it left off. + +```bash +docker start dapr_redis +``` + +```bash +INFO[0036] Recovered processing operation component[statestore] output. +== APP == Saving Order: { orderId: '5' } +== APP == Getting Order: { orderId: '5' } +== APP == Saving Order: { orderId: '6' } +== APP == Getting Order: { orderId: '6' } +== APP == Saving Order: { orderId: '7' } +== APP == Getting Order: { orderId: '7' } +== APP == Saving Order: { orderId: '8' } +== APP == Getting Order: { orderId: '8' } +== APP == Saving Order: { orderId: '9' } +== APP == Getting Order: { orderId: '9' } +``` + +{{% /codetab %}} + + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- [Latest Node.js installed](https://nodejs.org/download/). + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/resiliency). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +In a terminal window, navigate to the `order-processor` directory. + +```bash +cd ../state_management/javascript/sdk/order-processor +``` + +Install dependencies + +```bash +npm install +``` + +### Step 2: Run the application with resiliency enabled + +Run the `order-processor` service alongside a Dapr sidecar. In the `dapr run` command below the `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-id order-processor ../config.yaml --components-path ../../../components/ -- npm start +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - checkout + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB + ``` + +Once the application has started, the `order-processor`service writes and reads `orderId` key/value pairs to the `statestore` Redis instance [defined in the `statestore.yaml` component]({{< ref "statemanagement-quickstart.md#statestoreyaml-component-file" >}}). + +```bash +== APP == Saving Order: { orderId: '1' } +== APP == Getting Order: { orderId: '1' } +== APP == Saving Order: { orderId: '2' } +== APP == Getting Order: { orderId: '2' } +== APP == Saving Order: { orderId: '3' } +== APP == Getting Order: { orderId: '3' } +== APP == Saving Order: { orderId: '4' } +== APP == Getting Order: { orderId: '4' } +``` + +### Step 3: Introduce a fault + +Simulate a fault by stopping the Redis `statestore.yaml` instance that was initalized when executing `dapr init` on your development machine. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `statestore.yaml` component as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + components: + statestore: + outbound: + retry: retryForever + circuitBreaker: simpleCB +``` + +In a new terminal window, run the following command: + +```bash +docker stop dapr_redis +``` + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0006] Error processing operation component[statestore] output. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0026] Circuit breaker "simpleCB-statestore" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from half-open to open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from half-open to closed +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 3: Remove the fault + +Once you restart the Redis container on your machine, the application will recover seamlessly, picking up where it left off. + +```bash +docker start dapr_redis +``` + +```bash +INFO[0036] Recovered processing operation component[statestore] output. +== APP == Saving Order: { orderId: '5' } +== APP == Getting Order: { orderId: '5' } +== APP == Saving Order: { orderId: '6' } +== APP == Getting Order: { orderId: '6' } +== APP == Saving Order: { orderId: '7' } +== APP == Getting Order: { orderId: '7' } +== APP == Saving Order: { orderId: '8' } +== APP == Getting Order: { orderId: '8' } +== APP == Saving Order: { orderId: '9' } +== APP == Getting Order: { orderId: '9' } +``` + +{{% /codetab %}} + + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- [.NET SDK or .NET 6 SDK installed](https://dotnet.microsoft.com/download). + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/resiliency). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +In a terminal window, navigate to the `order-processor` directory. + +```bash +cd ../state_management/csharp/sdk/order-processor +``` + +Install dependencies + +```bash +dotnet restore +dotnet build +``` + +### Step 2: Run the application with resiliency enabled + +Run the `order-processor` service alongside a Dapr sidecar. In the `dapr run` command below the `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-id order-processor --config ../config.yaml --components-path ../../../components/ -- dotnet run +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - checkout + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB + ``` + +Once the application has started, the `order-processor`service writes and reads `orderId` key/value pairs to the `statestore` Redis instance [defined in the `statestore.yaml` component]({{< ref "statemanagement-quickstart.md#statestoreyaml-component-file" >}}). + +```bash +== APP == Saving Order: { orderId: '1' } +== APP == Getting Order: { orderId: '1' } +== APP == Saving Order: { orderId: '2' } +== APP == Getting Order: { orderId: '2' } +== APP == Saving Order: { orderId: '3' } +== APP == Getting Order: { orderId: '3' } +== APP == Saving Order: { orderId: '4' } +== APP == Getting Order: { orderId: '4' } +``` + +### Step 3: Introduce a fault + +Simulate a fault by stopping the Redis `statestore.yaml` instance that was initalized when executing `dapr init` on your development machine. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `statestore.yaml` component as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + components: + statestore: + outbound: + retry: retryForever + circuitBreaker: simpleCB +``` + +In a new terminal window, run the following command: + +```bash +docker stop dapr_redis +``` + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0006] Error processing operation component[statestore] output. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0026] Circuit breaker "simpleCB-statestore" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from half-open to open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from half-open to closed +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 3: Remove the fault + +Once you restart the Redis container on your machine, the application will recover seamlessly, picking up where it left off. + +```bash +docker start dapr_redis +``` + +```bash +INFO[0036] Recovered processing operation component[statestore] output. +== APP == Saving Order: { orderId: '5' } +== APP == Getting Order: { orderId: '5' } +== APP == Saving Order: { orderId: '6' } +== APP == Getting Order: { orderId: '6' } +== APP == Saving Order: { orderId: '7' } +== APP == Getting Order: { orderId: '7' } +== APP == Saving Order: { orderId: '8' } +== APP == Getting Order: { orderId: '8' } +== APP == Saving Order: { orderId: '9' } +== APP == Getting Order: { orderId: '9' } +``` + +{{% /codetab %}} + + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- Java JDK 11 (or greater): + - [Oracle JDK](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK11), or + - OpenJDK +- [Apache Maven](https://maven.apache.org/install.html), version 3.x. + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/resiliency). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +In a terminal window, navigate to the `order-processor` directory. + +```bash +cd ../state_management/java/sdk/order-processor +``` + +Install dependencies + +```bash +mvn clean install +``` + +### Step 2: Run the application with resiliency enabled + +Run the `order-processor` service alongside a Dapr sidecar. In the `dapr run` command below the `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-id order-processor --config ../config.yaml --components-path ../../../components/ -- java -jar target/OrderProcessingService-0.0.1-SNAPSHOT.jar +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - checkout + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + apps: + order-processor: + retry: retryForever + circuitBreaker: simpleCB + ``` + +Once the application has started, the `order-processor`service writes and reads `orderId` key/value pairs to the `statestore` Redis instance [defined in the `statestore.yaml` component]({{< ref "statemanagement-quickstart.md#statestoreyaml-component-file" >}}). + +```bash +== APP == Saving Order: { orderId: '1' } +== APP == Getting Order: { orderId: '1' } +== APP == Saving Order: { orderId: '2' } +== APP == Getting Order: { orderId: '2' } +== APP == Saving Order: { orderId: '3' } +== APP == Getting Order: { orderId: '3' } +== APP == Saving Order: { orderId: '4' } +== APP == Getting Order: { orderId: '4' } +``` + +### Step 3: Introduce a fault + +Simulate a fault by stopping the Redis `statestore.yaml` instance that was initalized when executing `dapr init` on your development machine. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `statestore.yaml` component as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + components: + statestore: + outbound: + retry: retryForever + circuitBreaker: simpleCB +``` + +In a new terminal window, run the following command: + +```bash +docker stop dapr_redis +``` + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0006] Error processing operation component[statestore] output. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0026] Circuit breaker "simpleCB-statestore" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from half-open to open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from half-open to closed +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 3: Remove the fault + +Once you restart the Redis container on your machine, the application will recover seamlessly, picking up where it left off. + +```bash +docker start dapr_redis +``` + +```bash +INFO[0036] Recovered processing operation component[statestore] output. +== APP == Saving Order: { orderId: '5' } +== APP == Getting Order: { orderId: '5' } +== APP == Saving Order: { orderId: '6' } +== APP == Getting Order: { orderId: '6' } +== APP == Saving Order: { orderId: '7' } +== APP == Getting Order: { orderId: '7' } +== APP == Saving Order: { orderId: '8' } +== APP == Getting Order: { orderId: '8' } +== APP == Saving Order: { orderId: '9' } +== APP == Getting Order: { orderId: '9' } +``` + +{{% /codetab %}} + + +{{% codetab %}} + +### Pre-requisites + +For this example, you will need: + +- [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). +- [Latest version of Go](https://go.dev/dl/). + +- [Docker Desktop](https://www.docker.com/products/docker-desktop) + + +### Step 1: Set up the environment + +Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/resiliency). + +```bash +git clone https://github.com/dapr/quickstarts.git +``` + +In a terminal window, navigate to the `order-processor` directory. + +```bash +cd ../state_management/go/sdk/order-processor +``` + +Install dependencies + +```bash +go build . +``` + +### Step 2: Run the application with resiliency enabled + +Run the `order-processor` service alongside a Dapr sidecar. In the `dapr run` command below the `--config` parameter applies a Dapr configuration that enables the resiliency feature. + +```bash +dapr run --app-id order-processor --config ../config.yaml --components-path ../../../components -- go run . +``` + +The resilency spec is: +- Located in the `components` directory. +- Automatically discovered by the Dapr sidecar when run in standalone mode. + + ```yaml + apiVersion: dapr.io/v1alpha1 + kind: Resiliency + metadata: + name: myresiliency + scopes: + - order-processor + + spec: + policies: + retries: + retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 + + circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 + + targets: + components: + statestore: + outbound: + retry: retryForever + circuitBreaker: simpleCB + ``` + +Once the application has started, the `order-processor`service writes and reads `orderId` key/value pairs to the `statestore` Redis instance [defined in the `statestore.yaml` component]({{< ref "statemanagement-quickstart.md#statestoreyaml-component-file" >}}). + +```bash +== APP == Saving Order: { orderId: '1' } +== APP == Getting Order: { orderId: '1' } +== APP == Saving Order: { orderId: '2' } +== APP == Getting Order: { orderId: '2' } +== APP == Saving Order: { orderId: '3' } +== APP == Getting Order: { orderId: '3' } +== APP == Saving Order: { orderId: '4' } +== APP == Getting Order: { orderId: '4' } +``` + +### Step 3: Introduce a fault + +Simulate a fault by stopping the Redis `statestore.yaml` instance that was initalized when executing `dapr init` on your development machine. Once the instance is stopped, write and read operations from the order-processor service begin to fail. + +Since the `resiliency.yaml` spec defines the `statestore.yaml` component as a target, all failed requests will apply retry and circuit breaker policies: + +```yaml + targets: + components: + statestore: + outbound: + retry: retryForever + circuitBreaker: simpleCB +``` + +In a new terminal window, run the following command: + +```bash +docker stop dapr_redis +``` + +Once the first request fails, the retry policy titled `retryForever` is applied: + +```bash +INFO[0006] Error processing operation component[statestore] output. Retrying... +``` + +Retries will continue for each failed request indefinitely, in 5 second intervals. + +```yaml +retryForever: + policy: constant + maxInterval: 5s + maxRetries: -1 +``` + +Once 5 consecutive retries have failed, the circuit breaker policy, `simpleCB`, is tripped and the breaker opens, halting all requests: + +```bash +INFO[0026] Circuit breaker "simpleCB-statestore" changed state from closed to open +``` + +```yaml +circuitBreakers: + simpleCB: + maxRequests: 1 + timeout: 5s + trip: consecutiveFailures >= 5 +``` + +After 5 seconds has surpassed, the circuit breaker will switch to a half-open state, allowing one request through to verify if the fault has been resolved. If the request continues to fail, the circuit will trip back to the open state. + +```bash +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0031] Circuit breaker "simpleCB-statestore" changed state from half-open to open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from open to half-open +INFO[0036] Circuit breaker "simpleCB-statestore" changed state from half-open to closed +``` + +This half-open/open behavior will continue for as long as the Redis container is stopped. + +### Step 3: Remove the fault + +Once you restart the Redis container on your machine, the application will recover seamlessly, picking up where it left off. + +```bash +docker start dapr_redis +``` + +```bash +INFO[0036] Recovered processing operation component[statestore] output. +== APP == Saving Order: { orderId: '5' } +== APP == Getting Order: { orderId: '5' } +== APP == Saving Order: { orderId: '6' } +== APP == Getting Order: { orderId: '6' } +== APP == Saving Order: { orderId: '7' } +== APP == Getting Order: { orderId: '7' } +== APP == Saving Order: { orderId: '8' } +== APP == Getting Order: { orderId: '8' } +== APP == Saving Order: { orderId: '9' } +== APP == Getting Order: { orderId: '9' } +``` + +{{% /codetab %}} + +{{< /tabs >}} + +## Tell us what you think! +We're continuously working to improve our Quickstart examples and value your feedback. Did you find this quickstart helpful? Do you have suggestions for improvement? + +Join the discussion in our [discord channel](https://discord.com/channels/778680217417809931/953427615916638238). + +## Next steps + +Learn more about [the resiliency feature]({{< ref resiliency-overview.md >}}) and how it works with Dapr's building block APIs. + +{{< button text="Explore Dapr tutorials >>" page="getting-started/tutorials/_index.md" >}}