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-Encoding
HTTP gövdesini ve içerik üst bilgilerini temsil eder. İçerik, verilerin biçimine bağlı olarak ve ReadAsByteArrayAsync
gibi 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
.
Ş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ı CatalogViewModel
kullanı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 CatalogService
dö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/json
ayarlarAccept
. 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.GetAsync
Items
, 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 BasketView
görüntülenen sepet verilerini sepet mikro hizmeti için gönderen sınıfların etkileşimini gösterir.
Ş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ı BasketViewModel
kullanı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 BasketService
dö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.PostAsync
Post
, 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 CheckoutView
gösterir.
Ş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.DeleteAsync
Delete
, 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 ProductTemplate
denetimi nasıl kullandığını gösterir. Bu, içindeki denetim CatalogView
tarafı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.