|
ASP.NET'de "Output Cache" Modeli |
|
Gönderiliyor lütfen bekleyin... |
|
|
Merhaba değerli C#nedir?com
okuyucuları; ASP NET sitelerinde performansı arttırmak için kullanılan en önemli
yapılardan biri olan Caching mekanizmasını anlatmaya çalışacağım. Caching’in Türkçesi
önbellekleme demektir ki adından da anlaşılacağı gibi sayfanızın bir kopyasının
önbellekte saklanması ve artık gelen isteklere de önbelleklenmiş sayfanın gösterilmesi
ve bu sayede ASP.NET sayfamızın yeniden derlenmemesi ve böylece artan performans.
Artık düşündüğümüzde 1000 lerce kişinin bağlandığı bir server da isteklere göre
sayfaların derlenmesi ve kullanıcılara gösterilmesinin oluşturacağı gecikmeyi
herhalde tahmin edebilirsiniz ama tabiî ki cachingin iyi yönleri olduğu gibi
kötü yönleride vardır, aslında kötü yönleri demeyelim de dezavantajları diyelim
ama ne güzeldir ki yine bu dezavantajları da caching için kullanacağımız kodlarda
bazı değişikler yaparak giderebiliriz.
Caching olayını eğer sınıflamak gerekirse ana başlık altında
2 sınıfta toplayabiliriz.
1- OutPut Caching (*Çıktı Önbellekleme)
2- Data Caching (*Veri Önbellekleme)
Ve bunların dışında ama yukarıdakiler ile alakalı alt başlık
olarakta koyabileceğimiz özelleşmiş cachingler ise Fragment Caching (*Parça
parça önbellekleme) ki bu OutPut Cachingin özelleşmiş bir halidir ve DataSource
Caching (*VeriKaynağı Önbellekleme) ki bu da Data Caching in özelleşmiş halidir.
Biz bu makalemizde Data Cacheing hariç diğer bütün yöntemlere göz atmaya çalıcağız.
OutPut Caching : Bu Cachleme sayesinde sayfamızın
son HTML halininin önbellekte bir kopyası oluşturulur ve gelen isteklere bu
sayfalar gönderilir ama unutmadan söyleyelim cache için bir yaşam süresi diyebileceğim
Duration alt özelliğini eklememiz gerekecektir. Bunun sayesinde cache mizin
ne kadar süre
önbellekte saklanacağını ayarlamış olacağız. Şimdi bu dediklerimizi bir örnekle
açaklamaya çalışalım.
İlk başta kendinize yeni bir ASP.NET projesi oluşturun. Aşağıdaki resimde olduğu
gibi sayfasınıza
<%@ OutputCache Duration="5" VaryByParam="None" %>
satırını ekleyin.
Bu kod satırını açıklamak gerekirse ;
*Duration : Sayfamızın önbellekte ne kadar saklanacağını belirttiğimiz
alt özelliktir.
* VaryByParam : Bu alt özellikiğin “None” yapılması demek,
Sayfamızın tamamının önbelleğe alınması demektir ki buna ileride daha detaylı
değineceğiz.
Şimdi sayfamıza
önbelleklemeyi somut bir şekilde görmek için Zaman ekleyelim. Bunu yapmak için
tek yapmanız gereken sayfamıza bir tane label eklemeniz ve şu kodları yazmanız;
public
partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object
sender, EventArgs e)
{
label1.Text
= DateTime.Now.ToLongTimeString();
}
}
|
Yukarıda bulunan
kodda sizinde göreceğiniz gibi Sayfa her Yüklendiğinde eğer önbellekleme yapılmamış
ise o anki saati gösterir ama şimdi sayfamızı derleyelim ve sayfamızı devamlı
Refresh yani yenileyelim , ne gördünüz? Tabiki saatin hiç değişmediğini, neden?
Nedeni ni söyleyelim ; Önbellekleme tabiki. Sayfamızı devamlı yenilerseniz 5
saniyede bir saatin saniyesinin değişeceğini göreceksiniz. Çünkü biz önbellekleme
süresini 5 saniye olarak ayarladık ve her 5 saniyede yeni bir cachimiz oluşturulur.
Bu olayın avantajları
:
*Sayfamız yeniden derlenmedi
*Kullanıcılara değişmeyen yani static sayfalar daha hızlı bir şekilde gösterilir
*Server gereksiz yere yorulmaz
(Static sayfalarda performans için mükemmel bir yöntem.)
Kısacası performans artışı…
Dezavantajlar ise
:
*Eğer sayfamız dinamik olsaydı ve dışarıdan QueryString ler ile farklı bilgiler
gelseydi !
İşte yukarıdaki
dezavantajtan sıyrılmanın yöntemi :
Yeniden bir proje
açın ve bu sefer iki tane asp.net sayfası ekleyin projenize. İsimleri Default.aspx
ve Default2.aspx olsun.Default2.aspx sayfasının Source kısmına şunu yazmayı
uutmayın : <%@ OutputCache Duration="10" VaryByParam="None"
%> Burada önbellekte kalma süresini 10 saniye yaptık. Şimdi Default.aspx
sayfamızın Kod kısmı olan Default.aspx.cs sayfasının Button_Click olayına aşağıdaki
kodları yazın ama bundan önce tabi sayfamıza bir tane TextBox ve bir tane de
Button Kontrolu koymayı unutmayın.
protected
void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("Default.aspx?giden="
+ TextBox1.Text);
}
|
Burada Default2.aspx
sayfamıza giden QueryStringi sayesinde TextBox1 den alınan veriyi gönderiyoruz
şimdi de Default.aspx sayfasına bir tane Label koyun ve Default2.aspx.cs sayfasına
ise şu kodları yazın ;
protected
void Page_Load(object sender, EventArgs e)
{
Label1.Text = Request.QueryString["giden"].ToString();
}
|
Burada ise gelen
verimizi Request ile aldırdıktan sonra Labelimiza yazdırıyoruz. Evet şimdi deneyin
bakalım ne olacak.Ben size söyleyeyim ilk gönderdiğiniz veri (TextBox a yazıp
buttona bastıktan sonra gönderilen veri yani) Default2.aspx sayfamızda görülecek
ama bunda sonra her göndereceğiniz veride yeni ilk gönderdiğiniz veri şeklinde
gözükecek.Yani Label kontrolmuzde hep aynı yazı gözükecek taki 10 sn geçene
kadar.İşte size Dezavantaj ?. İşte bundan şöyle sıyrılacağız : <%@ OutputCache
Duration="10" VaryByParam="*" %> kodumuzun VaryByParam
özelliğini “*” bu şekilde yapın ve bu sefer yeniden deneyin bakalım ne olacak
o zaman. İşte şimdi problem çözüldü. Artık her gelen yeni QueryStringe göre
bir cache oluşturulup kullanıcılara en taze hali gösterilir ama burada da çok
ama çok önemli bir durum söz konusu: Şimdi siz mesela “Ahmet” diye bir QueryString
gönderdiniz Default2.aspx sayfamıza ve doğal olarak ta label kontrolmuzda “Ahmet”
gözükecektir.İşte bu sayfanın serverda A kopyası olarak saklandığını düşünelim.Peki
başka bir kullanıcı ise “Mehmet” diye bir QueryString gönderdi o zaman Default2.aspx
sayfamda ise “Mehmet” olarak gözükecektir Label kontrolum ama önceki A kopyam
silindi mi peki? Cevap vereyim: Kocaman bir Hayır! A kopyam hala saklanmakta
ve bu sefer ise “Mehmet” olan B kopyam olarak saklanıyor.Eğer başka bir tane
daha farklı bir QueryString ile sayfama istekte bulunulursa bu sefer sayfam
C kopyası olarak saklanacaktır. Peki bunlar saklandı ama ne olacak bunlara.Eğer
bir kullanıcı sayfamı Ahmet QueryString ile çağırırsa o zaman ona A kopyası
gösterilecek ve sayfam yeniden derlenmecektir.Eğer başkası ise “Mehmet” QueryString
ile çağırırsa ona da B kopyası gönderilecektir ve bu sayede yine performans
artışı sağlanacaktır.Nasıl ama? ? Peki ben eğer iki tane QueryString gönderirsem
ama sayfamın sadece bir tane QueryStringim değiştiğinde cachleme yapmasını istiyorsam
o zaman ne yaparım.Düşünün bir UrunlerID ve HizmetID diye iki tane QueryStringim
var ve ben bunlardan sadece HizmetID değiştiğinde sayfamın serverda farklı bir
cachlenmiş halinin saklanmasını istiyorum.O zaman yapmam gereken sadece şu :
<%@ OutputCache Duration="10" VaryByParam="HizmetlerID"
%> İşte bu kadar. Artık istediğim gibi oldu.(Unutmadan! Bakın bu yöntemler
sadece QueryStringler için geçerlidir.Cookiler ve Sessionlar için geçerli yöntemler
değillerdir) Eğer ki ben birkaç tane QueryString e göre cachleme yapmak istiyorsam
o zaman ise Noktalı Virgül kullanmam yeterli olacaktır. Örneğin VaryByParam=”HizmetlerID;UrunlerID;SenID”
vs gibi.Gayet kolay değil mi?
Şimdi diğer özellikleri
inceleyelim (Bu makalede bunları yüzeysel geçeceğiz ama diğer makalelerde hepsine
teker teker inceleyeceğiz) :
*VaryByCustom
: Bu alt özellik ; kendi yazacağımız kodumuza göre Cahcleme yapabiliriz.Mesela
Browser farklılıklarına göre bile Önbellekme yapabiliriz.Bir düşünün Nescape
kullanan ve bir kullanıcı doğal olarak Nescape-Optimized sayfalara ulaşacaktır
aynı şekilde IE kullanan ise Explorer-Optimized sayfalar kullanmak ister.İşte
bu farklılık doğal olarak Cachlemeyede yansır. Aynı şekilde başta ta dediğimiz
gibi kendinize Procuderler yazarak (Code-Behind a yazabileceğiniz gibi Global.asax
dosyalarında yazabilirsiniz ) istediğiniz bir şeye göre cachleme yapabilirsiniz.Diğer
makalemizde kodların nasıl yazılacağını göstermeye çalışacağız ki bu özelliğin
kullanması ise özel bir kod yapısı kullanması gerekmektedir.
*DiskCacheable
: Bu alt özellik ise diskinizin önbellenebilir veya olmadığını ayarlamanızı
sağlar.Bool değer geriye dönderir.( True/False)
*VaryByHeader
: Bu alt özellik ise HTML başlığınızın değişimine göre Cachleme yapılmasını
sağlar.
*Location
: Bu ise Cachlemenmiş dosyaların nerede saklancağını göstermenizi sağlar.
*NoStore
: Depolama yapılıp yapılmayacağını belirtmenizi sağlar. (True/False)
*SqlDependency
: Bu alt özellik ise gerçekten en önemli özelliklerden biridir ve Sql bağımlılığını
gösterir. Şöyleki DataBase olarak Sql kullandığınız durumda eğer sayfanızı önbellekliyorsanız
ve eğer değişen verileriniz (Delete/Update vs gibi) varsa doğal olarak sayfanın
en güncel veriyi kullanıcılara göstermesi gerekecektir. Bu durumda bu özelliği
kullanarak eğer veritabanınızda bir değişiklik olmuş ise yeni bir cachin oluşturulması
sağlanır.
*VaryByControl : Bu ise istediğiniz kontrollere göre önbellekleme
yapılmasını sağlar.
Unutmadan söyleyelim
bu anlatılanları hepsi OuptPut Caching kapsamına girmektedir.
Fragment
Caching : Bazen sayfamızın her tarafını değilde bazı yerlerini
önbellekleme ihtiyacı duyarız ki bu bazen çok önemli bir ihtiyaçta olabilir.İşte
bu durumlarda kullanılacak olan Fragment Cachingtir.Bunu yapmak aslından çok
basittir ve User Controls kullanılmasını gerektirir. Eğer User Controls bilmiyorsanız
ilk başta onları incelemenizde yarar var. User Controls oluşturun ve bunu VaryByControl
özelliğine bağlayın ve bitti.Unutmadan söyleyelim eğer bu yapıyı kullancaksanız
Cachleme zamanı bitmeden Önbelleklediğiniz User Controllerinin (*Kullanıcı Kontroleri)
Eventler (*Olayları) çalışmaz.
İlk başta anlattığımız ama örnek vermediğimiz Fragment cahcing ile devam edelim.
Kısaca özetlemek gerekirse bu cachleme yöntemi parça parça cachleme olarakta
türkçe bir karşılık getirebiliriz. Bu yöntemde amaç sayfamızın belli bölümlerini
önbellekleme yapmak ve böylece istediğimiz doğrultuda performans artışına gitmektir.
Unutmadan söylemek gerekki burada ki ince nokta user controls ( kullanıcı kontrolleri
) kullanmak. Tabi ki bu yöntemi uygulama sırasından tek user controls kullanılacak
diye bir olay aynı şekilde subsitution kontrolunu kullanarak ta yapabiliriz.
Bu özetlerden sonra konumuza başlayalım. Önceki bölümlerde Directive bölümüne
cachleme işlemi yapmak için hangi directive leri yazdığımızı görmüştük şimdi
bunlardan yola çıkarak çok basit ve anlaşılır örnekler ile konumuzu inceleyelim.(Unutmadan
eğer user controls hakkında bilginiz yoksa bu makaleyi okumada önce ilk başta
user controls konusunu incelemenizi şiddetle tavsiye ederim.)
1.) İlk başta Toplama isimli bir user control ü projenize ekleyiniz ve aşağıdaki
tasarimi yapınız
2.) Bu tasarımı
yaptıktan sonra Kullanıcı Kontrolümüzde Source (kaynak) kısmına gelip şu direktivi
ekleyelim sayfamızın üst kısmına
<%@ OutputCache Duration="5" VaryByParam="None" %>
2.) Yukarıda dikkatinizi
çeken kısımlardan biri duration yani cache mizin kullanılma süresinini 5 saniye
yaptık.
3.) Şimdi bu oluşturduğumuz Kullanıcı Kontrolunün Toplama isimli tuşun olay
yordamına şunu yazın ;
protected
void btnToplama_Click(object sender, EventArgs e)
{
lblSonuc.Text = (Convert.ToInt16(txtSayi1.Text)
+ Convert.ToInt16(txtSayi2.Text)).ToString();
} |
Evet bunları yaptıktan
sonra artık iki sayıyı toplayan ve sonucunu bize veren bir kullanıcı kontolümüz
olmuş oldu. Şimdi ise yapmamı gereken olay bunu Default.aspx sayfamıza eklemek.
Ekledikten sonra cachlemeyi daha iyi farkedebilmek amacıyla Default.aspx sayfamıza
bır tane label ekleyin ve Page_Load olayına şu kodları yazın :
protected
void Page_Load(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToLongTimeString();
} |
Evet artık sistemimiz
çalışmaya hazırdır ve şimdi derleyiniz. Evet açılan sayfamızda bulunan Kullanıcı
Kontrolümüzde sayıları girip Toplama tuşuna basınız. Neler gördünüz ? Tabiki
herhangi bişey değişmedi ama Default.aspx sayfasına eklediğiniz Label baktığımzda
ise her sayfayı yenilemede değiştiğini göreceksiniz ve 5 saniye sonra ise Kullanıcı
Kontrolümüz değişir. Burada önemli noktalardan biri ise Cache in kullanımı sırasında
Kullanıcı Kontrolu için yazılan Code-Behind (Toplama.ascx.cs) deki kodun derlenmeyeceğidir.
İşte sizde Fragment önbelleklemenin ne kadar kolay olduğunu gördünüz.
Peki ben Default.aspx
sayfasına koyduğum Label1 kontrolunun içeriğinin Herhangi bir kontrole göre
değişmesini isteseydim yani, Default.aspx sayfamda yeni bir cache oluşturulmasını
tetikleyici etkenin benim belirlediğim kontrolümün olmasını isteseydim bunu
nasıl yapardım ? Bunun için tek yapmanız gereken olay şu :
Default.aspx sayfasına
bır tane örnek olması amacıyla DropDownList ekleyiniz. Ve EnableAutoPostBack
özelliğini true yaptıktan sonra 3-4 tane içine item ekleyiniz yada direk aşağıda
bulunan kodu Default.aspx sayfanızın Source kısmına ekleyiniz :
<asp:DropDownList
ID="DropDownList1" runat="server" AutoPostBack="True">
<asp:ListItem>Visual C#.NET</asp:ListItem>
<asp:ListItem>ASP.NET</asp:ListItem>
<asp:ListItem>CSharpnedir.com</asp:ListItem>
</asp:DropDownList> |
Şimdi bunu ekledikten
sonra Default.aspx sayfamızda Directive bölümüne şunu eklemeniz gerekecek :
<%@
OutputCache Duration="5" VaryByControl="DropDownList1" %>
Evet şimdi burada
önemli olan nokta VaryByControl ( Kontrole göre değiştir ) özelliği. Burada
amacımız DropDownList1 kontrolünün değişimine göre önbellekleme yapmak. ( Tabiki
hala önceden eklediğimiz ve güncel zamanı gösteren Label1 kontrolümüz duruyor
olması gerekir.) ve sayfamızı derleyelim. İlk başta sayfamızı yenileyelim bakalım
zamanı gösteren label kontrolünde herhangi bir değişim oluyo mu? Dikkat ettiyseniz
her 5 dakikada bir değişim olduğunu göreceksiniz ve şimdide eklemiş olduğumuz
DropDownList1 kontrolümüzün seçili olan indexini değiştirin. Ne oldu ? Tabiki
sayfamız önbellekleme zamanının bitmesini beklemeden yeniden bir önbelleği oluşturuldu
ve güncel sayfa önümüze geldi. İşte bu şekilde herhani bir kontrole göre de
nasıl önbellekleme yapabileceğimizi görmüş olduk.
Bu arada değinmeden
geçmek istemediğim bölümlerden birisi ise Önceki örneğimizde Kullanıcı Kontrolleri
ile çalışırken şöyle bir ifadeninde Kullanıcı Kontrollerinde önbellekle yapma
sırasında gözükebileceği :
<%@
OutputCache Duration="5" Shared="true" %>
Peki buradaki Shared
özelliği ne işimize yarıyor. İlka başta adından da anlaşılacağı gibi paylaşılmış
manasına gelen bu özellik : aynı kullanıcı kontrolünü birden fazla yerde kullanabilirsiniz
ve her farklı sayfa için asp.net bu kullanıcı kontrolünün farklı bir önbelleklenmiş
kontrolünü oluşturur. Ama eğer biz böyle bir gereksinime ihtiyaç duymuyorsak
ve her sayfa için aynı önbelleklenmiş kullanıcı kontrolünü kullanmak istiyorsak
o zaman Share özelliğini true yapmamız sorunumuzu giderecektir.
Bu arada bu makalede
data cahcing anlatmadım çückü data caching başlıbalına ayrı ele alınması gereken
bir konu; onunla alakalı video hazırlamamın daha iyi olacağını düşünüyorum çünkü
veritabani işin işine girdiği yerler var görerek öğrenmek daha etkili olur kanaatindeyim.
Makale:
ASP.NET'de "Output Cache" Modeli ASP.NET Abdullah Tarık Güney
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|