Makale Özeti

Bu makalede SQL Server 2005 ile gelen en önemli yeniliklerden biri de asenkron işlemleri son derece basite indirgeyen Broker Service özelliğini inceliyor olacağız.

Makale

Service Broker’ın ne olduğu ve bize ne gibi imkanlar sunduğunu ele almadan önce, Service Broker’ı kullanmak isteyeceğimiz bir senaryo çizelim.

Uygulamaların bazı işlemleri asenkron olarak yapmaları, sıklıkla karşılaştığımız bir durumdur. Örneğin bir online mağazadan kitap aldığımızda, yeni bir alışveriş yapmak için siparişin tamamlanmasını beklemeyiz. Talebiniz sıraya alınır ve daha sonra işlenir, siz ise bu sırada sitede farklı işlemler gerçekleştirebilirsiniz. Şekil 1.1, bu tür uygulamaların genel akışını örneklemektedir.

Şekil 1.1 :: Kuyruk Mekanizması

Şekil 1.1’de görüldüğü üzere,  uygulama web sunucusuna bir talep iletir. Sunucu talebi kuyruğa alır ve istemciye yanıt verir. Kuyruktaki kayıtlar daha sonra bir kuyruk işlemcisi tarafından (kuyruğu yönetmek amacıyla geliştirilmiş bir yazılım) okunur ve gerekli işlemleri gerçekleştirir. Yapılan işlemlere ve işlem sonucuna dair bilgiler ise daha sonra kullanıcıya bir şekilde (mail, sms, vb.) iletilir.

Pek çok noktada, iş akışına oldukça büyük katkısı olan bu tür asenkron işlemlerin gerçekleştirilmesine gereksinim duyulur. Mesaj tabanlı uygulamalar geliştirilirken dikkat etmemiz gereken bazı konular vardır. Bu konuların başlıcaları şunlardır;

1.      Mesaj Sırası: Kuyruğun birden çok mesajı yönetiyor olması durumunda, mesajların belirli bir sıraya göre sıralandırılması gerekir. Bu sıralandırma ilk gelen mesaj ilk olarak işlenecek şeklinde temel bir mantıkta olabileceği gibi, belirli koşulları sağlayan mesajların öncelikli olarak işlenmesi ve/veya belirli koşulları sağlayan mesajların gruplanarak işlenmesi gerekebilir. Örneğin yukarıda çizdiğimiz kitap alışverişi senaryosunda kullanıcımızın alışverişe devam etmesi durumunda, alışveriş bilgilerinin önce, sonrasında da ilgili işleme ait tüm sipariş mesajlarının sırasıyla işlenmesi gerekmektedir.

2.      İşlemler (Transactions): Mesajların işlenmesi ve bağlı olarak işlemlerin gerçekleştirilmesi sırasında sıklıkla hatalar oluşur. Örneğin sistem müşterimizin siparişlerini işlerken bir tedarikçi ile iletişim kuramayabilir. Bu gibi durumlarda mesajın kaybolmaması, sıra geldiğinde yeniden işlenmek üzere kuyruğa geri aktarılması ve o ana kadar yapılan işlemlerin geri alınması gerekmektedir.

3.      Recoverability: Mesajların işlenmesi ve bağlı olarak işlemlerin gerçekleşmesi sırasında, sistemin kendisi de pek çok nedenden dolayı devre dışı kalabilir. Bu gibi durumlarda mesajların sunucular aktif duruma geldiğinde kaldığı yerden, veya yapılmış tüm işlemler geri alınarak en baştan yeniden işlenebilmesi hayati önem taşır. (Bir havale işlemi sırasında 3 kez sistemin yeniden başlamasından dolayı bir hesaptan aynı ücreti 4 defa çektiğinizi düşünün? :)

4.      Esneklik (Scalability): Uygulamamız mesajları performans açısından sıkıntı oluşturmayacak bir aralık kullanarak işlemelidir. Örneğin, mesajlar kuyruğa, kuyruk işlemcisinin mesaj işleyebilme hızından daha hızlı gönderilirse, sistem performans sorunları ile karşılaşabilir.

Farklı mesaj işleme sistemleri, bu konularda farklı çözüm önerileri sunmaktadır ancak bizim asıl ihtiyacımız olan, bize tüm bu özellikleri sunarken, bu özellikleri edinmek için kod yazmamıza ihtiyaç bırakmayacak ve sadece bir veritabanı sisteminde olabilecek recoverability, yönetilebilirlik, dayanıklılık, performans ve esneklik odaklı bir tasarıma sahip olan bir yapı. SQL Server 2005, bize tüm bu saydıklarımızı sunmaktadır.

Service Broker kolayca saniyede binlerce mesajı kabul edip işleyebilecek ve gruplama ve sıralama yapabilecek şekilde konfigure edilebilmektedir. Tüm mesaj işleme süreci transaction tabanlı olduğundan kurtarılabilir durumdadır. Son olarak iş yükü, birden çok SQL Server üzerinde paylaştırılabilmektedir.

Sıradaki bölümde Service Broker altyapısını daha detaylı olarak ele alarak ilk mesaj tabanlı uygulamamızı geliştiriyor olacağız.

Service Broker Building Blocks

Şekil 1.2, service broker uygulaması geliştirmek için kullanılacak building block’ları görüntülemektedir.

Şekil 1.2 :: Service Broker Building Blocks

Application layer’da iki adet uygulamamız mevcut. Bunlar online mağaza ve kuyruk işleme uygulaması olabilir. İki uygulamanın birbiri ile konuşabilmesi için konuşacak uygulamaları tanımlayan bazı meta data kayıtları oluşturmamız gerekiyor. Meta data’yı detaylı olarak incelediğimizde aşağıdaki bölümlerden oluştuğunu görürüz:

1.      Mesaj Türleri: Mesajlar, service broker uygulamalarının en temel elemanlarıdır. Mesaj türleri, mesajın içeriğini tanımlar. Binary, well-formed XML veya geçerli XML türleri şeklinde olabilirler.

2.      Contracts: Contract’lar uygulamaların yaşam süreleri boyunca gönderil alacağı mesajlardan oluşan bir kolleksiyondur.

3.      Servisler: Servisler, mesajların gönderildiği endpointlerdir ve servisler mesajların doğrulanabilmesini sağlamak için bir contract ile ilişkilendirilmişlerdir

4.      Kuyruk: Kuyruklar, SQL Server üzerinde tablo olarak saklanan ve mesajları barındıran yapılardır. Mesajlar kuyruktan bir servis uygulaması tarafından okunur ve işlenirler.

5.      Transport: Transport SQL Server 2005 ile birlikte gelen ve mesajların iletiminde kullanılan tescilli bir protokoldür

6.      Dialog: İki servisin iletişim kurması dialog olarak adlandırılır. Dialog mesajların sıralı olarak işlenmesini sağlayan ve mesajların gönderilip alınmasını sağlayan temel bir yapıdır.

Saydığımız bu bölümler T-SQL dilindeki yeni yapılar aracılığıyla oluşturulur ve yönetilir. Örneğin mesaj türleri oluşturmak için CREATE MESSAGE TYPE ifadesini, iki servis arasında bir mesaj diyaloğu oluşturmak içinse BEGIN DIALOG CONVERSATION ifadesini kullanırız. Bu ifadelerin kullanımını, örnek uygulamamızı geliştirirken daha detaylı açıklıyor olacağız.

Service Broker Kuyruk İşleme Mekanizması
Service Broker’daki kuyruk yapısını kısa bir örnekle açıklayalım;

Bir havaalanında, sırayla yolculara uçak bileti satan satış personelimiz mevcut. Her satış personeli bir veya daha fazla sayıda yolcuya bilet satışı yaparak bir sonraki yolcunun işlemlerini gerçekleştiriyor. Eğer yolcuların oluşturduğu kuyruk çok kalabalıklaşırsa, yoğunluk normal seviyeye inene kadar ek satış personeli devreye giriyor. Service Broker kuyruk işleme mekanizması bu modele oldukça benzemektedir. Her kuyruk bir servise bağlıdır. Eğer mesajlar kuyruğa, sistemin işlem yapabilme hızını aşan bir hızla eklenirse birden çok queue reader tanımlayabilirsiniz. Service Broker tüm reader instancelarını yönetecek ve gerekli olması halinde belirlenen üst sınıra ulaşana kadar yeni instance’lar oluşturacaktır.

Service Broker kuyruk işleme mekanizmasındaki bir diğer önemli kavramsa “conversation group”tur. Mesajlar servisler arasında iletilirken birbiri ile ilgili mesajların arasında bir bağ kurulmasına conversation group denir. Bu yapı mesajların sıralı olarak işlenmesini sağlamaktadır. Örneğin kuyruğa çok yüklü miktarda sipariş ve sipariş detay bilgileri geliyorsa sipariş bilgileri işlenene kadar detay bilgileri işlemememiz gerekir. Conversation group yapısı bu tür durumlarda bize yardımcı olmaktadır. Conversation group’ları aynı zamanda kilit kapsamını oluşturmaktadır. Belirli bir gruba ait tüm mesajlar okuma sürecinde sıralı işlenmeyi sağlamak amacıyla kilitlenirler. Ancak bu yapı, diğer conversation group’ların paralel olarak işlenmesine mani değildir.

Service Broker Uygulaması
Sıra ilk service broker uygulamamızı geliştirmeye geldi. Örnek uygulamamız tek yönlü mesajlaşma yapan bir uygulama olacak. Bir mesaj oluşturacağız ve sonrasında bu mesajı okuması için ayrı bir servise ileteceğiz. Son derece basit ancak service broker mekanizmasını açıklayan bir örnek olacak.

Service Broker uygulamalarının geliştirilmesi şu adımlardan oluşur.

1.      Gerekli mesaj türlerinin ve ilgili doğrulamaların tanımlanması

2.      Gerekli contract’ların tanımlanması ve mesaj sıralamasının belirlenmesi

3.      Gerekli kuyrukların oluşturulması

4.      Gerekli servislerin oluşturulması ve ilgili kuyruklarla ilişkilendirilmesi

5.      Mesajların gönderilmesine ve okunmasına başlanması

Bu adımların her birinde çeşitli T-SQL ifadeleri kullanırız. Örneğimiz kullanılacak T-SQL ifadelerinin pek çoğunu içeriyor olsa da, bu ifadelerin tümünü ve ifadelerle ilgili detaylı bilgiyi SQL Server 2005 Books Online’da bulabilirsiniz.

Aşağıdaki T-SQL scriptini GO ifadelerinden ayırarak çalıştırırsanız, aşamaları ve gerçekleştirilen işlemleri detaylı olarak görebilirsiniz.

-- örneğimizde adventureworks veritabanını kullanıyor olacağız

USE AdventureWorks

GO

-- ilk olarak mesaj türünü oluşturuyoruz.

CREATE MESSAGE TYPE DenemeMesaji

VALIDATION = NONE

GO

-- daha sonra kimlerin ne tür mesajlar gönderebileceğini belirleyen

-- bir contract oluşturuyoruz

CREATE CONTRACT DenemeContracti

(DenemeMesaji SENT BY INITIATOR)

GO

-- iki endpoint arasındaki iletişimi sağlamak için mesajların saklanacağı

-- iki adet kuyruk tanımlamamız gerekiyor

CREATE QUEUE GondericiKuyruk

 

CREATE QUEUE OkuyucuKuyruk

GO

-- kuyrukları yönetmek üzere iki servis tanımlayarak bir önceki adımda

-- oluşturduğumuz kuyruklara bağlıyoruz

CREATE SERVICE Gonderici

  ON QUEUE GondericiKuyruk

 

CREATE SERVICE Okuyucu

  ON QUEUE OkuyucuKuyruk (DenemeContracti)

GO

-- bu noktada servisler aracılığıyla mesajlar gönderip almaya

-- başlayabiliriz

DECLARE @conversationHandle UNIQUEIDENTIFIER

DECLARE @message NVARCHAR(100)

 

BEGIN

  BEGIN TRANSACTION;

  BEGIN DIALOG @conversationHandle

        FROM SERVICE Gonderici

        TO SERVICE 'Okuyucu'

        ON CONTRACT DenemeContracti

  -- conversation içinde bir mesaj gönderiyoruz

  SET @message = N'Hello, World';

  SEND  ON CONVERSATION @conversationHandle

        MESSAGE TYPE DenemeMesaji (@message)

  COMMIT TRANSACTION

END

GO

-- mesajı kuyruktan okuyoruz

RECEIVE CONVERT(NVARCHAR(max), message_body) AS message

 FROM OkuyucuKuyruk

-- oluşturduğumuz nesneleri siliyoruz

DROP SERVICE Gonderici

DROP SERVICE Okuyucu

DROP QUEUE GondericiKuyruk

DROP QUEUE OkuyucuKuyruk

DROP CONTRACT DenemeContracti

DROP MESSAGE TYPE DenemeMesaji

GO

Mesajları okumakta kullanırken kullandığımız söz dizimi SELECT ifadesine oldukça benzemektedir. RECEIVE ifadesi bir mesajı kuyruktan okur ve sonrasında siler. Bu işleme "destructive read" adı verilmektedir. Kuyruktaki mesajları okumak için aynı zamanda SELECT ifadesini de kullanabiliriz. SELECT ifadesi non-destructive okuma yapar.

Bu noktada gelecek ilk soru, "neden veritabanına dayanan bir mesajlaşma yapısı kullanalım?" olacaktır. Mesela;

1.      Mesajları veritabanında saklayarak alışık olduğumuz veritabanı programlama yapısını kuyruk tabanlı uygulamalarda da kullanabiliriz. Öğrenmemiz veya kullanmamız gereken ayrı bir API yoktur.

2.      Veritabanı tabanlı programlama, veritabanı sisteminin tüm avantajlarını kullanımımıza sunmaktadır. Örneğin service broker uygulamaları esnek, recoverable ve daha kolay yönetilebilirdir.

3.      İhtiyaç duyulan tüm ifadeler veritabanı sistemi ile birlikte gelmektedir. Özel bir yapı öğrenme gereği yoktur.

4.      Çoklu kuyruk okuyucu modeli, SQL Server'da önceden gerçekleştiremediğimiz multi-thread uygulamalara destek vermektedir.

Bu makalede Service Broker hizmetini genel hatlarıyla özetlemeye çalıştık. İleride daha geniş kapsamlı örnekler içeren makalelerle bu hizmeti daha yakından ele alıyor olacağız.

Kullanılan kaynaklar;
SQL Server 2005 Books Online
Msdn (http://msdn.microsoft.com)

Kadir Sümerkent
http://www.sumerkent.com