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:
- Produser (sender) mengirimkan pesan ke antrian.
- Beberapa konsumer (worker) mengambil pesan dari antrian.
- 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:
- 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;
@Componentpublic class TaskProducer {    @Autowired    private RabbitTemplate rabbitTemplate;
    public void sendTask(String task) {        rabbitTemplate.convertAndSend("task_queue", task);        System.out.println("Task Sent: " + task);    }}- Receiver (Worker): Setiap worker mendengarkan antrian yang sama dan memproses pesan.
import org.springframework.amqp.rabbit.annotation.RabbitListener;import org.springframework.stereotype.Component;
@Componentpublic 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);    }}- 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:
- Produser mengirim pesan ke FanoutExchange.
- Exchange mendistribusikan pesan ke semua antrian yang terhubung.
- Semua konsumer menerima pesan.
Studi Kasus:
Skenario:
Sebuah sistem pengumuman mengirimkan pesan ke semua layanan seperti email, SMS, dan notifikasi aplikasi.
Konfigurasi:
- Sender: Mengirimkan pesan ke exchange.
import org.springframework.amqp.rabbit.core.RabbitTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;
@Componentpublic class AnnouncementSender {    @Autowired    private RabbitTemplate rabbitTemplate;
    public void sendAnnouncement(String message) {        rabbitTemplate.convertAndSend("announcement_exchange", "", message);        System.out.println("Announcement Sent: " + message);    }}- Receivers: Email, SMS, dan aplikasi memiliki antrian masing-masing.
@Componentpublic 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:
- Produser mengirimkan pesan dengan routing key ke DirectExchange.
- 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:
- Sender: Mengirim pesan log berdasarkan level.
@Componentpublic 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);    }}- Receiver: Setiap konsumer hanya menerima pesan untuk level tertentu.
@Componentpublic 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:
- Produser mengirimkan pesan dengan routing key ke TopicExchange.
- 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:
- Sender: Mengirimkan data dengan routing key.
@Componentpublic 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);    }}- Receiver: Menerima pesan berdasarkan wilayah.
@Componentpublic 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:
- Klien mengirim pesan ke antrian permintaan.
- Server memproses pesan dan mengirim respons ke antrian balasan.
- Klien menerima respons.
Studi Kasus:
Skenario:
Sebuah sistem menghitung faktorial angka yang diminta oleh klien.
Konfigurasi:
- Client: Mengirim permintaan dan menunggu respons.
@Componentpublic class FactorialClient {    @Autowired    private RabbitTemplate rabbitTemplate;
    public int requestFactorial(int number) {        return (Integer) rabbitTemplate.convertSendAndReceive("rpc_queue", number);    }}- Server: Memproses permintaan dan mengirim respons.
@Componentpublic 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