Spring Boot kullanarak RabbitMQ ile Mesaj İletimi

Ne Geliştireceğiz?

Merhaba,

Bu yazımızda Spring Boot ile RabbitMQ kullanarak kuyruğa mesaj iletmeyi göreceğiz.

Neler Gerekiyor?

  • IntelliJ IDEA (Ben bu IDE’yi kullanacağım)
  • Java 1.8 JDK
  • Maven 3.2 ya da üzeri
  • Docker

Evet bu eğitimizide docker da kullanacağız. Peki docker nedir? Docker işletim sistemi seviyesinde sanallaştırma sunan bir konteyner yönetim programıdır. Kısaca bilgisayarımızda sanal makine kurulumunu saniyeler içinde sağlayan bir yapıdır. Docker sayesinde kendi sistemimizde herhangi bir kurulum yapmadan işlerimizi yapan sanal makineler üretebilir ve daha sonra bunları kaldırıp atabiliriz. Bu yönüyle çok pratik ve ucuz maliyetlidir.

RabbitMQ Nedir?

RabbitMQ, açık kaynaklı bir mesaj aracısı (messaging broker) yazılımıdır. Mesaj aracı, uygulamalar arasında veri ve bilgi alışverişi için kullanılır. RabbitMQ, dağıtık sistemler arasında veri iletimini kolaylaştırır ve bu iletişimi güvenilir ve etkili bir şekilde yönetir. Özellikle mikroservis tabanlı uygulamalar, iş kuyrukları, olay tabanlı sistemler ve dağıtık uygulamalar için ideal bir araçtır.

RabbitMQ Neden Kullanılır?

RabbitMQ’nun kullanılmasının bazı temel nedenleri şunlardır:

1. Asenkron İletişim:

RabbitMQ, uygulamalar arasında asenkron mesaj iletişimini destekler. Bu, bir uygulamanın bir mesajı gönderdiğinde, alıcı uygulama anında yanıt vermek zorunda olmadığı anlamına gelir. Bu, sistemler arasında bağımsız çalışabilme ve daha iyi ölçeklenebilme sağlar.

2. İş Kuyrukları:

RabbitMQ, iş kuyrukları oluşturmak ve yönetmek için kullanılır. İş kuyrukları, işlemleri sıraya koymak ve işlem önceliklerini belirlemek için kullanılır. Bu, yoğun iş yüklerini daha iyi yönetmek ve işleri düzenli bir şekilde işlemek için kullanışlıdır.

İlgini çekebilir:  Spring ile Spring Boot Arasındaki Farklar Nelerdir?

3. Hata Toleransı:

RabbitMQ, mesajların kaybedilmesini önlemek için güvenilir bir iletişim sağlar. Mesajların başarıyla iletilip işlenmediğini takip etmek ve gerektiğinde yeniden denemek için mekanizmalar sunar. Bu, sistemler arasında hata toleransı sağlar.

4. Entegrasyon Kolaylığı:

Spring Boot ile birlikte kullanıldığında RabbitMQ, uygulamaları kolayca entegre edebilir. Spring Boot, RabbitMQ bağlantılarını ve işlem sırasını yönetmek için kullanışlı araçlar ve kütüphaneler sunar.

5. Dağıtık Sistemler İçin Uygunluk:

RabbitMQ, dağıtık sistemler ve mikroservis mimarileri için ideal bir çözümdür. Uygulamalar arasında iletişimi kolaylaştırır ve verilerin güvenli bir şekilde taşınmasını sağlar.

RabbitMQ’nun bu avantajları, özellikle büyük ve karmaşık sistemlerde, veri akışının güvenilirliği ve ölçeklenebilirliği gerektiren projelerde kullanılmasını popüler hale getirir. Spring Boot ile entegrasyonu sayesinde, RabbitMQ kullanarak uygulamalarınızı daha verimli ve güvenilir hale getirebilirsiniz.

Bağımlıklıkların Tanımlanması

Bu projemizde pom.xml dosyamız işe şu şekilde olacak:

<?xml version="1.0" encoding="UTF-8"?>
<project 
    xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
        <relativePath/>
    </parent>
    <groupId>com.codingbytime</groupId>
    <artifactId>rabbitmq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>rabbitmq</name>
    <description>RabbitMQ Broker</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

RabbitMQ için Konfigürasyonların Ayarlanması

RabbitMqConfig isminde bir java sınıfı oluşturalım ve bu config isimli package’ın altında bulunsun. Sınıfımızın Spring context’inde tanımlanması için @Configuration notasyonumuzu verelim. Burada tanımlamamız gereken 3 adet @Bean bulunmakta bunlardan ilki kuyruğumuzu tanımlayacağımız Queue, ikincisi Exchange sonuncusu ise Binding. Sırasıyla tanımlamalar bu şekilde;

package com.codingbytime.rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfig {
    static String exchangeName = "CodingInTime-Exchange";
    static String queueName = "CodingInTime-Queue";

    @Bean
    Queue queue() {
        return new Queue(queueName, false);
    }

    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange(exchangeName);
    }

    @Bean
    Binding binding(Queue queue, FanoutExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange);
    }
}

Gelen mesajları dinlemesi için listener package’ı altında QueueListener adında bir java sınıfı oluşturalım. Spring context’inde tanımlanması için @Service notasyonunu verelim. Kuyruğumuzu dinleyecek metodumuzu da @RabbitListener notasyonu ile işaretlememiz gerekiyor. Alacağı parametre ise kuyruğumuzun ismi olmalı.

package com.codingbytime.rabbitmq.listener;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

@Service
public class QueueListener {

    @RabbitListener(queues = "CodingInTime-Queue")
    public void handleMessage(String notification) {
        System.out.println("Kuyruktan Gelen Mesaj:" + notification);
    }
}

Şimdi de bizim için her 5 saniyede bir defa kuyruğa mesaj yollayacak bir CommandLineRunner yazalım. Runner isminde bir java sınıfımızı producer package’ı altında oluşturalım. Burada yeni bir Thread içerisinde sonsuz döngü açarak sürekli mesaj gönderilmesini sağladık. Sınıfımızıda @Component olarak işaretledik.

İlgini çekebilir:  Functional Interface Nedir?

 

package com.codingbytime.rabbitmq.producer;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class Runner implements CommandLineRunner {

    static String exchangeName = "CodingInTime-Exchange";
    static String routingName = "CodingInTime-Routing";

    private final RabbitTemplate rabbitTemplate;

    public Runner(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    @Override
    public void run(String... args) throws Exception {
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(5000);
                    rabbitTemplate.convertAndSend(exchangeName, routingName, "\nMerhaba RabbitMQ! Tarih : " + new Date());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

 

Son olarak main metodumuzu tanımlayalım.

package com.codingbytime.rabbitmq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class RabbitMqApplication {

    public static void main(String[] args) {
        SpringApplication.run(RabbitMqApplication.class, args);
    }
}

RabbitMQ’yu Docker Kullanarak Kuralım

Her şeyi tamamladık ancak ortada bağlanacağımız bir RabbitMQ yok. Şimdi kurulumu tek bir satır kod ile yapacağız. Ancak bunu kullanabilmeniz için sisteminize uygun olan docker engine’i https://docs.docker.com/get-docker/ buradan indirmeniz ve kurmanız lazım. Daha sonrasında bu kodu çalıştıralım:

 

docker run -d --name codingbytime-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:management

-d parametresi detach olarak arka planda çalışmasını sağlayacak

-p ile port tanımlamalarını

–name ile container’ımıza isim verdik.

 

Şimdi ise bu komut ile container’ımızın çalıştığını görelim.

docker ps

 

Çıktımız ise şu şekilde olmalı: (Port kısmını bayağı küçülttüm ve STATUS, CREATED ve COMMAND kısımlarını buradan kaldırdım)

CONTAINER ID IMAGE               PORTS                    NAMES
b9411c8dc977 rabbitmq:management 5672, 15672 codingbytime-rabbit

Uygulamamızı Çalıştıralım

Eğer windows kullanıyorsanız baştaki “./” ifadesini silmelisiniz.

./mvnw spring-boot:run

Sonuç

More Reading

Post navigation