Makale Özeti

Daha önceki makalelerimde sizlere AppFabric Cache’in ne olduğunu, nasıl bir mimariye sahip olduğunu anlatmış. Bu makalemde ise sizlere PowerShell üzerinden yönetim modüllerine sahip olan AppFabric Cache'in C# üzerinden öncelikle nasıl PowerShell’e ulaşabileceğinizi, ardından da nasıl AppFabric Cache yönetim komutlarını kullanabileceğinizi anlatacağım.

Makale

Daha önceki makalelerimde sizlerle AppFabric Cache'i ve AppFabric Cache mimarisini anlatmıştım. Bu makalemde sizlere öncelikle C# üzerinden nasıl PowerShell’e ulaşabileceğinizi, ardından da nasıl PowerShell AppFabric Cache yönetim komutlarını kullanabileceğinizi anlatacağım.

C# üzerinden PowerShell komutları çalıştırabilmek için öncelikle System.Management.Automation kütüphanesine referans vermeniz gerekli. Bu kütüphaneyi aşağıdaki klasör altında bulabilirsiniz;

C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0 (x32)
C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0 (x64)

Eğer bilgisayarınızda bu klasörü bulamıyorsanız yapmanız gereken ilk şey PowerShell 2.0 SDK’sını kurmak olmalı; çünkü makalemin devamında bu SDK içerisindeki assembly'lere referans vermeniz gerekecek.

Referansını ekledikten sonra AppFabric Cache komutlarını çalıştırabileceğimiz bir PowerShell çalışma alanı oluşturmalıyız. Aşağıda bir PowerShell çalışma alanı oluşturma kodunu bulabilirsiniz;

  1. var initialSessionState = InitialSessionState.CreateDefault();
  2. initialSessionState.ThrowOnRunspaceOpenError = true;
  3. var cacheRunspace = RunspaceFactory.CreateRunspace(initialSessionState);
  4. cacheRunspace.Open();

Not: Yukarıdaki kodun derlenebilmesi için System.Management.Automation.Runspaces isim uzayı için using eklemelisiniz.

Bu kod ile oluşturduğunuz çalışma alını üzerinden bir pipeline oluşturarak bu pipeline içerisinde PowerShell komutlarını çalıştırabilirsiniz;

  1. var pipe = cacheRunspace.CreatePipeline();
  2. pipe.Commands.Add("[bir PowerShell komutu]");
  3.  
  4. var sonuc = pipe.Invoke();

PipeLine içerisine vereceğiniz PowerShell komutu yeni bir cache oluşturma olabileceği gibi (New-Cache), Önbellek kümesini yeniden başlatmakta olabilir (Restart-CacheCluster).

Konu hakkında daha fazla ilerlemeden önce, aynı PowerShell komut satırından yaptığımız gibi, ihtiyacımız olan AppFabric Cache PowerShell modüllerini yüklememiz gerektiğini de belirtmeliyim. Aksi halde, yazacağımız komutlar PowerShell tarafından tanınmayacağı için hata mesajı alacağız. AppFabric modüllerini PowerShell çalışma alanına eklemenin en kolay yolu SessionState'i bu çalışma alanına eklenmeden hemen önce hazırladığımız SessionState içerisine ImportPSModule fonksiyonunu kullanarak yüklemek;

  1. initialSessionState.ImportPSModule(new[] { "DistributedCacheAdministration", "DistributedCacheConfiguration" });

Her ne kadar yukarıdaki örnekte her iki AppFabric Cache modülü yüklenmiş de olsa; iş mantığınız gereği kullanacağınız AppFabric Cache komutları bunlarda sadece birine ihtiyaç duyabilir. Bu durumda sadece gerekli olan modülü yüklemeniz ihtiyacınızı karşılayacaktır.

Bu noktada önemli bir not düşmek isterim; eğer işletim sisteminiz x64 ise yukarıdaki kodu çalıştırdığınızda aşağıdaki hata ile karşılaşabilirsiniz;

One or more errors occurred processing the module 'DistributedCacheAdministration' specified in the InitialSessionState object used to create this runspace. See the ErrorRecords property for a complete list of errors. The first error was: The specified module 'DistributedCacheAdministration' was not loaded because no valid module file was found in any module directory.

Bu hatanın sebebi yazdığınız uygulamayı x64 bir makine üzerinde x32 olarak derlemiş olmanızdır. Özellikle Visual Studio 2010 kullanıyorsanız bu nokta gözünüzden kaçabilir. x32 olarak derlenerek çalışan uygulamanız içerisinde başlattığınız PowerShell oturumu DistributedCacheAdministration modülünü bulamayacaktır. Problemin çözmek için uygulamanızı configuration manager penceresinden “Any CPU” ya da “x64” seçerek derlemeniz gerekli.

Bu ufak nottan sonra konumuza devam edilim. Eğer AppFabric Cache Yönetimi ile ilgili bir/birkaç komut çalıştırmayı planlıyorsanız aynı PowerShell komut satırında yapmanız gerektiği gibi ilk çalıştırmanız gereken komut “Use-CacheCluster” olmalı. Eğer kodun çalıştığı bilgisayar bir önbellek kümesine dahil değilse ya da farklı bir önbellek kümesi için komut çalıştırmak istiyorsanız bu durumda “Use-CacheCluster” komutuyla birlikte bu önbellek kümesinin bağlantı bilgilerini de vermeniz gereklidir.

Oluşturduğumuz pipeline içerine birden fazla komut eklememiz durumda bu komutlar PowerShell içerisinde eklenme sırasına göre işletilecektir.

C# içerisinde AppFabric Cache PowerShell komutlarını çalıştırmaya en güzel örnek bir önbelleğin istemcilerce kullanılmaya başlanması öncesinde hazırlanması olacaktır. Bu durumda yeni önbellek oluşturulması sonrası bu önbelleğin doldurulması gereklidir;

  1. var newCacheKomutu = new Command("New-Cache");
  2. newCacheKomutu.Parameters.Add("CacheName", "test");
  3. pipe.Commands.Add(newCacheKomutu);

Yukarıdaki örnekte New-Cache komutu sadece zorunlu olan CacheName parametresi verilerek çağırılmıştır. PowerShell komutlarınca kullanılacak parametreler Command nesnesinin Parameters özelliği üzerinden belirtilir. Parametreler eklenirken parametre adı ve değeri ikilisi birlikte verilir. Bu örnekteki komutun işletilmesi sonucunda küme içerisinde test adıyla yeni bir önbellek oluşturulacaktır. Bu basit örnekten yola çıkarak sizde C# üzerinden kendi önbelleklerinizi programsal olarak oluşturabilirsiniz. New-Cache komutuna verebileceğiniz diğer parametreleri ise PowerShell oturumda “Get-Help New-Cache” komutuyla göreceğiniz yardım ekranında bulabilirsiniz. Bu komut hakkında daha detaylı yardım almak için “Get-Help New-Cache –full” komutunu da kullanabilirsiniz.

Şimdiye kadar anlattıklarımı bir araya topladığımızda karşımıza aşağıdaki kod parçacığı çıkacaktır;

  1. var initialSessionState = InitialSessionState.CreateDefault();
  2. initialSessionState.ImportPSModule(new[] { "DistributedCacheAdministration" });
  3. initialSessionState.ThrowOnRunspaceOpenError = true;
  4.  
  5. var cacheRunspace = RunspaceFactory.CreateRunspace(initialSessionState);
  6.  
  7. cacheRunspace.Open();
  8.  
  9. var pipe = cacheRunspace.CreatePipeline();
  10.  
  11. pipe.Commands.Add("Use-CacheCluster");
  12.  
  13. var newCacheKomutu = new Command("New-Cache");
  14. newCacheKomutu.Parameters.Add("CacheName", "test");
  15. pipe.Commands.Add(newCacheKomutu);
  16.  
  17. var sonuc = pipe.Invoke();

PowerShell içerisinden kullanabileceğiniz komutları aşağıdaki komutlar vasıtasıyla listeleyebilirsiniz;

Get-Command -module DistributedCacheAdministration
Get-Command -module DistributedCacheConfiguration

CommandList-DistributedCacheAdministration

Geldiğimiz noktada C#'la PowerShell komutlarımızın çalışacağı bir çalışma alanı içerisinde bir pipeline oluşturmuş ve son satırda bu pipeline’ı çalıştırmıştık. Bu örnekte dikkat edecek olursanız sonuc değişkeni içerisinde System.Management.Automation.PSObject barındıran 0 elemanlı bir koleksiyon bulunmamakta; çünkü pipeline içerisinde çalıştırdığımız AppFabric Cache komutlarının bir geri dönüş değeri bulunmamakta.

Oluşturduğumuz kodu ilk çalıştırmanız sonrasında alınan aşağıdaki ekran görüntüsünde PowerShell oturumunda, DistributedCacheAdministration modülünün yüklendiğini ve bilgisayarın bağlı olduğu önbellek kümesinin kullanıldığını, ardından da bu önbellek kümesinde bulunan önbelleklerin listesinin alındığını göreceksiniz.

Get-Cache

Görüldüğü gibi test adıyla bir önbellek oluşturulmuş durumda.

Aynı kodu ikinci defa çalıştıracak olursanız, verdiğiniz isimde bir önbelleğin küme içerisinde daha önceden oluşturulmuş olduğuna dair “ErrorCode<ERRCAdmin011>:SubStatus<ES0001>:Specified Cache is already present in cluster.” şeklinde bir hata mesajı alırsınız. Canlı sistemlerde olmasını istemediğimiz bu durumdan kaçınmak için öncelikle küme içerisindeki önbellekleri listeyip içlerinde oluşturmak istediğimiz önbelleğin olup olmadığına bakmalıyız, eğer yoksa yeni bir önbellek oluşturmalıyız. AppFabric Cache PowerShell modülü bize küme içerisinde bulunan tüm önbellekleri listelemek için bir komut sunmakta; Get-Cache :

  1. pipe.Commands.Add("Get-Cache");
  2.  
  3. var sonuc = pipe.Invoke();

İlk kodumuzdaki diğer komutları çıkartarak sadece “Get-Cache” kullandığımız yukarıdaki örnek kod bize içerisinde sadece tek bir elemanı olan bir PSObject listesi verecektir. Quick Watch ile sonuc değişkenine bakacak olursak 0. indeksteki PSObject içerisinde CacheInfo türünden bir nesne barındırdığını görürüz. Bu nesneye PSObject içerisindeki BaseObject özelliğinden ulaşabiliriz.

Sonuc QuickWatch

Aşağıdaki kodla, gelen sonuçlar arasında test önbelleği olup olmadığını kontrol ederek bu bilgiyi daha sonra kullanmak üzere bir boolean içerisinde tutuyoruz.

  1. var testOnbellegiBulundu = false;
  2. foreach (var cacheInfoPSObject in sonuc)
  3. {
  4.     var cacheInfo = ((CacheInfo)cacheInfoPSObject.BaseObject);
  5.  
  6.     if (cacheInfo.CacheName == "test")
  7.     {
  8.         testOnbellegiBulundu = true;
  9.         break;
  10.     }
  11. }

devamında ise eğer test önbelleği yoksa ilk örneğimizdeki oluşturma kodunu çalıştırıyoruz;

  1. if (!testOnbellegiBulundu)
  2. {
  3.     pipe = cacheRunspace.CreatePipeline();
  4.  
  5.     var newCacheKomutu = new Command("New-Cache");
  6.     newCacheKomutu.Parameters.Add("CacheName", "test");
  7.     pipe.Commands.Add(newCacheKomutu);
  8.  
  9.     pipe.Invoke();
  10. }

AppFabric Cache PowerShell komutları ve bu komutları çalıştırdığımızda dönecek nesneleri Get-Help komutu yardımıyla öğrenebiliriz. Örneğin; Get-Cache komutu hakkında aşağıdaki şekilde bilgi alabilirsiniz;

Get-Help Get-Cache -full

Get-Help Get-Cache -full

Gelen yardım bilgilerinin sonunda komutun çıktısı hakkındaki bilgiler OUTPUTS başlığı altında verilmektedir.

Şimdiye kadar ki anlattıklarımı toparlayacak olursak, kodumuz aşağıdaki hale gelmiştir;

  1. var initialSessionState = InitialSessionState.CreateDefault();
  2. initialSessionState.ImportPSModule(new[] { "DistributedCacheAdministration" });
  3. initialSessionState.ThrowOnRunspaceOpenError = true;
  4.  
  5. var cacheRunspace = RunspaceFactory.CreateRunspace(initialSessionState);
  6.  
  7. cacheRunspace.Open();
  8.  
  9. var pipe = cacheRunspace.CreatePipeline();
  10.  
  11. pipe.Commands.Add("Use-CacheCluster");
  12.  
  13. pipe.Commands.Add("Get-Cache");
  14.  
  15. var sonuc = pipe.Invoke();
  16.  
  17. var testOnbellegiBulundu = false;
  18. foreach (var cacheInfoPSObject in sonuc)
  19. {
  20.     var cacheInfo = ((CacheInfo)cacheInfoPSObject.BaseObject);
  21.  
  22.     if (cacheInfo.CacheName == "test")
  23.     {
  24.         testOnbellegiBulundu = true;
  25.         break;
  26.     }
  27. }
  28.  
  29.  
  30. if (!testOnbellegiBulundu)
  31. {
  32.     pipe = cacheRunspace.CreatePipeline();
  33.  
  34.     var newCacheKomutu = new Command("New-Cache");
  35.     newCacheKomutu.Parameters.Add("CacheName", "test");
  36.     pipe.Commands.Add(newCacheKomutu);
  37.  
  38.     pipe.Invoke();
  39. }

Şimdiye kadar anlatılanlarla oluşturmak istediğimiz önbelleğin varlığı kontrol ettikten sonra yoksa oluşturmayı, çalıştırılan PowerShell komutlarının sonuçlarını cast ederek kullanmayı öğrendik; fakat bazı AppFabric Cache komutlarında malesef ki hayat biz yazılım geliştiriciler için o kadar kolay olmuyor.Bazı komutların sonuç sınıfları barındıkları assembly içerisinde internal olarak tanımlanmaları nedeniyle dışarıdan kullanılamayabilir. Get-CacheStatistics komutunu ele alalım;

Get-Help Get-CacheStatistics -full

Get-Help Get-CacheStatistics -full

Bu komut bize iki tür sonuç döndürebilir;

  1. Microsoft.Data.Caching.NamedCacheStats (gerçekte Microsoft.ApplicationServer.Caching.NamedCacheStats)
  2. Microsoft.Data.Caching.HostCacheStats (gerçekte Microsoft.ApplicationServer.Caching.HostCacheStats)

Fakat bunlar assembly dışından erişilemeyen sınıflar (internal class) olduğu için kodumuz içerisinde doğrudan kullanamayız. Peki bu durumda ne yapmalıyız?

Bu durumda PSObject.BaseObject NamedCacheStats ya da HostCacheStats sınıflarına dönüştürülemeyeceği için imdadımıza PSObject’in Properties özelliği yetişiyor. Properties yardımıyla PSObject’in barındırdığı sonuç nesnesinin özelliklerine erişilebilir.

  1. var psObject = sonuc[0];
  2.  
  3. var ItemCount = (long)psObject.Properties["ItemCount"].Value;
  4. var MissCount = (long)psObject.Properties["MissCount"].Value;
  5. var RegionCount = (long)psObject.Properties["RegionCount"].Value;
  6. var RequestCount = (long)psObject.Properties["RequestCount"].Value;
  7. var Size = (long)psObject.Properties["Size"].Value;

Bu makale ile sizlerle paylaştığım bilgilerin C# üzerinden AppFabric Cache'i nasıl yönetebileceğiniz konusunda yardımcı olduğunu umuyorum. Bu noktadan sonra ihtiyaçlarınız/iş mantığınız doğrultusunda gerekli komutları rahatlıkla C# üzerinden kullanabilirsiniz.

Fatih Boy

http://www.enterprisecoding.com
http://twitter.com/fatihboy