Gereksinimler ve Ön Hazırlık
JMS ile çalışmaya başlamadan önce, mesajlaşma altyapısını yönetecek bir "Message Broker" (Mesaj Aracısı) yazılımına ihtiyacınız vardır. 2026 yılı standartlarında en yaygın kullanılan araçlar Apache ActiveMQ Artemis ve RabbitMQ (JMS desteği ile) olarak öne çıkmaktadır.
- JDK 21 veya üzeri: Modern Java özellikleri ve performans iyileştirmeleri için gereklidir.
- Maven/Gradle: Bağımlılık yönetimi için kullanılacaktır.
- ActiveMQ Artemis: Mesaj kuyruğu sağlayıcısı olarak kullanılacaktır.
- IDE: IntelliJ IDEA veya Eclipse gibi gelişmiş bir geliştirme ortamı.
Projenize gerekli kütüphaneleri eklemek için pom.xml dosyanıza aşağıdaki bağımlılığı ekleyerek başlayabilirsiniz:
org.apache.activemq
artemis-jms-client
2.37.0
JMS Mimarisi: Temel Kavramlar
JMS, iki ana model üzerine kuruludur: PTP (Point-to-Point) ve Pub/Sub (Publish/Subscribe). PTP modelinde bir mesaj tek bir alıcıya giderken, Pub/Sub modelinde mesaj bir konuya (Topic) gönderilir ve o konuya abone olan tüm alıcılar mesajı alır.
| Özellik | Point-to-Point (Queue) | Publish/Subscribe (Topic) |
|---|---|---|
| Alıcı Sayısı | Tek alıcı | Çoklu alıcı |
| Kalıcılık | Mesaj kuyrukta bekler | Abone aktif değilse mesaj kaybolabilir |
| Kullanım Alanı | İş yükü dağıtımı (Load Balancing) | Bildirim sistemleri (Event Broadcasting) |
Adım Adım Mesaj Gönderici (Producer) Oluşturma
Mesaj gönderici, kuyruğa veri bırakan bileşendir. Öncelikle bir ConnectionFactory oluşturmalı ve ardından bir Session başlatmalıyız. Aşağıdaki kod örneği, bir metin mesajının nasıl kuyruğa gönderileceğini göstermektedir.
import javax.jms.*;
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
public class MesajGonderici {
public void mesajGonder(String metin) throws Exception {
ConnectionFactory cf = new ActiveMQConnectionFactory("tcp://localhost:61616");
try (Connection connection = cf.createConnection()) {
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("islemKuyrugu");
MessageProducer producer = session.createProducer(queue);
TextMessage message = session.createTextMessage(metin);
producer.send(message);
System.out.println("Mesaj gönderildi: " + metin);
}
}
}
Bu kod bloğu, belirtilen adresteki mesaj aracısına bağlanır, "islemKuyrugu" isimli bir kuyruk oluşturur ve metin mesajını iletir. try-with-resources yapısı, bağlantıların güvenli bir şekilde kapatılmasını sağlar.
Adım Adım Mesaj Alıcı (Consumer) Oluşturma
Mesaj alıcı, kuyruğu dinleyen ve gelen veriyi işleyen bileşendir. JMS'de alıcılar mesajı senkron (çekerek) veya asenkron (dinleyerek) alabilirler. Modern uygulamalarda MessageListener arayüzü ile asenkron dinleme yapmak daha performanslıdır.
public class MesajAlici implements MessageListener {
@Override
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
String icerik = ((TextMessage) message).getText();
System.out.println("Alınan mesaj: " + icerik);
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
Bu sınıf, kuyruğa yeni bir mesaj düştüğü anda otomatik olarak tetiklenir. onMessage metodu içerisindeki mantık, mesajın işlenme sürecini temsil eder.
JMS Kullanımında Güvenlik ve Hata Yönetimi
Mesaj kuyrukları ile çalışırken, verinin güvenliği ve mesajın işlenememesi durumu (Poison Message) kritik öneme sahiptir. Mesajların şifrelenmesi ve hatalı mesajların "Dead Letter Queue" (DLQ) adı verilen yedek kuyruklara aktarılması gerekir.
Kritik Güvenlik Uyarısı: Mesaj kuyruklarına gönderilen verilerde hassas kişisel veriler (KVKK kapsamında) bulunuyorsa, veriyi kuyruğa atmadan önce uygulama katmanında mutlaka şifreleyin. Ayrıca, mesaj aracısına erişim için mutlaka kullanıcı adı ve parola tabanlı kimlik doğrulama kullanın.
Hata yönetimi için Session oluştururken CLIENT_ACKNOWLEDGE modunu kullanarak, mesajın başarıyla işlendiğinden emin olduktan sonra onay (acknowledge) gönderebilirsiniz.
// Mesajı manuel onaylamak için
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
// İşlem başarılı olursa:
message.acknowledge();
Sıkça Sorulan Sorular
JMS ile REST API arasındaki temel fark nedir?
REST API senkron bir haberleşme sağlar; yani istek gönderen taraf yanıt bekler. JMS ise asenkron çalışır; gönderici mesajı bırakır ve kendi işine devam eder, alıcı ise müsait olduğunda mesajı işler.
Mesaj kuyruğu neden gereklidir?
Sistemlerin birbirine sıkı sıkıya bağlı (tightly coupled) olmasını engeller. Eğer bir servis geçici olarak kapalıysa, mesajlar kuyrukta birikir ve servis ayağa kalktığında işlenmeye devam eder.
JMS yerine neden Kafka tercih edilir?
JMS, geleneksel kurumsal mesajlaşma için idealdir. Kafka ise "Event Streaming" yani çok yüksek hacimli ve sürekli veri akışı gerektiren büyük veri projeleri için tasarlanmıştır.
Mesaj kaybolması nasıl engellenir?
Mesajların kalıcı (persistent) olarak işaretlenmesi ve mesaj aracısının disk üzerinde yedekleme yapması sağlanmalıdır.
JMS ile işlem (Transaction) yönetimi nasıl yapılır?
JMS oturumları transaksiyonel olarak başlatılabilir. Bu sayede bir mesaj işlenirken hata oluşursa, mesaj otomatik olarak kuyruğa geri döndürülür (rollback).
JMS Uygulamalarında Performans Optimizasyonu ve İleri İpuçları
Mesaj kuyruğu tabanlı sistemlerde performans, sadece mesaj gönderim hızı ile değil, aynı zamanda kaynak kullanımı ve ağ trafiğinin verimli yönetimiyle ölçülür. Büyük ölçekli kurumsal uygulamalarda JMS performansını artırmak için aşağıdaki stratejileri uygulayabilirsiniz.
Mesaj Gruplandırma ve Batch İşleme
Tek tek mesaj göndermek yerine, yüksek hacimli verilerde mesajları gruplandırarak (Batching) göndermek, ağdaki TCP el sıkışma maliyetini düşürür. Ayrıca, Session nesnelerini yeniden kullanmak ve Connection havuzlarını (Connection Pooling) aktif etmek, kaynak tüketimini ciddi oranda azaltır.
Asenkron Mesaj Gönderimi
Varsayılan olarak birçok JMS sağlayıcısı senkron gönderim yapar. Ancak, yüksek performans gerektiren senaryolarda CompletionListener kullanarak gönderim işlemini asenkron hale getirebilirsiniz. Bu sayede ana iş parçacığınız (thread) kuyruktan onay beklemek zorunda kalmaz.
// Asenkron mesaj gönderimi örneği
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("Yüksek performanslı veri");
producer.send(message, new CompletionListener() {
@Override
public void onCompletion(Message message) {
System.out.println("Mesaj başarıyla iletildi.");
}
@Override
public void onException(Message message, Exception e) {
System.err.println("Mesaj gönderimi başarısız: " + e.getMessage());
}
});
JMS Sistemlerinde Hata Ayıklama ve İzlenebilirlik (Observability)
Dağıtık sistemlerde bir mesajın kaybolması veya hatalı işlenmesi durumunda sorunun kaynağını bulmak oldukça zordur. JMS uygulamalarınızda izlenebilirliği artırmak için şu yöntemleri izlemelisiniz:
Correlation ID Kullanımı
İstek-cevap (Request-Reply) desenini kullanırken, her mesaj için benzersiz bir JMSCorrelationID atamak, sistemdeki mesaj akışını izlemenizi sağlar. Bu ID sayesinde log dosyalarınızda bir mesajın yaşam döngüsünü uçtan uca takip edebilirsiniz.
Dead Letter Queue (DLQ) Yapılandırması
İşlenemeyen mesajlar için bir "Ölü Mektup Kuyruğu" (DLQ) oluşturmak, üretim ortamındaki hataları izole etmek için kritiktir. Eğer bir mesaj belirlenen sayıda denemeden (retry) sonra başarısız olursa, mesajı silmek yerine DLQ'ya taşıyarak daha sonra manuel inceleme yapabilirsiniz.
| Strateji | Fayda |
|---|---|
| Correlation ID | Mesaj izlenebilirliği ve hata takibi sağlar. |
| DLQ (Dead Letter Queue) | Hatalı mesajların kaybolmasını önler. |
| Message Priority | Kritik mesajların öncelikli işlenmesini sağlar. |
JMX ile İzleme
Çoğu JMS sağlayıcısı (ActiveMQ, Artemis vb.), JMX (Java Management Extensions) üzerinden metrikler sunar. Kuyruk derinliği (queue depth), tüketici sayısı ve mesaj işleme süresi gibi metrikleri JMX aracılığıyla izleyerek sistem darboğazlarını önceden tespit edebilirsiniz.
// Mesaj önceliği belirleme örneği
MessageProducer producer = session.createProducer(destination);
producer.setPriority(9); // 0-9 arası değer, 9 en yüksek öncelik
producer.send(message);
Bu ileri seviye konfigürasyonlar, uygulamanızın sadece çalışmasını sağlamakla kalmaz, aynı zamanda yüksek trafik altında bile kararlı ve yönetilebilir bir mimariye sahip olmanıza yardımcı olur.
Sonuç
Java ile JMS kullanarak mesaj kuyruğu tabanlı iletişim kurmak, sistemlerinizin dayanıklılığını ve ölçeklenebilirliğini artırmanın en etkili yollarından biridir. Bu rehberde temel gönderim ve alım mekanizmalarını, güvenlik prensiplerini ve hata yönetimini adım adım inceledik. Bir sonraki adım olarak, Spring Boot'un JmsTemplate yapısını kullanarak bu işlemleri çok daha az kodla nasıl yöneteceğinizi araştırmanızı öneririm.
Yasal Uyarı: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamına (Production) geçmeden önce, mesaj aracınızın konfigürasyonunu, ağ güvenliğini ve hata tolerans mekanizmalarını kurumunuzun güvenlik politikalarına göre yapılandırdığınızdan emin olun.


Yorumlar (0)
Yorum Yaz