.. role:: htm(raw)
:format: html
.. role:: pdf(raw)
:format: latex pdflatex
.. _Program: https://github.com/ThreeMammals/Ocelot/blob/main/samples/Basic/Program.cs
.. _Polly: https://www.thepollyproject.org
.. _documentation: https://www.pollydocs.org
.. |QoS_label| image:: https://img.shields.io/badge/-QoS-D3ADAF.svg
:target: https://github.com/ThreeMammals/Ocelot/labels/QoS
:alt: label QoS
:class: img-valign-textbottom
Quality of Service
==================
Repository Label: |QoS_label|:pdf:`\href{https://github.com/ThreeMammals/Ocelot/labels/QoS}{QoS}`
Ocelot currently supports a single *Quality of Service* (QoS) capability.
It allows you to configure, on a per-route basis, the application of a circuit breaker when making requests to downstream services.
This feature leverages a well-regarded .NET library known as `Polly`_.
For more details, visit the Polly library's official `repository `_.
Installation
------------
To utilize the :ref:`administration-api`, begin by importing the appropriate `NuGet package `_:
.. code-block:: powershell
Install-Package Ocelot.Provider.Polly
Next, in your `Program`_, incorporate `Polly`_ services by invoking the ``AddPolly()`` extension on the ``OcelotBuilder``, as shown below [#f1]_:
.. code-block:: csharp
:emphasize-lines: 5
using Ocelot.Provider.Polly;
builder.Services
.AddOcelot(builder.Configuration)
.AddPolly();
.. _qos-configuration:
Configuration
-------------
Then add the following section to a route configuration:
.. code-block:: json
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 1000, // ms
"TimeoutValue": 5000 // ms
}
- To implement this rule, you must set a value of **2** or higher for ``ExceptionsAllowedBeforeBreaking``. [#f2]_
- ``DurationOfBreak`` indicates that the circuit breaker will remain open for **1** second after being triggered.
- ``TimeoutValue`` specifies that if a request exceeds **5** seconds, it will automatically time out.
.. _qos-circuit-breaker-strategy:
Circuit Breaker strategy
------------------------
The options ``ExceptionsAllowedBeforeBreaking`` and ``DurationOfBreak`` can be configured independently from ``TimeoutValue``:
.. code-block:: json
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 1000
}
Alternatively, you can omit ``DurationOfBreak``, which will default to the implicit 5-second setting as specified in Polly's `documentation`_:
.. code-block:: json
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3
}
This setup activates only the `Circuit breaker `_ strategy.
.. _qos-timeout-strategy:
Timeout strategy
----------------
The ``TimeoutValue`` can be configured independently from the ``ExceptionsAllowedBeforeBreaking`` and ``DurationOfBreak`` options:
.. code-block:: json
"QoSOptions": {
"TimeoutValue": 5000 // ms
}
This setup activates only the `Timeout `_ strategy.
Notes
-----
1. If a *QoS* section is not included, *QoS* will not be applied, and Ocelot will enforce a default timeout of **90** `seconds `_ for all downstream requests.
To request additional configurability, consider opening an issue. [#f3]_
2. The `Polly`_ V7 syntax is no longer supported as of version `23.2`_. [#f4]_
3. Starting with `Polly`_ V8, the `documentation`_ outlines the following constraints on values:
* The ``ExceptionsAllowedBeforeBreaking`` value must be **2** or higher.
* The ``DurationOfBreak`` value must exceed **500** milliseconds, defaulting to **5000** milliseconds (5 seconds) if unspecified or if the value is **500** milliseconds or less.
* The ``TimeoutValue`` must be over **10** milliseconds.
Refer to the `Resilience strategies `_ documentation for a comprehensive explanation of each option.
.. _qos-extensibility:
Extensibility [#f4]_
--------------------
To use your ``ResiliencePipeline`` provider, you can apply the following syntax:
.. code-block:: csharp
:emphasize-lines: 3
builder.Services
.AddOcelot(builder.Configuration)
.AddPolly();
// MyProvider should implement IPollyQoSResiliencePipelineProvider
// Note: you can use standard provider PollyQoSResiliencePipelineProvider
Additionally, if you want to utilize your own ``DelegatingHandler``, the following syntax can be applied:
.. code-block:: csharp
:emphasize-lines: 3
builder.Services
.AddOcelot(builder.Configuration)
.AddPolly(MyQosDelegatingHandlerDelegate);
// MyQosDelegatingHandlerDelegate is a delegate use to get a DelegatingHandler. Refer to Ocelot's PollyResiliencePipelineDelegatingHandler
Finally, to define your own set of exceptions for mapping, you can apply the following syntax:
.. code-block:: csharp
:emphasize-lines: 11
static Error CreateError(Exception e) => new RequestTimedOutError(e);
Dictionary> MyErrorMapping = new()
{
{typeof(TaskCanceledException), CreateError},
{typeof(TimeoutRejectedException), CreateError},
{typeof(BrokenCircuitException), CreateError},
{typeof(BrokenCircuitException), CreateError},
};
builder.Services
.AddOcelot(builder.Configuration)
.AddPolly(MyErrorMapping);
// Note: Default error mapping is defined in the DefaultErrorMapping field of the Ocelot.Provider.Polly.OcelotBuilderExtensions class
""""
.. [#f1] The :ref:`di-services-addocelot-method` adds default ASP.NET services to the DI container. You can call another extended :ref:`di-addocelotusingbuilder-method` while configuring services to develop your own :ref:`di-custom-builder`. See more instructions in the ":ref:`di-addocelotusingbuilder-method`" section of the :doc:`../features/dependencyinjection` feature.
.. [#f2] If something doesn't work or you're stuck, consider reviewing the current `QoS issues `_ filtered by the |QoS_label| label.
.. [#f3] Recently, surrounding the release of version `24.0`_, we opened pull request `2073`_ to address the issue of default timeout configurations. This is a high-priority pull request, and the feature will be included in an upcoming major or minor release (excluding patches).
.. [#f4] We upgraded `Polly`_ from version 7.x to 8.x! The :ref:`qos-extensibility` feature was requested in issue `1875`_ and implemented through pull request `1914`_, as part of version `23.2`_.
.. _1875: https://github.com/ThreeMammals/Ocelot/issues/1875
.. _1914: https://github.com/ThreeMammals/Ocelot/pull/1914
.. _2073: https://github.com/ThreeMammals/Ocelot/pull/2073
.. _23.2: https://github.com/ThreeMammals/Ocelot/releases/tag/23.2.0
.. _24.0: https://github.com/ThreeMammals/Ocelot/releases/tag/24.0.0