MenuBar

Kata Mutiara

"Keberhasilan merupakan tetesan dari jeri-payah perjuangan, luka, pengorbanan dan hal-hal yang mengejutkan. Kegagalan merupakan tetesan dari kemalasan, kebekuan, kelemahan, kehinaan dan kerendahan"

ANIMASI TULISAN BERJALAN

Monday, January 27, 2025

Work Queue hingga RPC: Membongkar Pola Messaging RabbitMQ dengan Contoh

 RabbitMQ: Penjelasan dan Studi Kasus Detail

RabbitMQ adalah message broker yang digunakan untuk berkomunikasi antar aplikasi melalui antrian pesan. Ia mendukung berbagai pola messaging seperti Work Queue, Publish/Subscribe, Routing, Topics, dan RPC. Berikut penjelasan detail dan studi kasus masing-masing pola:


1. Work Queue

Tujuan:

  • Membagi pekerjaan secara adil ke beberapa worker (pekerja).
  • Ideal untuk sistem yang membutuhkan load balancing.

Cara Kerja:

  1. Produser (sender) mengirimkan pesan ke antrian.
  2. Beberapa konsumer (worker) mengambil pesan dari antrian.
  3. Pesan hanya diproses oleh satu worker, memastikan tidak ada duplikasi.

Studi Kasus:

Skenario:

Sebuah sistem memproses data laporan harian, dan pekerja harus membagi tugas secara merata.

Konfigurasi:

  1. Sender: Mengirimkan pesan ke antrian task_queue.
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class TaskProducer {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendTask(String task) {
        rabbitTemplate.convertAndSend("task_queue", task);
        System.out.println("Task Sent: " + task);
    }
}
  1. Receiver (Worker): Setiap worker mendengarkan antrian yang sama dan memproses pesan.
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class TaskWorker {

    @RabbitListener(queues = "task_queue")
    public void receiveTask(String task) {
        System.out.println("Processing Task: " + task);
        // Simulate processing time
        try { Thread.sleep(1000); } catch (InterruptedException ignored) {}
        System.out.println("Task Done: " + task);
    }
}
  1. Hasil: Jika 10 tugas dikirim ke antrian, dan ada 2 worker, tugas akan dibagi rata, 5 tugas masing-masing.

2. Publish/Subscribe

Tujuan:

  • Mengirimkan pesan ke banyak konsumer melalui sebuah exchange.
  • Ideal untuk notifikasi atau broadcast.

Cara Kerja:

  1. Produser mengirim pesan ke FanoutExchange.
  2. Exchange mendistribusikan pesan ke semua antrian yang terhubung.
  3. Semua konsumer menerima pesan.

Studi Kasus:

Skenario:

Sebuah sistem pengumuman mengirimkan pesan ke semua layanan seperti email, SMS, dan notifikasi aplikasi.

Konfigurasi:

  1. Sender: Mengirimkan pesan ke exchange.
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AnnouncementSender {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendAnnouncement(String message) {
        rabbitTemplate.convertAndSend("announcement_exchange", "", message);
        System.out.println("Announcement Sent: " + message);
    }
}
  1. Receivers: Email, SMS, dan aplikasi memiliki antrian masing-masing.
@Component
public class NotificationReceiver {

    @RabbitListener(queues = "email_queue")
    public void receiveEmail(String message) {
        System.out.println("Email Notification: " + message);
    }

    @RabbitListener(queues = "sms_queue")
    public void receiveSMS(String message) {
        System.out.println("SMS Notification: " + message);
    }
}

3. Routing

Tujuan:

  • Mengirim pesan berdasarkan routing key ke antrian tertentu.
  • Ideal untuk sistem yang hanya memproses jenis pesan tertentu.

Cara Kerja:

  1. Produser mengirimkan pesan dengan routing key ke DirectExchange.
  2. Exchange meneruskan pesan ke antrian yang cocok dengan routing key.

Studi Kasus:

Skenario:

Sebuah sistem log memiliki tiga level: INFO, WARN, dan ERROR. Pesan didistribusikan ke antrian sesuai level.

Konfigurasi:

  1. Sender: Mengirim pesan log berdasarkan level.
@Component
public class LogSender {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendLog(String level, String message) {
        rabbitTemplate.convertAndSend("logs_exchange", level, message);
        System.out.println("Log Sent: [" + level + "] " + message);
    }
}
  1. Receiver: Setiap konsumer hanya menerima pesan untuk level tertentu.
@Component
public class LogReceiver {

    @RabbitListener(queues = "error_queue")
    public void receiveError(String message) {
        System.out.println("ERROR Log: " + message);
    }

    @RabbitListener(queues = "info_queue")
    public void receiveInfo(String message) {
        System.out.println("INFO Log: " + message);
    }
}

4. Topics

Tujuan:

  • Mengirim pesan berdasarkan pattern matching di routing key.
  • Ideal untuk sistem yang membutuhkan pengelompokan pesan fleksibel.

Cara Kerja:

  1. Produser mengirimkan pesan dengan routing key ke TopicExchange.
  2. Exchange meneruskan pesan ke antrian sesuai pola binding key.

Studi Kasus:

Skenario:

Sebuah sistem cuaca mengirimkan data cuaca regional. Konsumer hanya mendengarkan data untuk wilayah tertentu.

Konfigurasi:

  1. Sender: Mengirimkan data dengan routing key.
@Component
public class WeatherPublisher {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendWeatherUpdate(String region, String update) {
        String routingKey = "weather." + region;
        rabbitTemplate.convertAndSend("weather_exchange", routingKey, update);
        System.out.println("Weather Update Sent: [" + region + "] " + update);
    }
}
  1. Receiver: Menerima pesan berdasarkan wilayah.
@Component
public class WeatherReceiver {

    @RabbitListener(queues = "weather_north_queue")
    public void receiveNorthWeather(String message) {
        System.out.println("North Region Weather: " + message);
    }
}

5. RPC (Remote Procedure Call)

Tujuan:

  • Mengimplementasikan komunikasi sinkron, di mana klien menunggu respons dari server.

Cara Kerja:

  1. Klien mengirim pesan ke antrian permintaan.
  2. Server memproses pesan dan mengirim respons ke antrian balasan.
  3. Klien menerima respons.

Studi Kasus:

Skenario:

Sebuah sistem menghitung faktorial angka yang diminta oleh klien.

Konfigurasi:

  1. Client: Mengirim permintaan dan menunggu respons.
@Component
public class FactorialClient {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public int requestFactorial(int number) {
        return (Integer) rabbitTemplate.convertSendAndReceive("rpc_queue", number);
    }
}
  1. Server: Memproses permintaan dan mengirim respons.
@Component
public class FactorialServer {

    @RabbitListener(queues = "rpc_queue")
    public int calculateFactorial(int number) {
        int result = 1;
        for (int i = 1; i <= number; i++) {
            result *= i;
        }
        System.out.println("Calculated Factorial: " + result);
        return result;
    }
}

Kesimpulan:

RabbitMQ mendukung berbagai pola komunikasi yang fleksibel:

  • Work Queue: Load balancing tugas.
  • Publish/Subscribe: Broadcast pesan ke banyak konsumer.
  • Routing: Mengarahkan pesan berdasarkan kunci tertentu.
  • Topics: Pencocokan pesan fleksibel dengan pola.
  • RPC: Permintaan dan respons sinkron.

Dengan RabbitMQ, kita dapat membangun sistem terdistribusi yang efisien dan dapat diskalakan.

No comments:

Post a Comment

iklan

iklan