Поделиться через


Доступ к удаленным данным

Совет

Это содержимое является фрагментом из электронной книги, шаблонов корпоративных приложений с помощью .NET MAUI, доступных в .NET Docs или в виде бесплатного скачиваемого PDF-файла, который можно прочитать в автономном режиме.

Корпоративные шаблоны приложений с помощью эскиза обложки электронной книги .NET MAUI .

Многие современные веб-решения используют веб-службы, размещенные на веб-серверах, для обеспечения функциональности удаленных клиентских приложений. Предоставляемые веб-службой операции составляют веб-API.

Клиентские приложения должны использовать веб-API, не зная, как реализуются данные или операции, предоставляемые API. Это требует, чтобы API соблюдался общими стандартами, которые позволяют клиентскому приложению и веб-службе согласиться с форматами данных, используемыми, и структурой данных, которые обмениваются между клиентскими приложениями и веб-службой.

Общие сведения о передаче состояния представления

Передача репрезентативного состояния (REST) — это архитектурный стиль для создания распределенных систем на основе гипермедии. Основное преимущество модели REST заключается в том, что она основана на открытых стандартах и не привязывает реализацию модели или клиентских приложений, которые обращаются к ней к какой-либо конкретной реализации. Таким образом, веб-служба REST может быть реализована с помощью Microsoft ASP.NET Core, а клиентские приложения могут разрабатываться с помощью любого языка и набора инструментов, который может создавать HTTP-запросы и анализировать HTTP-ответы.

Модель REST использует схему навигации для представления объектов и служб по сети, называемых ресурсами. Системы, реализующие REST, обычно используют протокол HTTP для передачи запросов для доступа к этим ресурсам. В таких системах клиентское приложение отправляет запрос в виде URI, определяющего ресурс, и метод HTTP (например, GET, POST, PUT или DELETE), указывающий на операцию, выполняемую в этом ресурсе. Текст HTTP-запроса содержит все данные, необходимые для выполнения операции.

Примечание.

REST определяет модель запроса без отслеживания состояния. Поэтому HTTP-запросы должны быть независимыми и могут выполняться в любом порядке.

Ответ от запроса REST использует стандартные коды состояния HTTP. Например, запрос, возвращающий допустимые данные, должен включать код HTTP-ответа 200 (OK), а запрос, который не сможет найти или удалить указанный ресурс, должен возвращать ответ, содержащий код состояния HTTP 404 (Not Found).

Веб-API RESTful предоставляет набор подключенных ресурсов и предоставляет основные операции, позволяющие приложению управлять этими ресурсами и легко перемещаться между ними. По этой причине URI, составляющие типичный веб-API RESTful, ориентированы на данные, предоставляемые им, и используют средства, предоставляемые HTTP для работы с данными.

Данные, включенные клиентским приложением в HTTP-запросе, и соответствующие сообщения ответа от веб-сервера, могут быть представлены в различных форматах, известных как типы носителей. Когда клиентское приложение отправляет запрос, возвращающий данные в тексте сообщения, он может указать типы носителей, которые он может обрабатывать в заголовке Accept запроса. Если веб-сервер поддерживает этот тип мультимедиа, он может ответить с ответом, который включает заголовок Content-Type, указывающий формат данных в тексте сообщения. Затем это ответственность клиентского приложения, чтобы проанализировать ответное сообщение и интерпретировать результаты в тексте сообщения соответствующим образом.

Дополнительные сведения о REST см. в статье о разработке API и реализации API на Документация Майкрософт.

Использование API RESTful

Приложение eShop с несколькими платформами использует шаблон Model-View-ViewModel (MVVM), а элементы модели шаблона представляют сущности домена, используемые в приложении. Классы контроллера и репозитория в справочном приложении eShop принимают и возвращают многие из этих объектов модели. Поэтому они используются в качестве объектов передачи данных (DTO), которые содержат все данные, передаваемые между приложением и контейнерными микрослужбами. Основное преимущество использования DTOs для передачи данных и получения данных из веб-службы заключается в том, что путем передачи дополнительных данных в одном удаленном вызове приложение может уменьшить количество удаленных вызовов, которые необходимо сделать.

Создание веб-запросов

Приложение eShop с несколькими платформами использует HttpClient класс для выполнения запросов по протоколу HTTP с использованием JSON в качестве типа носителя. Этот класс предоставляет функциональные возможности для асинхронной отправки HTTP-запросов и получения HTTP-ответов из определяемого ресурса URI. Класс HttpResponseMessage представляет сообщение HTTP-ответа, полученное от REST API после выполнения HTTP-запроса. Он содержит сведения об ответе, включая код состояния, заголовков и любой текст. Класс HttpContent представляет заголовки текста HTTP и содержимого, такие как Content-Type и Content-Encoding. Содержимое можно считывать с помощью любого из ReadAs методов, таких как ReadAsStringAsync и ReadAsByteArrayAsyncв зависимости от формата данных.

Выполнение запроса GET

Класс CatalogService используется для управления процессом извлечения данных из микрослужбы каталога. В методе RegisterViewModels MauiProgram в классе CatalogService класс регистрируется как сопоставление типов с ICatalogService типом с контейнером внедрения зависимостей. Затем при создании экземпляра CatalogViewModel класса его конструктор принимает объект ICatalogService type, который разрешается контейнером внедрения зависимостей, возвращая экземпляр CatalogService класса. Дополнительные сведения о внедрении зависимостей см. в разделе "Внедрение зависимостей".

На рисунке ниже показано взаимодействие классов, которые считывают данные каталога из микрослужбы каталога для отображения в CatalogView.

Получение данных из микрослужбы каталога.

CatalogView При переходе OnInitialize метод в классе CatalogViewModel вызывается. Этот метод извлекает данные каталога из микрослужбы каталога, как показано в следующем примере кода:

public override async Task InitializeAsync()
{
    Products = await _productsService.GetCatalogAsync();
} 

Этот метод вызывает GetCatalogAsync метод экземпляра CatalogService , внедренного в CatalogViewModel контейнер внедрения зависимостей. Метод GetCatalogAsync показан в следующем примере кода:

public async Task<ObservableCollection<CatalogItem>> GetCatalogAsync()
{
    UriBuilder builder = new UriBuilder(GlobalSetting.Instance.CatalogEndpoint);
    builder.Path = "api/v1/catalog/items";
    string uri = builder.ToString();

    CatalogRoot? catalog = await _requestProvider.GetAsync<CatalogRoot>(uri);

    return catalog?.Data;          
} 

Этот метод создает URI, определяющий ресурс, в который будет отправлен запрос, и использует RequestProvider класс для вызова метода GET HTTP в ресурсе, прежде чем возвращать результаты в CatalogViewModelресурс. Класс RequestProvider содержит функциональные возможности, которые отправляет запрос в виде URI, который определяет ресурс, метод HTTP, указывающий операцию, выполняемую на этом ресурсе, и текст, содержащий все данные, необходимые для выполнения операции. Сведения о RequestProvider внедрении класса в класс см. в CatalogService разделе "Внедрение зависимостей".

В следующем примере кода показан GetAsync метод в RequestProvider классе:

public async Task<TResult> GetAsync<TResult>(string uri, string token = "")
{
    HttpClient httpClient = GetOrCreateHttpClient(token);
    HttpResponseMessage response = await httpClient.GetAsync(uri);

    await HandleResponse(response);
    TResult result = await response.Content.ReadFromJsonAsync<TResult>();

    return result;
}

Этот метод вызывает GetOrCreateHttpClient метод, который возвращает экземпляр HttpClient класса с соответствующим набором заголовков. Затем он отправляет асинхронный GET запрос в ресурс, определенный URI, с ответом, хранящимся в экземпляре HttpResponseMessage . Затем HandleResponse вызывается метод, который вызывает исключение, если ответ не содержит код состояния HTTP успешного выполнения. Затем ответ считывается как строка, преобразуется из JSON в CatalogRoot объект и возвращается в объект CatalogService.

Метод GetOrCreateHttpClient показан в следующем примере кода:

private readonly Lazy<HttpClient> _httpClient =
    new Lazy<HttpClient>(
        () =>
        {
            var httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            return httpClient;
        },
        LazyThreadSafetyMode.ExecutionAndPublication);

private HttpClient GetOrCreateHttpClient(string token = "")
    {
        var httpClient = _httpClient.Value;

        if (!string.IsNullOrEmpty(token))
        {
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        }
        else
        {
            httpClient.DefaultRequestHeaders.Authorization = null;
        }

        return httpClient;
    }

Этот метод использует создание нового экземпляра или получение кэшированного экземпляра HttpClient класса и задает заголовок Accept всех запросов, сделанных HttpClient экземпляром application/json, что означает, что содержимое любого ответа будет отформатировано с помощью JSON. Затем, если маркер доступа был передан в качестве аргумента GetOrCreateHttpClient методу, он добавляется в Authorization заголовок всех запросов, сделанных HttpClient экземпляром, префиксом строки Bearer. Дополнительные сведения об авторизации см. в разделе "Авторизация".

Совет

Настоятельно рекомендуется кэшировать и повторно использовать экземпляры HttpClient для повышения производительности приложения. Создание нового HttpClient для каждой операции может привести к проблеме с исчерпанием сокета. Дополнительные сведения см. в статье HttpClient Instancing в Центре разработчиков Майкрософт.

GetAsync При вызове Items HttpClient.GetAsyncметода в классе вызывается метод в RequestProvider CatalogController классе в Catalog.API проекте, который показан в следующем примере кода:

[HttpGet]
[Route("[action]")]
public async Task<IActionResult> Items(
    [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0)
{
    var totalItems = await _catalogContext.CatalogItems
        .LongCountAsync();

    var itemsOnPage = await _catalogContext.CatalogItems
        .OrderBy(c => c.Name)
        .Skip(pageSize * pageIndex)
        .Take(pageSize)
        .ToListAsync();

    itemsOnPage = ComposePicUri(itemsOnPage);
    var model = new PaginatedItemsViewModel<CatalogItem>(
        pageIndex, pageSize, totalItems, itemsOnPage);           

    return Ok(model);
}

Этот метод извлекает данные каталога из базы данных SQL с помощью EntityFramework и возвращает его как ответное сообщение, включающее код состояния HTTP, а также коллекцию отформатированных CatalogItem экземпляров JSON.

Выполнение запроса POST

Класс BasketService используется для управления процессом извлечения и обновления данных с помощью микрослужбы корзины. В методе RegisterAppServices MauiProgram в классе BasketService класс регистрируется как сопоставление типов с IBasketService типом с контейнером внедрения зависимостей. Затем, когда создается экземпляр BasketViewModel класса, его конструктор принимает IBasketService тип, который разрешается контейнером внедрения зависимостей, возвращая экземпляр BasketService класса. Дополнительные сведения о внедрении зависимостей см. в разделе "Внедрение зависимостей".

На рисунке ниже показано взаимодействие классов, которые отправляют данные корзины, отображаемые в КорзинеView, в микрослужбу корзины.

Отправка данных в микрослужбу корзины.

При добавлении элемента в корзину ReCalculateTotalAsync покупок вызывается метод в BasketViewModel классе. Этот метод обновляет общее значение элементов в корзине и отправляет данные корзины в микрослужбу корзины, как показано в следующем примере кода:

private async Task ReCalculateTotalAsync()
{
    // Omitted for brevity...

    await _basketService.UpdateBasketAsync(
        new CustomerBasket
        {
            BuyerId = userInfo.UserId, 
            Items = BasketItems.ToList()
        }, 
        authToken);
}

Этот метод вызывает UpdateBasketAsync метод экземпляра BasketService , внедренного в BasketViewModel контейнер внедрения зависимостей. В следующем методе UpdateBasketAsync показан метод:

public async Task<CustomerBasket> UpdateBasketAsync(
    CustomerBasket customerBasket, string token)
{
    UriBuilder builder = new UriBuilder(GlobalSetting.Instance.BasketEndpoint);
    string uri = builder.ToString();
    var result = await _requestProvider.PostAsync(uri, customerBasket, token);
    return result;
}

Этот метод создает URI, определяющий ресурс, в который будет отправлен запрос, и использует RequestProvider класс для вызова метода POST HTTP в ресурсе, прежде чем возвращать результаты в BasketViewModelресурс. Обратите внимание, что маркер доступа, полученный во IdentityServer время процесса проверки подлинности, необходим для авторизации запросов к микрослужбе корзины. Дополнительные сведения об авторизации см. в разделе "Авторизация".

В следующем примере кода показан один из PostAsync методов в RequestProvider классе:

public async Task<TResult> PostAsync<TResult>(
    string uri, TResult data, string token = "", string header = "")
{
    HttpClient httpClient = GetOrCreateHttpClient(token);

    var content = new StringContent(JsonSerializer.Serialize(data));
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    HttpResponseMessage response = await httpClient.PostAsync(uri, content);

    await HandleResponse(response);
    TResult result = await response.Content.ReadFromJsonAsync<TResult>();
    
    return result;
}

Этот метод вызывает GetOrCreateHttpClient метод, который возвращает экземпляр HttpClient класса с соответствующим набором заголовков. Затем он отправляет асинхронный запрос POST в ресурс, определенный URI, с сериализованными данными корзины, отправляемыми в формате JSON, и ответ, хранящийся в экземпляре HttpResponseMessage . Затем HandleResponse вызывается метод, который вызывает исключение, если ответ не содержит код состояния HTTP успешного выполнения. Затем ответ считывается как строка, преобразуется из JSON в CustomerBasket объект и возвращается в BasketService. Дополнительные сведения о методе GetOrCreateHttpClient см. в разделе "Создание запроса GET".

PostAsync При вызове Post HttpClient.PostAsyncметода в классе вызывается метод в RequestProvider BasketController классе в Basket.API проекте, который показан в следующем примере кода:

[HttpPost]
public async Task<IActionResult> Post([FromBody] CustomerBasket value)
{
    var basket = await _repository.UpdateBasketAsync(value);
    return Ok(basket);
} 

Этот метод использует экземпляр RedisBasketRepository класса для сохранения данных корзины в кэше Redis и возвращает его как ответное сообщение, включающее код состояния HTTP и отформатированный CustomerBasket экземпляр JSON.

Выполнение запроса DELETE

На рисунке ниже показаны взаимодействия классов, которые удаляют данные корзины из микрослужбы корзины.CheckoutView

Удаление данных из микрослужбы корзины.

При вызове CheckoutAsync процесса выхода вызывается метод в CheckoutViewModel классе. Этот метод создает новый заказ перед очисткой корзины покупок, как показано в следующем примере кода:

private async Task CheckoutAsync()
{
    // Omitted for brevity...

    await _basketService.ClearBasketAsync(
        _shippingAddress.Id.ToString(), authToken);
}

Этот метод вызывает ClearBasketAsync метод экземпляра BasketService , внедренного в CheckoutViewModel контейнер внедрения зависимостей. В следующем методе ClearBasketAsync показан метод:

public async Task ClearBasketAsync(string guidUser, string token)
{
    UriBuilder builder = new(GlobalSetting.Instance.BasketEndpoint);
    builder.Path = guidUser;
    string uri = builder.ToString();
    await _requestProvider.DeleteAsync(uri, token);
}

Этот метод создает URI, определяющий ресурс, в который будет отправлен запрос, и использует RequestProvider класс для вызова DELETE метода HTTP в ресурсе. Обратите внимание, что маркер доступа, полученный во IdentityServer время процесса проверки подлинности, необходим для авторизации запросов к микрослужбе корзины. Дополнительные сведения об авторизации см. в разделе "Авторизация".

В следующем примере кода показан DeleteAsync метод в RequestProvider классе:

public async Task DeleteAsync(string uri, string token = "")
{
    HttpClient httpClient = GetOrCreateHttpClient(token);
    await httpClient.DeleteAsync(uri);
}

Этот метод вызывает GetOrCreateHttpClient метод, который возвращает экземпляр HttpClient класса с соответствующим набором заголовков. Затем он отправляет асинхронный DELETE запрос в ресурс, определенный URI. Дополнительные сведения о методе GetOrCreateHttpClient см. в разделе "Создание запроса GET".

DeleteAsync При вызове Delete HttpClient.DeleteAsyncметода в классе вызывается метод в RequestProvider BasketController классе в Basket.API проекте, который показан в следующем примере кода:

[HttpDelete("{id}")]
public void Delete(string id) =>
    _repository.DeleteBasketAsync(id);

Этот метод использует экземпляр RedisBasketRepository класса для удаления данных корзины из кэша Redis.

Кэширование данных

Производительность приложения можно улучшить, кэширование часто доступных данных для быстрого хранения, расположенного рядом с приложением. Если быстрое хранилище расположено ближе к приложению, чем исходный источник, кэширование может значительно повысить время отклика при получении данных.

Наиболее распространенная форма кэширования — кэширование через чтение, где приложение извлекает данные, ссылаясь на кэш. Если данные находятся не в кэше, они извлекаются из хранилища данных и добавляются в кэш. Приложения могут реализовать кэширование с помощью шаблона кэширования в сторону кэша. Этот шаблон определяет, находится ли элемент в кэше. Если элемент не находится в кэше, он считывается из хранилища данных и добавляется в кэш. Дополнительные сведения см. в шаблоне кэширования в Документация Майкрософт.

Совет

Кэшируйте данные, которые часто считываются и изменяются редко.

Эти данные можно добавить в кэш по запросу при первом получении приложением. Это означает, что приложению необходимо получить данные только один раз из хранилища данных, а последующий доступ может быть удовлетворен с помощью кэша.

Распределенные приложения, такие как эталонное приложение eShop, должны предоставлять один или оба из следующих кэшей:

  • Общий кэш, к которому можно получить доступ с помощью нескольких процессов или компьютеров.
  • Частный кэш, где данные хранятся локально на устройстве под управлением приложения.

Приложение eShop с несколькими платформами использует частный кэш, где данные хранятся локально на устройстве, на котором выполняется экземпляр приложения.

Совет

Думайте о кэше как временном хранилище данных, которое может исчезнуть в любое время.

Убедитесь, что данные хранятся в исходном хранилище данных, а также в кэше. Вероятность потери данных будет сведена к минимуму, если кэш становится недоступным.

Управление истечением срока действия данных

Нецелесообразно ожидать, что кэшированные данные всегда будут согласованы с исходными данными. Данные в исходном хранилище данных могут измениться после его кэширования, что приведет к тому, что кэшированные данные становятся устаревшими. Поэтому приложения должны реализовать стратегию, которая помогает обеспечить актуальность данных в кэше, но также может обнаруживать и обрабатывать ситуации, возникающие при возникновении устаревших данных в кэше. Большинство механизмов кэширования позволяют настроить кэш для истечения срока действия данных и, следовательно, сократить период, для которого данные могут быть устаревшими.

Совет

Задайте время истечения срока действия по умолчанию при настройке кэша.

Многие кэши реализуют срок действия, который делает данные недействительными и удаляет их из кэша, если он недоступен в течение указанного периода. Однако при выборе срока действия необходимо учесть осторожность. Если это сделано слишком коротко, срок действия данных будет истекает слишком быстро, и преимущества кэширования будут сокращены. Если это слишком долго, данные рискуют стать устаревшими. Поэтому срок действия должен соответствовать шаблону доступа для приложений, использующих данные.

Когда срок действия кэшированных данных истекает, его следует удалить из кэша, а приложение должно получить данные из исходного хранилища данных и поместить его обратно в кэш.

Также возможно, что кэш может заполниться, если данные могут оставаться слишком долго. Таким образом, запросы на добавление новых элементов в кэш могут потребоваться для удаления некоторых элементов в процессе, известном как вытеснение. Службы кэширования обычно вытесняют данные по крайней мере недавно использованных. Однако существуют и другие политики вытеснения, в том числе недавно используемые и первый выход. Дополнительные сведения см. в руководстве по кэшированию по Документация Майкрософт.

Кэширование изображений

Приложение eShop с несколькими платформами использует удаленные образы продуктов, которые получают преимущества от кэширования. Эти изображения отображаются элементом управления Image. Элемент управления образами .NET MAUI поддерживает кэширование скачанных изображений, включаемых по умолчанию, и сохраняет образ локально в течение 24 часов. Кроме того, срок действия можно настроить с помощью свойства CacheValidity. Дополнительные сведения см. в разделе "Скачанный кэширование изображений" в Центре разработчиков Майкрософт.

Повышение устойчивости

Все приложения, взаимодействующие с удаленными службами и ресурсами, должны быть чувствительны к временным сбоям. Временные ошибки включают временную потерю сетевого подключения к службам, временную недоступность службы или время ожидания, возникающие при занятой службе. Эти ошибки часто самокорректируются, и если действие повторяется после подходящей задержки, скорее всего, будет выполнено успешно.

Временные ошибки могут оказать огромное влияние на предполагаемое качество приложения, даже если оно было тщательно проверено во всех обозримых обстоятельствах. Чтобы обеспечить надежную работу приложения, которое взаимодействует с удаленными службами, оно должно выполнять все указанные ниже действия.

  • Обнаружение сбоев при их возникновении и определение временных ошибок.
  • Повторите операцию, если она определяет, что ошибка, скорее всего, будет временной и следить за количеством повторных попыток операции.
  • Используйте соответствующую стратегию повторных попыток, которая указывает количество повторных попыток, задержку между каждой попыткой и действиями, которые необходимо предпринять после неудачной попытки.

Эта временная обработка ошибок может быть достигнута путем упаковки всех попыток доступа к удаленной службе в коде, реализующего шаблон повторных попыток.

Шаблон повтора

Если приложение обнаруживает сбой при попытке отправить запрос в удаленную службу, он может справиться с ошибкой любым из следующих способов:

  • Повторите операцию. Приложение может немедленно повторить неудачный запрос.
  • Повторите операцию после задержки. Приложение должно ожидать подходящего периода времени, прежде чем повторить запрос.
  • Отмена операции. Приложение должно отменить операцию и сообщить об исключении.

Стратегия повторных попыток должна быть настроена в соответствии с бизнес-требованиями приложения. Например, важно оптимизировать количество повторных попыток и интервал повторных попыток к попытке операции. Если операция является частью взаимодействия с пользователем, интервал повторных попыток должен быть коротким, и лишь несколько повторных попыток пытались избежать того, чтобы пользователи ждали ответа. Если операция является частью длительного рабочего процесса, при котором отмена или перезапуск рабочего процесса является дорогостоящим или временным, это позволяет ожидать больше времени между попытками и повторными попытками.

Примечание.

Агрессивная стратегия повторных попыток с минимальной задержкой между попытками и большим количеством повторных попыток может привести к снижению удаленной службы, которая выполняется близко к емкости или в емкости. Кроме того, такая стратегия повторных попыток также может повлиять на скорость реагирования приложения, если она постоянно пытается выполнить сбой операции.

Если запрос по-прежнему завершается ошибкой после ряда повторных попыток, лучше предотвратить дальнейшие запросы, поступающие к тому же ресурсу, и сообщить об ошибке. Затем после заданного периода приложение может выполнить один или несколько запросов к ресурсу, чтобы узнать, успешно ли они выполнены. Дополнительные сведения см. в разделе "Шаблон разбиения цепи".

Совет

Никогда не применяйте механизм с бесконечными повторными попытками. Вместо этого предпочитайте экспоненциальный откат.

Используйте ограниченное число повторных попыток или реализуйте шаблон разбиения цепи, чтобы разрешить службе восстановиться.

Эталонное приложение eShop реализует шаблон повторных попыток.

Дополнительные сведения о шаблоне повторных попыток см. в шаблоне повторных попыток на Документация Майкрософт.

Шаблон разбиения цепи

В некоторых ситуациях ошибки могут возникать из-за ожидаемых событий, которые требуют больше времени для устранения. Эти ошибки могут варьироваться от частичной потери подключения к полному сбою службы. В таких ситуациях это бессмысленно для приложения повторить операцию, которая вряд ли будет выполнена, и вместо этого следует принять, что операция завершилась ошибкой и обработать этот сбой соответствующим образом.

Шаблон разбиения цепи может предотвратить повторную попытку выполнения операции, которая, скорее всего, завершится ошибкой, а также позволяет приложению определить, была ли устранена ошибка.

Примечание.

Назначение шаблона автоматического останова отличается от шаблона повторных попыток. Шаблон повторных попыток позволяет приложению повторить операцию в ожидании успешного выполнения. Шаблон разбиения цепи запрещает приложению выполнять операцию, которая, скорее всего, завершится ошибкой.

Автоматическое выключение действует в качестве прокси-сервера операций, которые могут завершиться со сбоем. Прокси-сервер должен отслеживать количество недавних сбоев, которые произошли, и использовать эту информацию, чтобы решить, разрешать ли операция продолжаться, или немедленно возвращать исключение.

Приложение eShop с несколькими платформами в настоящее время не реализует шаблон разбиения цепи. Однако eShop делает.

Совет

Объедините шаблоны повторных попыток и разбиения цепи.

Приложение может объединить шаблоны повторных попыток и разбиения цепи с помощью шаблона повторных попыток для вызова операции через разбиение цепи. Однако логика повторения должна быть чувствительной к любым исключениям, возвращаемым автоматическим выключением, и отказываться от повторных попыток, если автоматическое выключение указывает, что неисправность не является временной.

Дополнительные сведения о шаблоне разбиения цепи см. в шаблоне разбиения цепи на Документация Майкрософт.

Итоги

Многие современные веб-решения используют веб-службы, размещенные на веб-серверах, для обеспечения функциональности удаленных клиентских приложений. Операции, предоставляемые веб-службой, представляют собой веб-API, и клиентские приложения должны иметь возможность использовать веб-API, не зная, как реализуются данные или операции, предоставляемые API.

Производительность приложения можно улучшить, кэширование часто доступных данных для быстрого хранения, расположенного рядом с приложением. Приложения могут реализовать кэширование с помощью шаблона кэширования в сторону кэша. Этот шаблон определяет, находится ли элемент в кэше. Если элемент не находится в кэше, он считывается из хранилища данных и добавляется в кэш.

При взаимодействии с веб-API приложения должны быть чувствительны к временным сбоям. Временные ошибки включают временную потерю сетевого подключения к службам, временную недоступность службы или время ожидания, возникающие при занятой службе. Эти ошибки часто самовосправляются, и если действие повторяется после подходящей задержки, то, скорее всего, это успешно. Поэтому приложения должны упаковать все попытки доступа к веб-API в коде, который реализует временный механизм обработки ошибок.