RabbitMQ-meldinger og asynkrone systemer · leksjon

Topic-exchange for fleksibel ruting

Bli fortrolig med Topic-exchange for komplekse rutemønstre ved hjelp av jokertegn. Utform fleksible og skalerbare topologier for meldingsruting.

Leksjon 3 av 411 trinn

Topic-exchange for fleksibel ruting er en gratis leksjon i RabbitMQ-meldinger og asynkrone systemer på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i RabbitMQ-meldinger og asynkrone systemer, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i RabbitMQ-meldinger og asynkrone systemer inneholder totalt 4 leksjoner.

Topic Exchange: Fleksibel ruting

Velkommen til Topic Exchange! Denne exchangetypen tilbyr den mest fleksible meldingsrutingen og lar Dem sende meldinger til køer basert på komplekse mønstre.

I motsetning til den enkle Fanout- eller den direkte samsvarende Direct exchange-en bruker Topic exchanges spesielle jokertegn i rutingsnøkler for å samsvare dynamisk med meldinger.

Forstå Topic-rutingsnøkler

Med en Topic exchange må rutingsnøkler ikke samsvare nøyaktig. De er strenger som består av ord adskilt med punktum (.), omtrent som deler av et filnavn eller en URL.

  • Eksempel: animal.rabbit.fast
  • Eksempel: log.error.database

Hvert ord angir et detaljnivå og muliggjør hierarkisk ruting.

Jokertegnet for ett ord: `*`

Jokertegnet asterisk (*) samsvarer med nøyaktig ett ord i en del av rutingsnøkkelen.

  • Bindingsnøkkelen animal.*.fast samsvarer med animal.rabbit.fast
  • Bindingsnøkkelen animal.*.fast samsvarer ikke med animal.dog.lazy.fast (for mange ord)
  • Bindingsnøkkelen *.error.* samsvarer med log.error.database

Dette er nyttig når De vil samsvare med en bestemt posisjon i nøkkelen.

Jokertegnet for null eller flere ord: `#`

Jokertegnet hash (#) samsvarer med null eller flere ord i en rutingsnøkkel. Det er langt kraftigere enn *.

  • Bindingsnøkkelen log.# samsvarer med log.error, log.info.web og log.debug.cache.entry
  • Bindingsnøkkelen animal.# samsvarer med animal.rabbit og animal.cat.sleepy

Bruk # for å fange opp alle meldinger som starter med et bestemt mønster.

Produsent: Deklarere Topic Exchange

Først må produsenten vår deklarere Topic exchange-en. Typen er ganske enkelt "topic".

Prøv å kjøre dette kodeeksempelet for å sette opp exchange-en:

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class TopicProducerSetup {
    private static final String EXCHANGE_NAME = "topic_logs";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost"); // Connect to local RabbitMQ
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {

            channel.exchangeDeclare(EXCHANGE_NAME, "topic");
            System.out.println("Topic exchange '" + EXCHANGE_NAME + "' declared.");
        }
    }
}

Produsent: Sende meldinger

La oss nå sende noen meldinger med ulike rutingsnøkler. Exchange-en bruker disse nøklene til å avgjøre hvilke køer som skal motta meldingene.

Legg merke til at nøklene er adskilt med punktum, slik at de kan angi detaljerte kategorier.

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.nio.charset.StandardCharsets;

public class TopicMessageSender {
    private static final String EXCHANGE_NAME = "topic_logs";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {

            channel.exchangeDeclare(EXCHANGE_NAME, "topic");

            sendMessage(channel, "animal.rabbit.fast", "A fast rabbit runs.");
            sendMessage(channel, "animal.cat.sleepy", "A sleepy cat naps.");
            sendMessage(channel, "log.error.db", "Database connection failed!");
            sendMessage(channel, "log.info.web", "User logged in.");

            System.out.println("Sent various topic messages.");
        }
    }

    private static void sendMessage(Channel channel, String routingKey, String message) throws Exception {
        channel.basicPublish(EXCHANGE_NAME, routingKey, null, message.getBytes(StandardCharsets.UTF_8));
        System.out.println(" [x] Sent '" + routingKey + ":'" + message + "'");
    }
}

Consumer: Binding med `*`

Consumere binder køene sine til Topic exchange-en ved hjelp av bindingsnøkler som kan inneholde jokertegn. Denne consumeren bruker *.orange.*.

Den mottar meldinger som animal.orange.fast, men ikke fruit.apple.sweet eller animal.orange.

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

public class TopicConsumerOrange {
    private static final String EXCHANGE_NAME = "topic_logs";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        String queueName = channel.queueDeclare().getQueue();

        String bindingKey = "*.orange.*"; // Matches e.g., 'animal.orange.fast'
        channel.queueBind(queueName, EXCHANGE_NAME, bindingKey);
        System.out.println(" [x] Waiting for messages matching: '" + bindingKey + "'");

        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println(" [x] Received '" + delivery.getEnvelope().getRoutingKey() + ":'" + message + "'");
        };
        channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});
    }
}

Consumer: Binding med `#`

Denne consumeren bruker bindingsnøkkelen log.#. Det betyr at den mottar alle meldinger der rutingsnøkkelen starter med log., uavhengig av hvor mange ord som følger etter.

Dette er svært nyttig i systemer som logging, der De kanskje ønsker en lytter som fanger opp alt innenfor en kategori.

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

public class TopicConsumerLogs {
    private static final String EXCHANGE_NAME = "topic_logs";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
        String queueName = channel.queueDeclare().getQueue();

        String bindingKey = "log.#"; // Matches e.g., 'log.error.db', 'log.info.web'
        channel.queueBind(queueName, EXCHANGE_NAME, bindingKey);
        System.out.println(" [x] Waiting for messages matching: '" + bindingKey + "'");

        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println(" [x] Received '" + delivery.getEnvelope().getRoutingKey() + ":'" + message + "'");
        };
        channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});
    }
}

Bruksområder for Topic Exchange

Topic exchanges utmerker seg i scenarioer som krever fleksibel og hierarkisk ruting:

  • Loggingssystemer: Rut logger basert på alvorlighetsgrad, kilde og komponent (for eksempel app.error.auth og app.info.payment).
  • Datastrømmer i sanntid: Filtrer sensordata (for eksempel sensor.room1.temp og sensor.room2.humidity).
  • Innholdsdistribusjon: Lever nyhetsartikler til abonnenter som er interessert i bestemte kategorier eller regioner.

De gir detaljert kontroll over meldingsflyten.

Utfordring i Topic-ruting

Se på følgende meldinger og bindingsnøkler. Hvilke meldinger blir levert til en kø som er bundet med nøkkelen animal.*.#.fast?

Oppsummering: Kraften i Topic Exchange

De har fått god oversikt over Topic exchange! Det er et svært kraftig verktøy for å bygge fleksible og skalerbare meldingsarkitekturer.

  • Bruker rutingsnøkler som er adskilt med punktum.
  • * samsvarer med nøyaktig ett ord.
  • # samsvarer med null eller flere ord.
  • Egner seg godt til logging, sanntidsanalyse og innholdsfiltrering.

Ved å bruke jokertegn kan De opprette avanserte rutingsregler som sørger for at meldingene havner akkurat der de trengs.

Gratis å komme i gang

Lær deg RabbitMQ-meldinger og asynkrone systemer med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
11
Leksjoner
44

Ofte stilte spørsmål

Er leksjonen «Topic-exchange for fleksibel ruting» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien RabbitMQ-meldinger og asynkrone systemer, inkludert «Topic-exchange for fleksibel ruting», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i RabbitMQ-meldinger og asynkrone systemer inneholder totalt 4 leksjoner.

Hva lærer jeg i «Topic-exchange for fleksibel ruting»?

Bli fortrolig med Topic-exchange for komplekse rutemønstre ved hjelp av jokertegn. Utform fleksible og skalerbare topologier for meldingsruting. Du øver på RabbitMQ-meldinger og asynkrone systemer med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med RabbitMQ-meldinger og asynkrone systemer?

Ingen tidligere erfaring er nødvendig. RabbitMQ-meldinger og asynkrone systemer på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Topic-exchange for fleksibel ruting»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne RabbitMQ-meldinger og asynkrone systemer-leksjonen?

Ja. Alle RabbitMQ-meldinger og asynkrone systemer-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Fanout-exchange for Pub/Sub
  2. Direct-exchange for ruting
  3. Topic-exchange for fleksibel ruting
  4. Standardexchange og implisitte bindinger
← Tilbake til RabbitMQ-meldinger og asynkrone systemer