.NET İçin Kuyruk Çözümleri : MSMQ

MSMQ Nedir?

MSMQ zaman bağımsız olarak birden fazla uygulama arasında offline veri alışverişini sağlayan Windows tabanlı kuyruk sistemidir. MSMQ ile birlikte uygulama veya ağ üzerinde bir sorun oluşsa dahi (çökme, hata fırlatma vb.) akış, gerçekleşen sorun giderildikten sonra veya çöken/çalışmayı durduran uygulama tekrar çalışmaya başladıktan sonra devam eder.

MSMQ ile iletilen mesajlar sistem üzerinde fiziksel bir alanda saklanmaktadır. Bu noktada yukarıda bahsetmiş olduğumuz senaryolar dahil, mesajları alması beklenen uygulama kapalı olsa dahi bu mesajlar saklanmaktadır.

Resim 1: Oluşturduğunuz Queue’ları Computer Management Ekranından Görmeniz Mümkün (compmgmt.msc)

Kuyruk Tipleri

MSMQ için iki adet kuyruk tipi mevcut;

Public Queues:

Bu tipte oluşturulmuş olan kuyruklara, yalnızca oluşturulduğu sunucu/bilgisayardaki uygulamalardan değil, aynı ağa bağlı tüm sunucu/bilgisayarlardan erişim sağlanabilmektedir. Bu sayede aynı ağda bulunan iki farklı sunucu ve bu sunucularda kurulu olan farklı uygulamalar arasında da MSMQ aracılığı ile mesaj iletimi sağlanabiliyor.

Private Queues:

Bu tipte oluşturulmuş olan kuyruklara ise yalnızca oluşturulduğu bilgisayar/uygulama üzerinden erişim sağlanabilir ve yalnızca aynı bilgisayar/sunucu üzerinde kurulu olan uygulamalar bu kuyruktan beslenebilir ve bu kuyruğu besleyebilir.

Programlanabilirlik

MSMQ alt yapısı C#, VB.NET ve .NET tabanlı diğer diller tarafından kullanılabilmektedir. System.Messaging namespace’i altından erişilebilir.

Kurulum

Eğer MSMQ sistemini bilgisayarınıza kurmak isterseniz, aşağıdaki adımları takip edebilirsiniz.

  1. Denetim Masası üzerinden “Programlar” seçimini yapın, ardından açılan ekranda “Programlar ve Özellikler” altında bulunan “Windows Özelliklerini Aç veya Kapat” seçimini yapın. Veya Windows + R tuş kombinasyonu ile “optionalfeatures” komutunu çalıştırabilirsiniz.
  2. Açılan pencerede “Microsoft Message Queue (MSMQ) Server” seçeneğini işaretleyin

Resim 2: “Windows Özelliklerini Aç veya Kapat” seçimi sonrası açılan pencereden “Microsof Message Queue (MSMQ) Server” özelliği işaretlenmeli.

Aynı kurulumu Windows Sunucu üzerinde yapmak için ise aşağıdaki adımları izlemelisiniz;

  1. Server Manager açıldıktan sonra Sağ üst tarafta bulunan Manage altından, “Add Roles and Features” seçilir.
  2. Açılan pencereden Features adımına gelindikten sonra listeden “Message Queuing” özelliği işaretlenir. Bu seçimin ardından “Install” butonu tıklanır ve özelliğin aktif edilme süreci bağlar. Bu işlemin ardından sunucunuzu yeniden başlatmanız gerekmez.

Resim 3: Features adımı altındaki listeden “Message Queuing” seçimi yapılır ve Install butonu tıklanarak kurulum süreci başlatılır.

C# Uygulamalarında MSMQ’yu Kullanmak

MSMQ’nun ne olduğundan ve nasıl kurulduğundan bahsettiğimize göre, örnek bir senaryo üzerinden bir C# uygulamasında MSMQ’nun sağladığı kuyruk alt yapısından nasıl faydalanabiliriz inceleyelim.

Senaryomuz; PeakUp’ta yeni işe başlayan personelin bilgisi sisteme girildiğinde, ilgili çalışana mail atmak olsun. Bu senaryoda ihtiyacımız olan iki uygulama var;

  1. Personel bilgilerinin girileceği uygulama
  2. Farklı uygulamalardan gelen mail gönderme taleplerini karşılayacak ve mailleri gönderecek uygulama.

İlk uygulamamızın ismi Peakup.Employee.Manager olsun. Projemizin yapısı aşağıdaki gibi;

PeakUp.Empoyee.Manager

  • Extensions
    • MessageQueueExtensions.cs (MessageQueue sınıfı için yazacağımız extension metotlar)
  • Models
    • EmployeeModel.cs (Personel sınıfı)
    • Mail.cs (Mail Sınıfı)
  • Program.cs

Önemli

MessageQueue sınıfını kullanabilmemiz için her iki projemize de System.Messaging referansını eklememiz gerekiyor.

Şimdi kodlara göz atalım:

Oluşturmak istediğimiz isimde bir Queue zaten varsa onu getirmek, yoksa tekrar oluşturmak gerekiyor. Bu işlemi daha hızlı bir şekilde gerçekleştirmek için bu Extension metodu kullanabilirsiniz.

public static class MessageQueueExtensions
{
public static MessageQueue CreateIfNotExists(this MessageQueue messageQueue, string queueName)
{
//Bu alanda ".\Private$" yolu, oluşturmak/bulmak istediğimiz queue'nin private olduğunu belirtiyor. Ardından dosya yoluna queue ismi ile devam ediyoruz.
if (MessageQueue.Exists($@".\Private$\{queueName}"))
{
//Queue mevcut, bu queue için bir C# objesi oluşturup dönüyoruz.
return new MessageQueue($@".\Private$\{queueName}");
}
else
{
//Queue mevcut değil, "Create" metodu ile yeni bir queue oluşturup, bu queue'nun C# objesini dönüyoruz.
return MessageQueue.Create($@".\Private$\{queueName}");
}
}
}

Employee ve Mail sınıflarımız;

public class EmployeeModel
{
public EmployeeModel(string name, string mailAddress)
{
this.Name = name;
this.MailAddress = mailAddress;
}
public string Name { get; set; }
public string MailAddress { get; set; }
}
public class Mail
{
public Mail(string to, string content)
{
this.To = to;
this.Content = content;
}
public string To { get; set; }
public string Content { get; set; }
}
view raw Mail.cs hosted with ❤ by GitHub

Yeni personel oluşturma ve bu personeli mail için kuyruğa atma işlemlerini yaptığımız program dosyamız;

using Newtonsoft.Json;
using PeakUp.Employee.Manager.Extensions;
using PeakUp.Employee.Manager.Models;
using System;
using System.Messaging;
using System.Threading;
namespace PeakUp.Employee.Manager
{
class Program
{
static void Main(string[] args)
{
//Kullanıcıdan Personel Bilgilerinin Alınması
Console.WriteLine("Personelin Adı");
var employeeName = Console.ReadLine();
Console.WriteLine("Personelin E-Posta Adresi");
var employeeMailAdress = Console.ReadLine();
//Alınan Bilgiler ile Employee objesinin oluşturulması
var employee = new EmployeeModel(employeeName, employeeMailAdress);
//Hoşgeldin Maili için Personelin Kuyruğa Eklenmesi
AddEmployeeToQueue(employee);
//Personelin OluÅŸturulduÄŸuna Dair Mesaj
Console.WriteLine("Personel oluşturuldu, teşekkürler.");
//Mesajın Ekranda 1 saniye kalması için Thread'i uyutuyoruz
Thread.Sleep(1000);
}
static void AddEmployeeToQueue(EmployeeModel employee)
{
// Email Queue zaten bilgisayarda/sunucuda mevcut ise getirilmesi, değilse oluşturulup getirilmesi (Detaylar için Extensions altında bulunan CreateIfNotExists metodunun incelenmesi gerekiyor.
var emailQueue = new MessageQueue().CreateIfNotExists("mail");
//string veri alışverişi yaptığımızdan dolayı emailQueue için string tipinde bir formatter tanımlıyoruz
Type formatterType = typeof(string);
emailQueue.Formatter = new XmlMessageFormatter(new Type[] { formatterType });
//Mail objesinin oluşturulması
var mail = new Mail(employee.MailAddress, $"Aramıza hoşgeldin {employee.Name}");
//Gönderilen mesajların daha kolay yazılıp, daha kolay okunabilmesi için JSON'a çevrilmesi (Opsiyonel)
var mailJson = JsonConvert.SerializeObject(mail);
//Mesajın queue'ya gönderilmesi
emailQueue.Send(mailJson);
}
}
}
view raw Program.cs hosted with ❤ by GitHub

İkinci uygulamamızın ismi ise PeakUp.Email.Manager. Projemizin yapısı aşağıdaki gibi;

PeakUp.Email.Manager

  • Extensions
    • MessageQueueExtensions.cs (MessageQueue sınıfı için yazacağımız extension metotlar)
  • Models
    • Mail.cs (Mail Sınıfı)
  • Program.cs

Bu projemizin kodları da aşağıdaki gibi;

Oluşturmak istediğimiz isimde bir Queue zaten varsa getirmek, yoksa tekrar oluşturmamız gerekiyor. Bu işlemi daha hızlı bir şekilde gerçekleştirmek için bu Extension metodu kullanabilirsiniz.

public static class MessageQueueExtensions
{
public static MessageQueue CreateIfNotExists(this MessageQueue messageQueue, string queueName)
{
//Bu alanda ".\Private$" yolu, oluşturmak/bulmak istediğimiz queue'nin private olduğunu belirtiyor. Ardından dosya yoluna queue ismi ile devam ediyoruz.
if (MessageQueue.Exists($@".\Private$\{queueName}"))
{
//Queue mevcut, bu queue için bir C# objesi oluşturup dönüyoruz.
return new MessageQueue($@".\Private$\{queueName}");
}
else
{
//Queue mevcut değil, "Create" metodu ile yeni bir queue oluşturup, bu queue'nun C# objesini dönüyoruz.
return MessageQueue.Create($@".\Private$\{queueName}");
}
}
}

Mail sınıfımız;

public class Mail
{
public Mail(string to, string content)
{
this.To = to;
this.Content = content;
}
public string To { get; set; }
public string Content { get; set; }
}
view raw Mail.cs hosted with ❤ by GitHub

Mail kuyruğunu dinleyen ve mail sınıfını konsola yazdıran program dosyamız;

using Newtonsoft.Json;
using PeakUp.Email.Manager.Extensions;
using PeakUp.Email.Manager.Models;
using System;
using System.Messaging;
namespace PeakUp.Email.Manager
{
class Program
{
static void Main(string[] args)
{
// Email Queue zaten bilgisayarda mevcut ise getirilmesi, değilse ise oluşturulup getirilmesi (Detaylar için Extensions altında bulunan CreateIfNotExists metodunun incelenmesi gerekiyor.
var emailQueue = new MessageQueue().CreateIfNotExists("mail");
//string veri alışverişi yaptığımız için emailQueue için string type bir formatter tanımlıyoruz
Type formatterType = typeof(string);
emailQueue.Formatter = new XmlMessageFormatter(new Type[] { formatterType });
//ReceiveCompleted Event'ini gelen mesajları okuyabilmek için takip etmemiz gerekiyor.
emailQueue.ReceiveCompleted += EmailQueue_ReceiveCompleted;
//Gelen mesajları almaya başlamak için BeginReceive() metodunu çağırmamız gerekiyor.
emailQueue.BeginReceive();
Console.ReadKey();
}
private static void EmailQueue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
//Sender objesi MessageQueue tipine dönüştürülür
var mailQueue = (MessageQueue)sender;
//Json formatında gönderdiğimiz mesajı tekrar objeye çeviriyoruz.
var mailObject = JsonConvert.DeserializeObject<Mail>((string)e.Message.Body);
//Gelen mesajı konsola yazdırıyoruz
Console.WriteLine($"Gönderilecek adres: {mailObject.To}, Mesaj: {mailObject.Content}");
//Mesaj almaya devam etmek için BeginReceive metodunu tekrar çağırıyoruz.
mailQueue.BeginReceive();
}
}
}
view raw Program.cs hosted with ❤ by GitHub

Bir C# projesinde MSMQ kullanan bu yazımızın sonuna gelmiş olduk. Bu konuyla ilgili daha fazla detaya ihtiyaç duyuyor veya örnekleri beraber incelemek istiyorsanız Live Coding Sessions‘larımızı takip etmeyi ihmal etmeyin!

Teşekkürler!

Start typing and press Enter to search

X