pengeunpedi pengeunpedi pengeunpedi
  penguenyuvasi   pengulog   arşiv   bulut   rss

servlet'in alamet-i farikası

Tuesday, June 20, 2006 6:14:00 AM tarihinde Fırat KÜÇÜK tarafından gönderildi.

Bu aralar hepinizin de bildiği üzere. Ya da bizim çokça zikrettiğimiz üzere; bir java serüvenidir ki gidiyor. Ee, her zaman yeni bir şeyler öğrenmeli, koşmalı, koşamıyorsa yerinde zıplamalı. Biz de bunu, destur edinerek başımıza böyle işler açıyoruz. Açarken de günlüğümüzü çiziktiriyoruz ki; ne maymunluklar yaptığımızı görün.

Bu gün bol bol servlet, koddum. (koddum, koddun, koddu yani i code, you code, he/she/it codes) EE, artık açık kaynak tabi :) Tiger kod adlı java 5.0 ile yolumuza dolu dizgin devam ediyoruz. Yalnız ! Bugün sıyırmama neden olan bir olay ile karşılaştım; HttpServlet sınıfından miras aldığımız ve çiğneyip, ezip geçtiğimiz (override) doGet metodunun get ile gönderilen istekleri tuttuğunu, servlet ile uğraşan herkes bilir. Tanımladığım bir Vector tipli değişken için addElement metodunu, doGet metodu içinden çağırdım. İşte sıyırma belirtileri tam burada başladı. Vector değişkeninin içine attığım veriler bir çok kez tekrar ediyordu. Bunun, oluşturduğum servlete giden parametre miktarınca olduğunu düşündüm ilk önce. Servlet?a=1&b=2&c=3 gibi bir örnek ifadenin, 3 parametre gittiğinden 3 defa doGet metodunu çağırdığını ve bundan dolayı olduğunu sandım evvela.

Ama, cıkk! Öyle değilmiş durum. Çünkü dizimizin boyutu git gide artmaktaydı. Bunu, servletimizin başına private int counter = 0; diye bir sayaç ekleyerek test etmeye karar verdim. doGet metodunun içine de o meşhuuuur: counter++; ifadesini yazdım.

İşte dananın kuyruğunun koptuğu an buydu! Her f5 tuşuna basışımda sayaç bir artıyordu! Bir oturum değişkeni değildi. Sunucuya ait küresel bir değişken de değildi. Yav PHP'de, Python'da böyle bir şey yok! C# programladığım zamanlar da bu tarz birşey ile karşılaşmamıştım. Hem de private bir değişkenin bu denli beni madara etmesi bende geçersiz işlem yürüttü.

Olayın kaynağı tabiki yine cehaletmiş. Servletin çok kanallı (multi-thread) olduğunu biliyoruz. Lakin gelen isteklere nasıl yanıt verdiği konusunda cehaletimiz sürmekteymiş. Efenim! Normal bir PHP betiğine gelen her istek (request), Apache'de bir alt süreç (child process) oluşturur. Bu alt süreçler, talep edilen PHP betiğini çalıştırır. Apache, kendisine istek gelmediği zaman, KeepAlive seçili ise, KeepAlive zaman aşımı süresince yeni istekleri bekler. Eğer istek gelmez ve KeepAlive süresi dolar ise PHP alt süreci, Hakk'ın rahmetine kavuşur. CGI'da da bu yaklaşım aynıdır. Fast-CGI'da ise tüm istekler için tek bir alt süreç oluşur. Fakat Servlet denilen meretin çalışma prensibi bunlardan hiçbirine uymamakta ki değişken sürekli etkin kalmaktaydı!

Efenim! Servlet sunucusu tek süreç ile çalışmaktadır. Bu süreç, kanalları vasıtası ile servletleri çağırır. Çağrılan servletler isteklere yine aynı metod ile cevap verirler. Bu sayede hızlı bir çalışma mekanizması kazanılır. Servlet ilk çalıştığında; init metodu çalışır. Ve servlet çalışmaya devam eder. Her gelen istek doGet veya doPost metodunu çağırır. Böylelikle değişkenimiz uygulama kapanana kadar işlevini yerine getirir.

Buna göre kolayca bir vuru ziyaretçi sayacı (hit counter) yazabiliriz. Bu sayaç, sayfaya gelen istek sayısını gösterir.

import java.io.*;
import javax.servlet.http.*;

public class Sayac extends HttpServlet {

    private int sayac;

    public void doGet(HttpServletRequest istek, HttpServletResponse cevap)

    throws IOException {
        sayac++;
        PrintWriter sayfa = cevap.getWriter();

        sayfa.println(sayac);
        sayfa.close();

    }
}
atölye, inceleme, javakaynak | yorumlar [1]
 
ilişkili gönderiler:

delicious | digg | reddit | magnoliacom | furl | google | yahoo






pengulog

her hakkı erkektir © 2008 e-posta