Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Tworzenie niezawodnych aplikacji HTTP, które mogą odzyskiwać dane po błędach przejściowych, jest typowym wymaganiem. W tym artykule założono, że znasz już artykuł Introduction to resilient app development (Wprowadzenie do odpornego programowania aplikacji), ponieważ ten artykuł rozszerza podstawowe pojęcia, które zostały przekazane. Aby ułatwić tworzenie odpornych aplikacji HTTP, pakiet NuGet Microsoft.Extensions.Http.Resilience zapewnia mechanizmy odporności specjalnie dla elementu HttpClient. Ten pakiet NuGet opiera się na Microsoft.Extensions.Resilience
bibliotece i polly, która jest popularnym projektem open source. Aby uzyskać więcej informacji, zobacz Polly.
Rozpocznij
Aby użyć wzorców odporności w aplikacjach HTTP, zainstaluj pakiet NuGet Microsoft.Extensions.Http.Resilience .
dotnet add package Microsoft.Extensions.Http.Resilience --version 8.0.0
Aby uzyskać więcej informacji, zobacz dotnet package add or Manage package dependencies in .NET applications (Dodawanie pakietów dotnet lub zarządzanie zależnościami pakietów w aplikacjach platformy .NET).
Dodawanie odporności do klienta HTTP
Aby zwiększyć odporność do HttpClient, należy utworzyć łańcuch wywołań dla typu IHttpClientBuilder zwracanego przez wywołanie dowolnej z dostępnych metod AddHttpClient. Aby uzyskać więcej informacji, zobacz IHttpClientFactory with .NET (IHttpClientFactory z platformą .NET).
Dostępnych jest kilka rozszerzeń skoncentrowanych na odporności. Niektóre z nich są standardowe, dlatego stosują różne najlepsze rozwiązania branżowe, a inne są bardziej dostosowywane. Podczas dodawania odporności należy dodać tylko jednego obsługującego odporność i unikać nawarstwiania obsługujących. Jeśli musisz dodać wiele procedur obsługi odporności, rozważ użycie AddResilienceHandler
metody rozszerzenia, która umożliwia dostosowanie strategii odporności.
Ważne
Wszystkie przykłady w tym artykule opierają się na interfejsie API AddHttpClient z biblioteki Microsoft.Extensions.Http , która zwraca instancję IHttpClientBuilder. Wystąpienie IHttpClientBuilder służy do konfigurowania HttpClient i dodawania mechanizmu odporności.
Dodawanie standardowego mechanizmu obsługi odpornościowej
Standardowy program obsługi odporności stosuje wiele strategii odpornościowych nałożonych na siebie, z domyślnymi opcjami do wysyłania żądań i obsługi wszelkich błędów przejściowych. Standardowy handler odporności dodaje się przez wywołanie AddStandardResilienceHandler
metody rozszerzenia na wystąpieniu IHttpClientBuilder.
var services = new ServiceCollection();
var httpClientBuilder = services.AddHttpClient<ExampleClient>(
configureClient: static client =>
{
client.BaseAddress = new("https://jsonplaceholder.typicode.com");
});
Poprzedzający kod:
- Tworzy instancję ServiceCollection.
- Dodaje element HttpClient typu
ExampleClient
do kontenera usługi. - Konfiguruje HttpClient do korzystania z
"https://jsonplaceholder.typicode.com"
jako adresu podstawowego. - Tworzy element
httpClientBuilder
używany w innych przykładach w tym artykule.
Bardziej rzeczywisty przykład polegałby na hostingu, takim jak opisany w artykule .NET Generic Host. Korzystając z pakietu NuGet Microsoft.Extensions.Hosting, rozważmy następujący zaktualizowany przykład:
using Http.Resilience.Example;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
IHttpClientBuilder httpClientBuilder = builder.Services.AddHttpClient<ExampleClient>(
configureClient: static client =>
{
client.BaseAddress = new("https://jsonplaceholder.typicode.com");
});
Kod ten jest podobny do ręcznego podejścia ServiceCollection
tworzenia, ale zamiast tego opiera się na Host.CreateApplicationBuilder() do budowy hosta, który udostępnia usługi.
Element ExampleClient
jest zdefiniowany w następujący sposób:
using System.Net.Http.Json;
namespace Http.Resilience.Example;
/// <summary>
/// An example client service, that relies on the <see cref="HttpClient"/> instance.
/// </summary>
/// <param name="client">The given <see cref="HttpClient"/> instance.</param>
internal sealed class ExampleClient(HttpClient client)
{
/// <summary>
/// Returns an <see cref="IAsyncEnumerable{T}"/> of <see cref="Comment"/>s.
/// </summary>
public IAsyncEnumerable<Comment?> GetCommentsAsync()
{
return client.GetFromJsonAsAsyncEnumerable<Comment>("/comments");
}
}
Poprzedzający kod:
- Definiuje typ
ExampleClient
, który ma konstruktor akceptujący HttpClient. - Uwidacznia metodę
GetCommentsAsync
, która wysyła żądanie GET do punktu końcowego/comments
i zwraca odpowiedź.
Typ jest definiowany Comment
w następujący sposób:
namespace Http.Resilience.Example;
public record class Comment(
int PostId, int Id, string Name, string Email, string Body);
Biorąc pod uwagę, że utworzono IHttpClientBuilder (httpClientBuilder
), a teraz rozumiesz implementację ExampleClient
i odpowiedni model Comment
, rozważmy następujący przykład:
httpClientBuilder.AddStandardResilienceHandler();
Poprzedni kod dodaje standardowy mechanizm zapewniający odporność do elementu HttpClient. Jak w przypadku większości interfejsów API dotyczących odporności, istnieją mechanizmy przeciążenia, które umożliwiają dostosowanie domyślnych opcji i zastosowanych strategii zwiększania odporności.
Usuń standardowe mechanizmy odporności
Istnieje metoda RemoveAllResilienceHandlers, która usuwa wszystkie wcześniej zarejestrowane procedury obsługi odporności. Jest to przydatne, gdy musisz wyczyścić istniejące mechanizmy odporności, aby dodać własny niestandardowy mechanizm.
W poniższym przykładzie pokazano, jak skonfigurować niestandardową HttpClient przy użyciu metody AddHttpClient
, usunąć wszystkie wstępnie zdefiniowane strategie odporności i zastąpić je nowymi procedurami obsługi.
Takie podejście umożliwia wyczyszczenie istniejących konfiguracji i zdefiniowanie nowych zgodnie z określonymi wymaganiami.
// By default, we want all HttpClient instances to include the StandardResilienceHandler.
services.ConfigureHttpClientDefaults(builder => builder.AddStandardResilienceHandler());
// For a named HttpClient "custom" we want to remove the StandardResilienceHandler and add the StandardHedgingHandler instead.
services.AddHttpClient("custom")
.RemoveAllResilienceHandlers()
.AddStandardHedgingHandler();
Poprzedzający kod:
- Tworzy instancję ServiceCollection.
- Dodaje standardowy mechanizm obsługi odporności do wszystkich wystąpień HttpClient.
- Dla "niestandardowego" HttpClient:
- Usuwa wszystkie wstępnie zdefiniowane mechanizmy odporności, które zostały wcześniej zarejestrowane. Jest to przydatne, gdy chcesz zacząć od czystego stanu, aby dodać własne strategie niestandardowe.
- Dodaje
StandardHedgingHandler
do HttpClient. Możesz zastąpićAddStandardHedgingHandler()
dowolną strategią, która odpowiada potrzebom aplikacji, takimi jak mechanizmy ponawiania prób, wyłączniki lub inne techniki odporności.
Domyślne ustawienia standardowej obsługi odporności
Domyślna konfiguracja zawiera pięć strategii odporności w następującej kolejności (od najbardziej zewnętrznej do najbardziej wewnętrznej):
Zamówienie | Strategia | opis | Domyślne |
---|---|---|---|
1 | Ogranicznik szybkości | System ograniczający limituje maksymalną liczbę współbieżnych żądań wysyłanych do zależności. | Kolejka: 0 Pozwolenie: 1_000 |
2 | Łączny limit czasu | Łączny przepływ limitu czasu żądania stosuje ogólny limit czasu do wykonania, zapewniając, że żądanie, w tym ponawiane próby, nie przekracza skonfigurowanego limitu. | Łączny limit czasu: 30s |
3 | Ponów próbę | Mechanizm ponawiania ponawia żądanie w przypadku, gdy zależność jest wolna lub zwraca błąd przejściowy. | Maksymalna liczba ponownych prób: 3 Wycofanie: Exponential Użyj roztrzasku: true Opóźnienie:2s |
4 | Wyłącznik obwodu | Wyłącznik blokuje wykonywanie, jeśli wykryto zbyt wiele bezpośrednich awarii lub przekroczenia limitu czasu. | Współczynnik awarii: 10% Minimalna przepływność: 100 Czas trwania próbkowania: 30s Czas trwania przerwy: 5s |
5 | Przekroczenie czasu próby | Mechanizm limitu czasu dla próby ogranicza czas trwania każdej próby żądania i zgłasza wyjątek, jeśli czas ten zostanie przekroczony. | Limit czasu próby: 10s |
Ponawianie prób i wyłączniki awaryjne
Strategie ponawiania i wyłącznika obsługują zarówno zestaw określonych kodów stanu HTTP, jak i wyjątków. Rozważ następujące kody stanu HTTP:
- HTTP 500 lub nowszy (błędy serwera)
- HTTP 408 (przekroczenie limitu czasu żądania)
- HTTP 429 (zbyt wiele żądań)
Ponadto te strategie obsługują następujące wyjątki:
HttpRequestException
TimeoutRejectedException
Wyłącz ponawianie prób dla danej listy metod HTTP
Domyślnie program obsługi odporności standardowej jest skonfigurowany tak, aby ponawiać próby dla wszystkich metod HTTP. W przypadku niektórych aplikacji takie zachowanie może być niepożądane, a nawet szkodliwe. Jeśli na przykład żądanie POST wstawia nowy rekord do bazy danych, wykonanie ponownych prób dla takiego żądania może prowadzić do duplikowania danych. Jeśli musisz wyłączyć ponawianie prób dla danej listy metod HTTP, możesz użyć metody DisableFor(HttpRetryStrategyOptions, HttpMethod[]):
httpClientBuilder.AddStandardResilienceHandler(options =>
{
options.Retry.DisableFor(HttpMethod.Post, HttpMethod.Delete);
});
Alternatywnie można użyć metody DisableForUnsafeHttpMethods(HttpRetryStrategyOptions), która wyłącza ponawianie prób dla żądań POST
, PATCH
, PUT
, DELETE
i CONNECT
. Zgodnie z RFCmetody te są uważane za niebezpieczne; co oznacza, że ich semantyka nie jest przeznaczona wyłącznie do odczytu:
httpClientBuilder.AddStandardResilienceHandler(options =>
{
options.Retry.DisableForUnsafeHttpMethods();
});
Dodaj standardową procedurę obsługi zabezpieczania
Standardowy moduł obsługi hedgingu opakowuje wykonanie żądania za pomocą standardowego mechanizmu zabezpieczającego. Równoległe zabezpieczenie ponawia powolne żądania.
Aby użyć standardowego mechanizmu obsługi hedgingu, wywołaj metodę rozszerzającą AddStandardHedgingHandler
. W poniższym przykładzie skonfigurowaliśmy element ExampleClient
tak, aby używał standardowej procedury obsługi hedgingowej.
httpClientBuilder.AddStandardHedgingHandler();
Kod powyżej dodaje standardowy mechanizm obsługi hedgingu do elementu HttpClient.
Domyślne ustawienia standardowego mechanizmu zabezpieczającego
Standardowe zabezpieczenie wykorzystuje pulę przełączników, aby zapewnić, że punkty dostępu w złej kondycji nie są objęte zabezpieczeniem. Domyślnie wybór z puli jest oparty na autorytecie URL (schemat + host + port).
Napiwek
Zaleca się skonfigurowanie sposobu wybierania strategii przez wywołanie StandardHedgingHandlerBuilderExtensions.SelectPipelineByAuthority
lub StandardHedgingHandlerBuilderExtensions.SelectPipelineBy
w przypadku bardziej zaawansowanych scenariuszy.
Kod powyżej dodaje standardowy mechanizm obsługi hedgingu do elementu IHttpClientBuilder. Domyślna konfiguracja zawiera pięć strategii odporności w następującej kolejności (od najbardziej zewnętrznej do najbardziej wewnętrznej):
Zamówienie | Strategia | opis | Domyślne |
---|---|---|---|
1 | Całkowity czas oczekiwania na odpowiedź żądania | Łączny potok limitu czasu żądania stosuje ogólne ograniczenie czasowe do wykonania, zapewniając, że żądanie, w tym próby wyprzedzania, nie przekracza skonfigurowanego limitu. | Łączny limit czasu: 30s |
2 | Zabezpieczenia | Strategia zabezpieczania wykonuje żądania do wielu punktów końcowych, jeśli zależny system jest powolny lub zwraca błąd przejściowy. Routing to opcja, domyślnie po prostu dostosowuje adres URL dostarczony przez oryginalny HttpRequestMessage element. | Minimalna liczba prób: 1 Maksymalna liczba prób: 10 Opóźnienie: 2s |
3 | Ogranicznik szybkości (na punkt końcowy) | System ograniczający limituje maksymalną liczbę współbieżnych żądań wysyłanych do zależności. | Kolejka: 0 Pozwolenie: 1_000 |
4 | Wyłącznik (dla punktu końcowego) | Wyłącznik blokuje wykonywanie, jeśli wykryto zbyt wiele bezpośrednich awarii lub przekroczenia limitu czasu. | Współczynnik awarii: 10% Minimalna przepływność: 100 Czas trwania próbkowania: 30s Czas trwania przerwy: 5s |
5 | Limit czasu próby (na punkt końcowy) | Mechanizm limitu czasu dla próby ogranicza czas trwania każdej próby żądania i zgłasza wyjątek, jeśli czas ten zostanie przekroczony. | Limit czasu: 10s |
Dostosowywanie wyboru trasy mechanizmu hedgingowego
W przypadku korzystania ze standardowego mechanizmu wyznaczania granic można dostosować sposób wybierania punktów końcowych żądań, wywołując różne rozszerzenia dla typu IRoutingStrategyBuilder
. Może to być przydatne w przypadku scenariuszy, takich jak testowanie A/B, w których chcesz kierować procent żądań do innego punktu końcowego:
httpClientBuilder.AddStandardHedgingHandler(static (IRoutingStrategyBuilder builder) =>
{
// Hedging allows sending multiple concurrent requests
builder.ConfigureOrderedGroups(static options =>
{
options.Groups.Add(new UriEndpointGroup()
{
Endpoints =
{
// Imagine a scenario where 3% of the requests are
// sent to the experimental endpoint.
new() { Uri = new("https://example.net/api/experimental"), Weight = 3 },
new() { Uri = new("https://example.net/api/stable"), Weight = 97 }
}
});
});
});
Poprzedzający kod:
- Dodaje obsługę hedgingową do elementu IHttpClientBuilder.
- Konfiguruje
IRoutingStrategyBuilder
, aby używał metodyConfigureOrderedGroups
do konfigurowania uporządkowanych grup. - Dodaje element
EndpointGroup
doorderedGroup
obiektu , który kieruje 3% żądań dohttps://example.net/api/experimental
punktu końcowego i 97% żądań do punktu końcowegohttps://example.net/api/stable
. - Konfiguruje
IRoutingStrategyBuilder
, aby użyć metodyConfigureWeightedGroups
do konfiguracji.
Aby skonfigurować grupę ważoną, wywołaj metodę ConfigureWeightedGroups
dla IRoutingStrategyBuilder
typu . Poniższy przykład konfiguruje IRoutingStrategyBuilder
do użycia metody ConfigureWeightedGroups
w celu konfiguracji grup ważonych.
httpClientBuilder.AddStandardHedgingHandler(static (IRoutingStrategyBuilder builder) =>
{
// Hedging allows sending multiple concurrent requests
builder.ConfigureWeightedGroups(static options =>
{
options.SelectionMode = WeightedGroupSelectionMode.EveryAttempt;
options.Groups.Add(new WeightedUriEndpointGroup()
{
Endpoints =
{
// Imagine A/B testing
new() { Uri = new("https://example.net/api/a"), Weight = 33 },
new() { Uri = new("https://example.net/api/b"), Weight = 33 },
new() { Uri = new("https://example.net/api/c"), Weight = 33 }
}
});
});
});
Poprzedzający kod:
- Dodaje obsługę hedgingową do elementu IHttpClientBuilder.
- Konfiguruje
IRoutingStrategyBuilder
do używania metodyConfigureWeightedGroups
do konfigurowania grup ważonych. - Ustawia wartość
SelectionMode
naWeightedGroupSelectionMode.EveryAttempt
. - Dodaje
WeightedEndpointGroup
doweightedGroup
, który kieruje 33% żądań do punktu końcowegohttps://example.net/api/a
, 33% żądań do punktu końcowegohttps://example.net/api/b
i 33% żądań do punktu końcowegohttps://example.net/api/c
.
Napiwek
Maksymalna liczba prób zabezpieczenia bezpośrednio koreluje z liczbą skonfigurowanych grup. Jeśli na przykład masz dwie grupy, maksymalna liczba prób wynosi dwa.
Aby uzyskać więcej informacji, zobacz Polly docs: Strategia zabezpieczenia odporności.
Często konfiguruje się uporządkowaną grupę lub grupę ważoną, ale ważne jest skonfigurowanie obu tych grup. Użycie uporządkowanych i ważonych grup jest przydatne w scenariuszach, w których chcesz wysłać procent żądań do innego punktu końcowego, na przykład w przypadku testowania A/B.
Dodawanie niestandardowych mechanizmów odporności
Aby mieć większą kontrolę, możesz dostosować procedury obsługi odporności przy użyciu interfejsu AddResilienceHandler
API. Ta metoda przyjmuje delegata, który konfiguruje instancję ResiliencePipelineBuilder<HttpResponseMessage>
używaną do tworzenia strategii odpornościowej.
Aby skonfigurować nazwaną procedurę obsługi odporności, wywołaj metodę rozszerzenia AddResilienceHandler
z nazwą procedury obsługi. W poniższym przykładzie skonfigurowano procedurę obsługi odporności o nazwie "CustomPipeline"
.
httpClientBuilder.AddResilienceHandler(
"CustomPipeline",
static builder =>
{
// See: https://www.pollydocs.org/strategies/retry.html
builder.AddRetry(new HttpRetryStrategyOptions
{
// Customize and configure the retry logic.
BackoffType = DelayBackoffType.Exponential,
MaxRetryAttempts = 5,
UseJitter = true
});
// See: https://www.pollydocs.org/strategies/circuit-breaker.html
builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
// Customize and configure the circuit breaker logic.
SamplingDuration = TimeSpan.FromSeconds(10),
FailureRatio = 0.2,
MinimumThroughput = 3,
ShouldHandle = static args =>
{
return ValueTask.FromResult(args is
{
Outcome.Result.StatusCode:
HttpStatusCode.RequestTimeout or
HttpStatusCode.TooManyRequests
});
}
});
// See: https://www.pollydocs.org/strategies/timeout.html
builder.AddTimeout(TimeSpan.FromSeconds(5));
});
Poprzedzający kod:
- Dodaje procedurę obsługi odporności o nazwie
"CustomPipeline"
jakopipelineName
do kontenera usług. - Dodaje strategię ponawiania prób z wykładniczym wycofywaniem, pięcioma ponownymi próbami i preferencjami trząsania do konstruktora odporności.
- Dodaje strategię wyłącznika z czasem próbkowania wynoszącym 10 sekund, stosunkiem awarii wynoszącym 0,2 (20%), minimalną przepływnością wynoszącą trzy oraz predykatem, który obsługuje kody stanu HTTP
RequestTimeout
iTooManyRequests
do konstruktora odporności. - Dodaje strategię limitu czasu z czasem 5 sekund do narzędzia do budowania odporności.
Dla każdej strategii odporności jest dostępnych wiele opcji. Aby uzyskać więcej informacji, zobacz dokumentację usługi Polly: Strategies. Aby uzyskać więcej informacji na temat konfigurowania ShouldHandle
delegatów, zobacz dokumentacja Polly: fault handling w reaktywnych strategiach.
Ostrzeżenie
Jeśli używasz strategii ponawiania prób i limitu czasu i chcesz skonfigurować delegata ShouldHandle
w strategii ponawiania prób, upewnij się, że powinna obsługiwać wyjątek limitu czasu usługi Polly. Polly zgłasza element TimeoutRejectedException
(który dziedziczy z Exception), a nie standard TimeoutException.
Dynamiczne ponowne ładowanie
Usługa Polly obsługuje dynamiczne ponowne ładowanie skonfigurowanych strategii odporności. Oznacza to, że można zmienić konfigurację strategii odpornościowych w czasie działania. Aby włączyć dynamiczne ponowne ładowanie, użyj odpowiedniego przeciążenia AddResilienceHandler
, które uwidacznia ResilienceHandlerContext
. Biorąc pod uwagę kontekst, wywołaj EnableReloads
odpowiednie opcje strategii odporności:
httpClientBuilder.AddResilienceHandler(
"AdvancedPipeline",
static (ResiliencePipelineBuilder<HttpResponseMessage> builder,
ResilienceHandlerContext context) =>
{
// Enable reloads whenever the named options change
context.EnableReloads<HttpRetryStrategyOptions>("RetryOptions");
// Retrieve the named options
var retryOptions =
context.GetOptions<HttpRetryStrategyOptions>("RetryOptions");
// Add retries using the resolved options
builder.AddRetry(retryOptions);
});
Poprzedzający kod:
- Dodaje procedurę obsługi odporności o nazwie
"AdvancedPipeline"
jakopipelineName
do kontenera usług. - Włącza ponowne ładowanie pipeline'u
"AdvancedPipeline"
za każdym razem, gdy zmieniają się nazwane opcjeRetryStrategyOptions
. - Pobiera nazwane opcje z IOptionsMonitor<TOptions> usługi.
- Dodaje strategię ponawiania wraz z pobranymi opcjami do mechanizmu odpornościowego.
Aby uzyskać więcej informacji, zobacz dokumentację Polly: zaawansowane wstrzykiwanie zależności.
Ten przykład opiera się na sekcji opcji, która może ulec zmianie, takiej jak plik appsettings.json . Rozważ następujący plik appsettings.json :
{
"RetryOptions": {
"Retry": {
"BackoffType": "Linear",
"UseJitter": false,
"MaxRetryAttempts": 7
}
}
}
Teraz wyobraź sobie, że te opcje zostały powiązane z konfiguracją aplikacji, wiążąc element z HttpRetryStrategyOptions
sekcją "RetryOptions"
:
var section = builder.Configuration.GetSection("RetryOptions");
builder.Services.Configure<HttpStandardResilienceOptions>(section);
Aby uzyskać więcej informacji, zobacz Wzorzec opcji na platformie .NET.
Przykładowe użycie
Aplikacja opiera się na iniekcji zależności, aby rozwiązać ExampleClient
i odpowiadający mu HttpClient. Kod kompiluje element IServiceProvider i rozpoznaje element ExampleClient
z niego.
IHost host = builder.Build();
ExampleClient client = host.Services.GetRequiredService<ExampleClient>();
await foreach (Comment? comment in client.GetCommentsAsync())
{
Console.WriteLine(comment);
}
Poprzedzający kod:
- Kompiluje element IServiceProvider z pliku ServiceCollection.
- Usuwa element
ExampleClient
z elementu IServiceProvider. - Wywołuje metodę
GetCommentsAsync
naExampleClient
, aby uzyskać komentarze. - Zapisuje każdy komentarz do konsoli.
Wyobraź sobie sytuację, w której sieć ulegnie awarii lub serwer przestaje odpowiadać. Na poniższym diagramie pokazano, jak strategie odporności będą obsługiwać sytuację, biorąc pod uwagę metodę ExampleClient
i GetCommentsAsync
:
Powyższy diagram przedstawia:
- Obiekt
ExampleClient
wysyła żądanie HTTP GET do punktu końcowego/comments
. - Wartość HttpResponseMessage jest oceniana:
- Jeśli odpowiedź zakończy się pomyślnie (HTTP 200), zostanie zwrócona odpowiedź.
- Jeśli odpowiedź nie powiedzie się (HTTP kod inny niż 200), potok odporności wykorzystuje skonfigurowane strategie odporności.
Chociaż jest to prosty przykład, pokazuje, jak strategie odporności mogą służyć do obsługi błędów przejściowych. Aby uzyskać więcej informacji, zobacz Dokumentacja usługi Polly: Strategie.
Znane problemy
W poniższych sekcjach opisano różne znane problemy.
Zgodność z pakietem Grpc.Net.ClientFactory
Jeśli używasz Grpc.Net.ClientFactory
wersji 2.63.0
lub starszej, włączenie standardowych mechanizmów odporności czy zabezpieczania dla klienta gRPC może spowodować wyjątek w czasie wykonywania. W szczególności rozważmy następujący przykład kodu:
services
.AddGrpcClient<Greeter.GreeterClient>()
.AddStandardResilienceHandler();
Powyższy kod powoduje następujący wyjątek:
System.InvalidOperationException: The ConfigureHttpClient method is not supported when creating gRPC clients. Unable to create client with name 'GreeterClient'.
Aby rozwiązać ten problem, zalecamy uaktualnienie do Grpc.Net.ClientFactory
wersji lub nowszej 2.64.0
.
Istnieje kontrola czasu budowania, która sprawdza, czy używasz wersji Grpc.Net.ClientFactory
2.63.0
lub starszej, i jeśli tak, generuje ostrzeżenie kompilacji. Ostrzeżenie można pominąć, ustawiając następującą właściwość w pliku projektu:
<PropertyGroup>
<SuppressCheckGrpcNetClientFactoryVersion>true</SuppressCheckGrpcNetClientFactoryVersion>
</PropertyGroup>
Zgodność z usługą .NET Application Insights
Jeśli używasz usługi .NET Application Insights w wersji 2.22.0 lub starszej , włączenie funkcji odporności w aplikacji może spowodować brak wszystkich danych telemetrycznych usługi Application Insights. Problem występuje, gdy funkcje odporności są rejestrowane przed usługami Application Insights. Rozważmy następujący przykład powodujący problem:
// At first, we register resilience functionality.
services.AddHttpClient().AddStandardResilienceHandler();
// And then we register Application Insights. As a result, Application Insights doesn't work.
services.AddApplicationInsightsTelemetry();
Problem można rozwiązać, aktualizując usługę .NET Application Insights do wersji 2.23.0 lub nowszej. Jeśli nie możesz go zaktualizować, zarejestrowanie usług Application Insights przed funkcjonalnością odpornościową, jak pokazano poniżej, rozwiąże problem.
// We register Application Insights first, and now it will be working correctly.
services.AddApplicationInsightsTelemetry();
services.AddHttpClient().AddStandardResilienceHandler();