Uzak Verilere Erişme

Not

Bu e-Kitap 2017 baharında yayımlanmıştır ve o zamandan beri güncelleştirilmemiştir. Kitapta değerli kalan çok şey var, ancak bazı malzemeler güncelliğini yitirmiş.

Birçok modern web tabanlı çözüm, uzak istemci uygulamalarına işlevsellik sağlamak için web sunucuları tarafından barındırılan web hizmetlerinden yararlanır. Bir web hizmetinin kullanıma sunma işlemleri bir web API'sini oluşturur.

İstemci uygulamaları, API'nin kullanıma sunulan verilerin veya işlemlerin nasıl uygulandığını bilmeden web API'sini kullanabilmelidir. Bu, API'nin bir istemci uygulaması ve web hizmetinin hangi veri biçimlerini kullanması gerektiğini ve istemci uygulamaları ile web hizmeti arasında değiştirilen verilerin yapısını kabul etmelerini sağlayan ortak standartlara uymasını gerektirir.

Temsili Durum Aktarımına Giriş

Temsili Durum Aktarımı (REST), hipermedia tabanlı dağıtılmış sistemler oluşturmaya yönelik bir mimari stildir. REST modelinin birincil avantajlarından biri, açık standartlara dayalı olması ve modelin veya buna erişen istemci uygulamalarının belirli bir uygulamaya uygulanmasını bağlamamasıdır. Bu nedenle, Microsoft ASP.NET Core MVC kullanılarak bir REST web hizmeti uygulanabilir ve istemci uygulamaları HTTP istekleri oluşturabilen ve HTTP yanıtlarını ayrıştırabilen herhangi bir dil ve araç kümesi kullanılarak geliştirilebilir.

REST modeli, bir ağ üzerindeki nesneleri ve hizmetleri temsil etmek için kaynak olarak adlandırılan bir gezinti düzeni kullanır. REST uygulayan sistemler genellikle bu kaynaklara erişim istekleri iletmek için HTTP protokollerini kullanır. Bu tür sistemlerde, istemci uygulaması bir kaynağı tanımlayan bir URI biçiminde bir istek ve bu kaynakta gerçekleştirilecek işlemi gösteren bir HTTP yöntemi (GET, POST, PUT veya DELETE gibi) gönderir. HTTP isteğinin gövdesi, işlemi gerçekleştirmek için gereken tüm verileri içerir.

Not

REST durum bilgisi olmayan bir istek modeli tanımlar. Bu nedenle, HTTP istekleri bağımsız olmalıdır ve herhangi bir sırada gerçekleşebilir.

REST isteğinden gelen yanıt, standart HTTP durum kodlarını kullanır. Örneğin, geçerli veriler döndüren bir istek 200 (Tamam) HTTP yanıt kodunu içerirken, belirtilen bir kaynağı bulabilen veya silmeyen bir istek 404 (Bulunamadı) HTTP durum kodunu içeren bir yanıt döndürmelidir.

RESTful web API'si bir dizi bağlı kaynağı kullanıma sunar ve bir uygulamanın bu kaynakları işlemesini ve aralarında kolayca gezinmesini sağlayan temel işlemleri sağlar. Bu nedenle, tipik bir RESTful web API'sini oluşturan URI'ler kullanıma sunduğu verilere yönlendirilir ve http tarafından sağlanan olanakları kullanarak bu veriler üzerinde çalışır.

Http isteğine bir istemci uygulaması tarafından eklenen veriler ve web sunucusundan gelen karşılık gelen yanıt iletileri, medya türleri olarak bilinen çeşitli biçimlerde sunulabilir. İstemci uygulaması bir iletinin gövdesinde veri döndüren bir istek gönderdiğinde, isteğin üst bilgisinde Accept işleyebileceği medya türlerini belirtebilir. Web sunucusu bu medya türünü destekliyorsa, ileti gövdesindeki Content-Type verilerin biçimini belirten üst bilgiyi içeren bir yanıtla yanıtlayabilir. Ardından yanıt iletisini ayrıştırmak ve ileti gövdesindeki sonuçları uygun şekilde yorumlamak istemci uygulamasının sorumluluğundadır.

REST hakkında daha fazla bilgi için bkz . API tasarımı ve API uygulaması.

RESTful API'lerini kullanma

eShopOnContainers mobil uygulaması Model-View-ViewModel (MVVM) desenini kullanır ve desenin model öğeleri uygulamada kullanılan etki alanı varlıklarını temsil eder. eShopOnContainers'daki denetleyici ve depo sınıfları, bu model nesnelerinin çoğunu kabul eder ve döndürür. Bu nedenle, mobil uygulama ile kapsayıcılı mikro hizmetler arasında geçirilen tüm verileri tutan veri aktarım nesneleri (DTO' lar) olarak kullanılırlar. Bir web hizmetine veri geçirmek ve bu hizmetten veri almak için DTO'ları kullanmanın temel avantajı, tek bir uzaktan çağrıda daha fazla veri ileterek uygulamanın yapılması gereken uzak çağrı sayısını azaltabilmesidir.

Web İstekleri Yapma

eShopOnContainers mobil uygulaması HTTP üzerinden istekte bulunmak için sınıfını HttpClient kullanır ve JSON medya türü olarak kullanılır. Bu sınıf, zaman uyumsuz olarak HTTP istekleri göndermek ve tanımlanan bir URI kaynağından HTTP yanıtları almak için işlevsellik sağlar. sınıfı, HttpResponseMessage BIR HTTP isteği yapıldıktan sonra REST API'den alınan http yanıt iletisini temsil eder. Durum kodu, üst bilgiler ve herhangi bir gövde dahil olmak üzere yanıt hakkındaki bilgileri içerir. sınıfı, HttpContent VE gibi Content-Type Content-EncodingHTTP gövdesini ve içerik üst bilgilerini temsil eder. İçerik, verilerin biçimine bağlı olarak ve ReadAsByteArrayAsyncgibi ReadAsStringAsync yöntemlerden herhangi biri ReadAs kullanılarak okunabilir.

GET İsteği Oluşturma

CatalogService sınıfı, katalog mikro hizmetindeki veri alma işlemini yönetmek için kullanılır. sınıfındaki RegisterDependencies yönteminde ViewModelLocator sınıfı, CatalogService Autofac bağımlılık ekleme kapsayıcısı ile türüne ICatalogService karşı bir tür eşlemesi olarak kaydedilir. Ardından, sınıfın CatalogViewModel bir örneği oluşturulduğunda oluşturucu, Autofac'ın sınıf örneğini CatalogService döndürerek çözümlediği bir türü kabul ICatalogService eder. Bağımlılık ekleme hakkında daha fazla bilgi için bkz . Bağımlılık Eklemeye Giriş.

Şekil 10-1'de, katalog mikro hizmetindeki katalog verilerini okuyan sınıfların tarafından görüntülenmesine yönelik etkileşimi gösterilmektedir CatalogView.

Katalog mikro hizmetten veri alma

Şekil 10-1: Katalog mikro hizmetten veri alma

CatalogView öğesine gidildiğinde, sınıfındaki OnInitialize CatalogViewModel yöntemi çağrılır. Bu yöntem, aşağıdaki kod örneğinde gösterildiği gibi katalog mikro hizmetinden katalog verilerini alır:

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

Bu yöntem, Autofac tarafından içine CatalogViewModel eklenen örneğin yöntemini CatalogService çağırırGetCatalogAsync. Aşağıdaki kod örneği yöntemini gösterir 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.ToObservableCollection();            
}

Bu yöntem, isteğin gönderileceği kaynağı tanımlayan URI'yi oluşturur ve sonuçları 'a döndürmeden önce kaynakta GET HTTP yöntemini çağırmak için sınıfını CatalogViewModelkullanırRequestProvider. RequestProvider sınıfı, bir kaynağı tanımlayan bir URI biçiminde istek gönderen işlevsellik, bu kaynakta gerçekleştirilecek işlemi belirten bir HTTP yöntemi ve işlemi gerçekleştirmek için gereken verileri içeren bir gövde içerir. sınıfının içine nasıl RequestProvider eklendiği hakkında bilgi için bkz. Bağımlılık EklemeyeCatalogService class Giriş.

Aşağıdaki kod örneği, sınıfındaki GetAsync RequestProvider yöntemini gösterir:

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

    await HandleResponse(response);  
    string serialized = await response.Content.ReadAsStringAsync();  

    TResult result = await Task.Run(() =>   
        JsonConvert.DeserializeObject<TResult>(serialized, _serializerSettings));  

    return result;  
}

Bu yöntem, uygun üst bilgi kümesine sahip sınıfın HttpClient bir örneğini döndüren yöntemini çağırırCreateHttpClient. Ardından URI tarafından tanımlanan kaynağa zaman uyumsuz bir GET isteği gönderir ve yanıt örnekte HttpResponseMessage depolanır. Daha HandleResponse sonra yöntemi çağrılır ve yanıt başarılı bir HTTP durum kodu içermiyorsa bir özel durum oluşturur. Ardından yanıt dize olarak okunur, JSON'dan nesneye CatalogRoot dönüştürülür ve öğesine CatalogServicedöndürülür.

CreateHttpClient yöntemi aşağıdaki kod örneğinde gösterilmiştir:

private HttpClient CreateHttpClient(string token = "")  
{  
    var httpClient = new HttpClient();  
    httpClient.DefaultRequestHeaders.Accept.Add(  
        new MediaTypeWithQualityHeaderValue("application/json"));  

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

Bu yöntem sınıfın HttpClient yeni bir örneğini oluşturur ve örnek tarafından HttpClient yapılan isteklerin üst bilgisini olarak application/jsonayarlarAccept. Bu, herhangi bir yanıtın içeriğinin JSON kullanılarak biçimlendirilmeyi beklediğini gösterir. Ardından, bir erişim belirteci yöntemine CreateHttpClient bağımsız değişken olarak geçirildiyse, örneği tarafından HttpClient yapılan tüm isteklerin üst bilgisine Authorization eklenir ve dizesi Bearerön ekini alır. Yetkilendirme hakkında daha fazla bilgi için bkz . Yetkilendirme.

sınıfındaki GetAsync RequestProvider yöntemi çağırdığındaHttpClient.GetAsyncItems, aşağıdaki kod örneğinde CatalogController gösterilen Catalog.API projesindeki sınıfındaki yöntemi çağrılır:

[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);  
}

Bu yöntem, EntityFramework kullanarak SQL veritabanından katalog verilerini alır ve başarılı bir HTTP durum kodu ve JSON biçimli CatalogItem örnekler koleksiyonu içeren bir yanıt iletisi olarak döndürür.

POST İsteği Yapma

BasketService sınıfı, sepet mikro hizmetiyle veri alma ve güncelleştirme işlemini yönetmek için kullanılır. sınıfındaki RegisterDependencies yönteminde ViewModelLocator sınıfı, BasketService Autofac bağımlılık ekleme kapsayıcısı ile türüne IBasketService karşı bir tür eşlemesi olarak kaydedilir. Ardından, sınıfın BasketViewModel bir örneği oluşturulduğunda oluşturucu, Autofac'ın sınıf örneğini BasketService döndürerek çözümlediği bir türü kabul IBasketService eder. Bağımlılık ekleme hakkında daha fazla bilgi için bkz . Bağımlılık Eklemeye Giriş.

Şekil 10-2, tarafından BasketViewgörüntülenen sepet verilerini sepet mikro hizmeti için gönderen sınıfların etkileşimini gösterir.

Sepet mikro hizmete veri gönderme

Şekil 10-2: Sepet mikro hizmete veri gönderme

Alışveriş sepetine bir öğe eklendiğinde, sınıftaki ReCalculateTotalAsync BasketViewModel yöntemi çağrılır. Bu yöntem, aşağıdaki kod örneğinde gösterildiği gibi sepetteki öğelerin toplam değerini güncelleştirir ve sepet verilerini sepet mikro hizmete gönderir:

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

Bu yöntem, Autofac tarafından içine BasketViewModel eklenen örneğin yöntemini BasketService çağırırUpdateBasketAsync. Aşağıdaki yöntem yöntemini UpdateBasketAsync gösterir:

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;  
}

Bu yöntem, isteğin gönderileceği kaynağı tanımlayan URI'yi oluşturur ve sonuçları 'a döndürmeden önce kaynakta POST HTTP yöntemini çağırmak için sınıfını BasketViewModelkullanırRequestProvider. Kimlik doğrulama işlemi sırasında IdentityServer'dan alınan bir erişim belirtecinin sepet mikro hizmeti için istekleri yetkilendirmek için gerekli olduğunu unutmayın. Yetkilendirme hakkında daha fazla bilgi için bkz . Yetkilendirme.

Aşağıdaki kod örneği, sınıfındaki PostAsync yöntemlerden RequestProvider birini gösterir:

public async Task<TResult> PostAsync<TResult>(  
    string uri, TResult data, string token = "", string header = "")  
{  
    HttpClient httpClient = CreateHttpClient(token);  
    ...  
    var content = new StringContent(JsonConvert.SerializeObject(data));  
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");  
    HttpResponseMessage response = await httpClient.PostAsync(uri, content);  

    await HandleResponse(response);  
    string serialized = await response.Content.ReadAsStringAsync();  

    TResult result = await Task.Run(() =>  
        JsonConvert.DeserializeObject<TResult>(serialized, _serializerSettings));  

    return result;  
}

Bu yöntem, uygun üst bilgi kümesine sahip sınıfın HttpClient bir örneğini döndüren yöntemini çağırırCreateHttpClient. Ardından URI tarafından tanımlanan kaynağa zaman uyumsuz bir POST isteği gönderir; serileştirilmiş sepet verileri JSON biçiminde gönderilir ve yanıt örnekte depolanır HttpResponseMessage . Daha HandleResponse sonra yöntemi çağrılır ve yanıt başarılı bir HTTP durum kodu içermiyorsa bir özel durum oluşturur. Ardından yanıt dize olarak okunur, JSON'dan nesneye CustomerBasket dönüştürülür ve öğesine BasketServicedöndürülür. Yöntemi hakkında CreateHttpClient daha fazla bilgi için bkz . GET İsteği Oluşturma.

sınıfındaki PostAsync RequestProvider yöntemi çağırdığındaHttpClient.PostAsyncPost, Aşağıdaki kod örneğinde BasketController gösterilen Basket.API projesindeki sınıfındaki yöntemi çağrılır:

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

Bu yöntem, sepet verilerini Redis önbelleğinde kalıcı hale getirmek için sınıfının bir örneğini RedisBasketRepository kullanır ve bunu başarılı bir HTTP durum kodu ve JSON biçimli CustomerBasket bir örnek içeren bir yanıt iletisi olarak döndürür.

DELETE İsteği Yapma

Şekil 10-3,için sepet mikro hizmetindeki sepet verilerini silecek sınıfların etkileşimlerini CheckoutViewgösterir.

Sepet mikro hizmetten veri silme

Şekil 10-3: Sepet mikro hizmetten veri silme

Kullanıma alma işlemi çağrıldığında, CheckoutAsync sınıfındaki CheckoutViewModel yöntemi çağrılır. Bu yöntem, aşağıdaki kod örneğinde gösterildiği gibi alışveriş sepetini temizlemeden önce yeni bir sipariş oluşturur:

private async Task CheckoutAsync()  
{  
    ...  
    await _basketService.ClearBasketAsync(_shippingAddress.Id.ToString(), authToken);  
    ...  
}

Bu yöntem, Autofac tarafından içine CheckoutViewModel eklenen örneğin yöntemini BasketService çağırırClearBasketAsync. Aşağıdaki yöntem yöntemini ClearBasketAsync gösterir:

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

Bu yöntem, isteğin gönderileceği kaynağı tanımlayan URI'yi oluşturur ve kaynakta DELETE HTTP yöntemini çağırmak için sınıfını kullanır RequestProvider . Kimlik doğrulama işlemi sırasında IdentityServer'dan alınan bir erişim belirtecinin sepet mikro hizmeti için istekleri yetkilendirmek için gerekli olduğunu unutmayın. Yetkilendirme hakkında daha fazla bilgi için bkz . Yetkilendirme.

Aşağıdaki kod örneği, sınıfındaki DeleteAsync RequestProvider yöntemini gösterir:

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

Bu yöntem, uygun üst bilgi kümesine sahip sınıfın HttpClient bir örneğini döndüren yöntemini çağırırCreateHttpClient. Ardından URI tarafından tanımlanan kaynağa zaman uyumsuz bir DELETE isteği gönderir. Yöntemi hakkında CreateHttpClient daha fazla bilgi için bkz . GET İsteği Oluşturma.

sınıfındaki DeleteAsync RequestProvider yöntemi çağırdığındaHttpClient.DeleteAsyncDelete, Aşağıdaki kod örneğinde BasketController gösterilen Basket.API projesindeki sınıfındaki yöntemi çağrılır:

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

Bu yöntem, redis önbelleğinden sepet verilerini silmek için sınıfının bir örneğini RedisBasketRepository kullanır.

Verileri Önbelleğe Alma

Uygulamanın performansı, sık erişilen verileri uygulamaya yakın bir konumda bulunan hızlı depolama alanına önbelleğe alarak geliştirilebilir. Hızlı depolama, uygulamaya özgün kaynaktan daha yakın bir konumdaysa önbelleğe alma, veri alınırken yanıt sürelerini önemli ölçüde artırabilir.

Önbelleğe almanın en yaygın biçimi, bir uygulamanın önbelleğe başvurarak veri aldığı okuma önbelleğidir. Veriler önbellekte değilse veri deposundan alınarak önbelleğe eklenir. Uygulamalar, edilgen önbellek düzeniyle okuma önbelleği uygulayabilir. Bu düzen, öğenin şu anda önbellekte olup olmadığını belirler. Öğe önbellekte değilse, veri deposundan okunur ve önbelleğe eklenir. Daha fazla bilgi için bkz. Edilgen Önbellek düzeni.

İpucu

Sık okunan ve seyrek değişen verileri önbelleğe alın. Bu veriler, bir uygulama tarafından ilk kez alındığında isteğe bağlı olarak önbelleğe eklenebilir. Bu, uygulamanın verileri veri deposundan yalnızca bir kez getirmesi gerektiği ve sonraki erişimin önbelleği kullanılarak karşılanabileceği anlamına gelir.

eShopOnContainers başvuru uygulaması gibi dağıtılmış uygulamalar aşağıdaki önbelleklerden birini veya ikisini de sağlamalıdır:

  • Birden çok işlem veya makine tarafından erişilebilen paylaşılan önbellek.
  • Verilerin uygulamayı çalıştıran cihazda yerel olarak tutulduğu özel önbellek.

eShopOnContainers mobil uygulaması, verilerin uygulamanın bir örneğini çalıştıran cihazda yerel olarak tutulduğu özel bir önbellek kullanır. eShopOnContainers başvuru uygulaması tarafından kullanılan önbellek hakkında bilgi için bkz . .NET Microservices: Architecture for Containerized .NET Applications.

İpucu

Önbelleği, herhangi bir zamanda kaybolabilecek geçici bir veri deposu olarak düşünün. Verilerin hem özgün veri deposunda hem de önbellekte tutuldığından emin olun. Daha sonra önbellek kullanılamaz duruma gelirse veri kaybı olasılığı en aza indirilir.

Veri Süre Sonunu Yönetme

Önbelleğe alınan verilerin her zaman özgün verilerle tutarlı olmasını beklemek pratik değildir. Özgün veri deposundaki veriler önbelleğe alındıktan sonra değişebilir ve bu da önbelleğe alınan verilerin eski olmasına neden olabilir. Bu nedenle, uygulamalar önbellekteki verilerin mümkün olduğunca güncel olduğundan emin olmaya yardımcı olan, ancak önbellekteki veriler eskidiğinde ortaya çıkan durumları algılayıp işleyebilen bir strateji uygulamalıdır. Çoğu önbelleğe alma mekanizması, önbelleğin verilerin süresi dolacak şekilde yapılandırılmasını sağlar ve bu nedenle verilerin güncel olma süresini kısaltır.

İpucu

Önbelleği yapılandırırken varsayılan bir süre sonu ayarlayın. Birçok önbellek, verileri geçersiz kılıp belirli bir süre boyunca erişilmemesi durumunda önbellekten kaldıran süre sonu uygular. Ancak, süre sonu seçerken dikkatli olunmalıdır. Çok kısa yapılırsa verilerin süresi çok hızlı dolacak ve önbelleğe almanın avantajları azaltılacaktır. Çok uzun sürerse veriler eskime riski taşır. Bu nedenle, süre sonu süresi, verileri kullanan uygulamalar için erişim deseni ile eşleşmelidir.

Önbelleğe alınan verilerin süresi dolduğunda önbellekten kaldırılmalıdır ve uygulamanın verileri özgün veri deposundan alıp önbelleğe geri yerleştirmesi gerekir.

Verilerin bir süre boyunca çok uzun süre kalmasına izin verilirse önbellek dolabilir. Bu nedenle, çıkarma olarak bilinen bir işlemdeki bazı öğeleri kaldırmak için önbelleğe yeni öğe ekleme istekleri gerekebilir. Önbellek hizmeti genellikle verileri en son kullanılan temele göre çıkartır. Ancak, en son kullanılan ve ilk çıkanlar dahil olmak üzere başka çıkarma ilkeleri de vardır. Daha fazla bilgi için bkz . Önbelleğe Alma Kılavuzu.

Görüntüleri Önbelleğe Alma

eShopOnContainers mobil uygulaması, önbelleğe alınmaktan yararlanan uzak ürün görüntülerini tüketir. Bu görüntüler denetim ve CachedImage FFImageLoading kitaplığı tarafından sağlanan denetim tarafından Image görüntülenir.

Denetim, Xamarin.FormsImage indirilen görüntülerin önbelleğe alınmasını destekler. Önbelleğe alma varsayılan olarak etkindir ve görüntüyü 24 saat boyunca yerel olarak depolar. Ayrıca, süre sonu süresi özelliğiyle CacheValidity yapılandırılabilir. Daha fazla bilgi için bkz . İndirilen Görüntü Önbelleğe Alma.

FFImageLoading'in CachedImage denetimi, ek işlevleri etkinleştiren ek özellikler sağlayan denetimin yerini Xamarin.FormsImage alır. Bu işlevsellik arasında denetim, hata ve yükleme görüntüsü yer tutucularını desteklerken yapılandırılabilir önbelleğe alma sağlar. Aşağıdaki kod örneği, eShopOnContainers mobil uygulamasının CachedImage içindeki ProductTemplatedenetimi nasıl kullandığını gösterir. Bu, içindeki denetim CatalogViewtarafından ListView kullanılan veri şablonudur:

<ffimageloading:CachedImage
    Grid.Row="0"
    Source="{Binding PictureUri}"     
    Aspect="AspectFill">
    <ffimageloading:CachedImage.LoadingPlaceholder>
        <OnPlatform x:TypeArguments="ImageSource">
            <On Platform="iOS, Android" Value="default_campaign" />
            <On Platform="UWP" Value="Assets/default_campaign.png" />
        </OnPlatform>
    </ffimageloading:CachedImage.LoadingPlaceholder>
    <ffimageloading:CachedImage.ErrorPlaceholder>
        <OnPlatform x:TypeArguments="ImageSource">
            <On Platform="iOS, Android" Value="noimage" />
            <On Platform="UWP" Value="Assets/noimage.png" />
        </OnPlatform>
    </ffimageloading:CachedImage.ErrorPlaceholder>
</ffimageloading:CachedImage>

DenetimCachedImage, ve ErrorPlaceholder özelliklerini platforma özgü görüntülere ayarlarLoadingPlaceholder. LoadingPlaceholder özelliği tarafından Source belirtilen görüntü alınırken görüntülenecek görüntüyü belirtir ve ErrorPlaceholder özelliği özelliği tarafından Source belirtilen görüntüyü almaya çalışırken bir hata oluşursa görüntülenecek görüntüyü belirtir.

Adından CachedImage da anlaşılacağı gibi, denetim özelliğin değeri tarafından belirtilen süre boyunca uzak görüntüleri cihazda önbelleğe CacheDuration alır. Bu özellik değeri açıkça ayarlanmıyorsa, varsayılan değer olan 30 gün uygulanır.

Dayanıklılığı Artırma

Uzak hizmetler ve kaynaklarla iletişim kuran tüm uygulamaların geçici hatalara duyarlı olması gerekir. Geçici hatalar arasında hizmetlere anlık ağ bağlantısı kaybı, hizmetin geçici olarak kullanılamama durumu veya hizmet meşgul olduğunda ortaya çıkan zaman aşımları sayılabilir. Bu hatalar genellikle kendi kendine düzeltilir ve uygun bir gecikmeden sonra eylem yinelenirse başarılı olma olasılığı yüksektir.

Geçici hatalar, tüm öngörülebilir koşullar altında kapsamlı bir şekilde test edilmiş olsa bile, bir uygulamanın algılanan kalitesi üzerinde büyük bir etkiye sahip olabilir. Uzak hizmetlerle iletişim kuran bir uygulamanın güvenilir bir şekilde çalıştığından emin olmak için aşağıdakilerin tümünü yapabilmesi gerekir:

  • Oluşan hataları algılayın ve hataların geçici olup olmadığını belirleyin.
  • Hatanın geçici olma olasılığını belirlerse işlemi yeniden deneyin ve işlemin yeniden denendi sayısını takip edin.
  • Yeniden deneme sayısını, her deneme arasındaki gecikmeyi ve başarısız bir denemeden sonra gerçekleştirilecek eylemleri belirten uygun bir yeniden deneme stratejisi kullanın.

Bu geçici hata işleme, yeniden deneme desenini uygulayan kodda uzak hizmete erişmeye yönelik tüm girişimleri sarmalayarak elde edilebilir.

Yeniden Deneme Düzeni

Bir uygulama uzak bir hizmete istek göndermeye çalıştığında bir hata algılarsa, aşağıdaki yollardan herhangi biriyle hatayı işleyebilir:

  • İşlemi yeniden deneyin. Uygulama başarısız olan isteği hemen yeniden deneyebilir.
  • Gecikmeden sonra işlemi yeniden deneyin. Uygulama, isteği yeniden denemeden önce uygun bir süre beklemelidir.
  • İşlem iptal edildi. Uygulamanın işlemi iptal etmesi ve bir özel durum bildirmesi gerekir.

Yeniden deneme stratejisi, uygulamanın iş gereksinimlerine uyacak şekilde ayarlanmalıdır. Örneğin, yeniden deneme sayısını ve yeniden deneme aralığını denenen işlemle en iyi duruma getirmek önemlidir. İşlem bir kullanıcı etkileşiminin parçasıysa, yeniden deneme aralığı kısa olmalı ve kullanıcıların yanıt beklemesini önlemek için yalnızca birkaç yeniden deneme denenmelidir. İşlem, iş akışının iptal edilmesi veya yeniden başlatılmasının pahalı veya zaman alıcı olduğu uzun süre çalışan bir iş akışının parçasıysa, denemeler arasında daha uzun süre beklemek ve daha fazla kez yeniden denemek uygundur.

Not

Girişimler arasında en az gecikme ve çok sayıda yeniden deneme içeren agresif bir yeniden deneme stratejisi, kapasiteye yakın veya kapasitede çalışan uzak bir hizmeti düşürebilir. Ayrıca, böyle bir yeniden deneme stratejisi, sürekli olarak başarısız bir işlem gerçekleştirmeye çalışıyorsa uygulamanın yanıt hızını da etkileyebilir.

Bir istek birkaç yeniden denemeden sonra yine başarısız olursa, uygulamanın aynı kaynağa daha fazla istek gelmesini önlemek ve bir hata bildirmek daha iyidir. Ardından, belirli bir süre sonra uygulama başarılı olup olmadığını görmek için kaynağa bir veya daha fazla istekte bulunabilir. Daha fazla bilgi için bkz. Devre Kesici Düzeni.

İpucu

Hiçbir zaman sonsuz bir yeniden deneme mekanizması uygulamayın. Sonlu sayıda yeniden deneme kullanın veya hizmetin kurtarılması için Devre Kesici düzenini uygulayın.

eShopOnContainers mobil uygulaması şu anda RESTful web istekleri yaparken yeniden deneme desenini uygulamaz. Ancak, CachedImage FFImageLoading kitaplığı tarafından sağlanan denetim, görüntü yüklemeyi yeniden deneyerek geçici hata işlemeyi destekler. Görüntü yükleme başarısız olursa, daha fazla deneme yapılır. Deneme sayısı özelliği tarafından belirtilir ve özelliği tarafından RetryCount RetryDelay belirtilen bir gecikmeden sonra yeniden denemeler gerçekleşir. Bu özellik değerleri açıkça ayarlanmamışsa, varsayılan değerleri uygulanır: özellik için RetryCount 3 ve özellik için RetryDelay 250ms. Denetim hakkında CachedImage daha fazla bilgi için bkz . Görüntüleri Önbelleğe Alma.

eShopOnContainers başvuru uygulaması yeniden deneme desenini uygular. Yeniden deneme desenini sınıfıyla HttpClient birleştirme hakkında daha fazla bilgi için bkz . .NET Microservices: Architecture for Containerized .NET Applications.

Yeniden deneme düzeni hakkında daha fazla bilgi için bkz . Yeniden deneme düzeni.

Devre Kesici Düzeni

Bazı durumlarda, düzeltilmesi daha uzun sürmesi beklenen olaylar nedeniyle hatalar oluşabilir. Bu hatalar kısmi bağlantı kaybından hizmetin tam hatasına kadar değişebilir. Bu gibi durumlarda, bir uygulamanın başarılı olma olasılığı düşük bir işlemi yeniden denemesi ve bunun yerine işlemin başarısız olduğunu kabul etmesi ve bu hatayı uygun şekilde işlemesi gerekir.

Devre kesici düzeni, bir uygulamanın başarısız olma olasılığı olan bir işlemi tekrar tekrar yürütmeye çalışmasını engelleyebilir ve ayrıca uygulamanın hatanın çözülmüş olup olmadığını algılamasını sağlayabilir.

Not

Devre kesici düzeninin amacı yeniden deneme deseninden farklıdır. Yeniden deneme düzeni, bir uygulamanın başarılı olması beklentisi içinde bir işlemi yeniden denemesini sağlar. Devre kesici düzeni, bir uygulamanın başarısız olma olasılığı olan bir işlem gerçekleştirmesini engeller.

Devre kesici, başarısız olabilecek işlemler için ara sunucu gibi çalışır. Ara sunucu, gerçekleşen son hataların sayısını izlemeli ve işlemin devam etmesi için izin verilip verilmeyeceğine karar vermek veya hemen bir özel durum döndürmek için bu bilgileri kullanmalıdır.

eShopOnContainers mobil uygulaması şu anda devre kesici desenini uygulamaz. Ancak, eShopOnContainers yapar. Daha fazla bilgi için bkz . .NET Mikro Hizmetleri: Kapsayıcılı .NET Uygulamaları için Mimari.

İpucu

Yeniden deneme ve devre kesici desenlerini birleştirin. Bir uygulama, bir devre kesici aracılığıyla bir işlemi çağırmak için yeniden deneme desenini kullanarak yeniden deneme ve devre kesici desenlerini birleştirebilir. Öte yandan, yeniden deneme mantığının devre kesici tarafından döndürülen özel durumlara duyarlı olması ve devre kesici hatanın geçici olmadığını gösteriyorsa yeniden denemeyi bırakması gerekir.

Devre kesici deseni hakkında daha fazla bilgi için bkz . Devre Kesici düzeni.

Özet

Birçok modern web tabanlı çözüm, uzak istemci uygulamalarına işlevsellik sağlamak için web sunucuları tarafından barındırılan web hizmetlerinden yararlanır. Bir web hizmetinin kullanıma sunulan işlemleri bir web API'sini oluşturur ve istemci uygulamaları, API'nin kullanıma oluşturduğu verilerin veya işlemlerin nasıl uygulandığını bilmeden web API'sini kullanabilmelidir.

Uygulamanın performansı, sık erişilen verileri uygulamaya yakın bir konumda bulunan hızlı depolama alanına önbelleğe alarak geliştirilebilir. Uygulamalar, edilgen önbellek düzeniyle okuma önbelleği uygulayabilir. Bu düzen, öğenin şu anda önbellekte olup olmadığını belirler. Öğe önbellekte değilse, veri deposundan okunur ve önbelleğe eklenir.

Web API'leriyle iletişim kurarken uygulamaların geçici hatalara duyarlı olması gerekir. Geçici hatalar arasında hizmetlere anlık ağ bağlantısı kaybı, hizmetin geçici olarak kullanılamama durumu veya hizmet meşgul olduğunda ortaya çıkan zaman aşımları sayılabilir. Bu hatalar genellikle kendi kendine düzeltilir ve eylem uygun bir gecikmeden sonra tekrarlanırsa başarılı olma olasılığı yüksektir. Bu nedenle, uygulamalar geçici bir hata işleme mekanizması uygulayan kodda bir web API'sine erişmeye yönelik tüm girişimleri sarmalamalıdır.