Quality of Service¶
Label: QoS
Ocelot supports one QoS capability at the current time. You can set on a per Route basis if you want to use a circuit breaker when making requests to a downstream service. This uses an awesome .NET library called Polly, check them out in official repository.
The first thing you need to do if you want to use the Administration API is bring in the relevant NuGet package:
Install-Package Ocelot.Provider.Polly
Then in your ConfigureServices
method to add Polly services we must call the AddPolly()
extension of the OcelotBuilder
being returned by AddOcelot()
[1] like below:
services.AddOcelot()
.AddPolly();
Then add the following section to a Route configuration:
"QoSOptions": {
"ExceptionsAllowedBeforeBreaking": 3,
"DurationOfBreak": 1000,
"TimeoutValue": 5000
}
You must set a number equal or greater than
2
against ExceptionsAllowedBeforeBreaking for this rule to be implemented. [2]DurationOfBreak means the circuit breaker will stay open for 1 second after it is tripped.
TimeoutValue means if a request takes more than 5 seconds, it will automatically be timed out.
You can set the TimeoutValue in isolation of the ExceptionsAllowedBeforeBreaking and DurationOfBreak options:
"QoSOptions": {
"TimeoutValue": 5000
}
There is no point setting the other two in isolation as they affect each other!
Defaults¶
If you do not add a QoS section, QoS will not be used, however Ocelot will default to a 90 seconds timeout on all downstream requests. If someone needs this to be configurable, open an issue. [2]
Polly v7 vs v8¶
Important changes in version 23.2: [3]
With Polly version 8+, the
ExceptionsAllowedBeforeBreaking
value must be equal to or greater than 2!The
AddPolly
method has been migrated from v7 policy wrappers to v8 resilience pipelines. Consequently, it now exhibits different behavior based on v8 pipelines.
If you prefer not to modify your settings, you can continue using Polly v7 as follows:
services.AddOcelot()
.AddPollyV7();
Note: Support for Polly v7 will be removed in a future version. We recommend avoiding this method (which is tagged as Obsolete
) unless absolutely necessary.
Extensibility [3]¶
If you want to use your ResiliencePipeline<T>
provider, you can use the following syntax:
services.AddOcelot()
.AddPolly<MyProvider>();
// MyProvider should implement IPollyQoSResiliencePipelineProvider<HttpResponseMessage>
// Note: you can use standard provider PollyQoSResiliencePipelineProvider
If, in addition, you want to use your own DelegatingHandler
, you can use the following syntax:
services.AddOcelot()
.AddPolly<MyProvider>(MyQosDelegatingHandlerDelegate);
// MyProvider should implement IPollyQoSResiliencePipelineProvider<HttpResponseMessage>
// Note: you can use standard provider PollyQoSResiliencePipelineProvider
// MyQosDelegatingHandlerDelegate is a delegate use to get a DelegatingHandler
And finally, if you want to define your own set of exceptions to map, you can use the following syntax:
services.AddOcelot()
.AddPolly<MyProvider>(MyErrorMapping);
// MyProvider should implement IPollyQoSResiliencePipelineProvider<HttpResponseMessage>
// Note: you can use standard provider PollyQoSResiliencePipelineProvider
// MyErrorMapping is a Dictionary<Type, Func<Exception, Error>>, eg:
private static readonly Dictionary<Type, Func<Exception, Error>> MyErrorMapping = new()
{
{typeof(TaskCanceledException), CreateError},
{typeof(TimeoutRejectedException), CreateError},
{typeof(BrokenCircuitException), CreateError},
{typeof(BrokenCircuitException<HttpResponseMessage>), CreateError},
};
private static Error CreateError(Exception e) => new RequestTimedOutError(e);