Parenteser

Betraktninger fra Mat-teamets grønne enger

PubSub med NATS

NATS er et meldingssystem med så mange bruksmønstre at det kan fremstå som litt overveldende. Vi snakker om et system som alene kan erstatte både Redis, RabbitMQ og Kafka. Heldigvis er NATS elegant designet rundt primitiven emnebasert meldingsutveksling (“subject-based messaging”), og med en god forståelse av hva det innebærer kan vi lett forstå hvordan alt henger sammen.

Hei på deg med NATS

La oss starte med et eksempel. Det er fort gjort å installere NATS: du trenger bare å laste ned den frittstående kjørbare fila og starte den. På OSX kan du slippe unna med brew install nats-server for serveren, og brew tap nats-io/nats-tools og så brew install nats-io/nats-tools/nats for CLI-et.

For å starte serveren åpner du en terminal og skriver:

nats-server

For å få meldinger i PubSub må du aktivt lytte etter meldinger i det øyeblikket de blir sendt – meldingene blir ikke persistert på serveren. Vi må derfor starte med å lytte etter meldinger:

nats subscribe chat.general

Dette setter opp en abonnent som lytter på meldinger på emnet chat.general. Vi kan publisere dit fra en annen terminal:

nats publish chat.general "Hei, verden!"

Den første terminalen din vil nå få meldingen:

$ nats subscribe chat.general
13:37:58 Subscribing on chat.general
[#1] Received on "chat.general"
Hei, verden

PubSub er mange-til-mange. Med andre ord kan du både publisere til emnet fra vilkårlig mange steder, og lytte så mange ganger du vil. Alle som lytter får alle meldingene.

Meldingene trenger ikke å være tekst som i disse eksemplene. Under panseret er meldingene rå bytes, så du kan i prinsippet sende hva som helst. Som JSON, EDN eller protobuf.

Emnebasert meldingsutveksling

Når du bruker NATS kan du bygge integrasjoner mellom systemer over emner, ala chat.general over. Så heller enn å snakke om hvor forskjellige systemer bor, og så gjøre REST-kall eller lignende til dem, så kan du bruke NATS som en informasjonshub der du heller snakker om hvilke emner som interesserer deg. Det er en mer dataorientert tilnærming til integrasjon.

For å understøtte slik kommunikasjon har NATS noen verktøy for å jobbe med emner. Spesifikt skiller punktumet tokens fra hverandre, slik at et emne representerer et hierarki. Du kan bruke * som wildcard for ett token, og > som et wildcard for “alle nivåer herfra og ut”. La oss belyse med et eksempel.

I det første eksempelet delte vi chat-meldinger. La oss raffinere eksempelet ved å publisere alle meldinger til et emne chat.<kanal>.<bruker>. Alle meldingene bærer med seg informasjon om hvilket emne de ble publisert til, så selv med kun tekst som meldings-body vil dette gi oss mer informasjon.

Vi kan nå lytte til alle meldinger på en kanal på følgende vis:

nats subscribe chat.general.*

Dette gir oss alle meldinger under topp-emnet chat.general. Ved å publisere meldinger på emner som chat.general.christian og chat.general.magnar kan vi observere følgende meldingsutveksling:

$ nats subscribe 'chat.general.*'
14:19:23 Subscribing on chat.general.*
[#1] Received on "chat.general.christian"
God morgen

[#2] Received on "chat.general.magnar"
Halla

[#3] Received on "chat.general.christian"
Hva skal vi gjøre i dag?

[#4] Received on "chat.general.magnar"
Skrive litt Clojure?

For å lytte på alle meldinger på alle kanaler kan vi bruke stjernen også for kanal, altså nats subscribe 'chat.*.*' – eller bruke nats subscribe 'chat.>', som oppnår det samme, men for et vilkårlig antall nivåer.

Stjernen kan brukes til å “wildcarde” et hvilket som helst nivå. Dette vil eksempelvis gi meg alle meldingene til Magnar, uavhengig av kanal:

$ nats subscribe 'chat.*.magnar'
14:25:04 Subscribing on chat.*.magnar
[#1] Received on "chat.general.magnar"
Halla

[#2] Received on "chat.general.magnar"
Skrive litt Clojure?

[#3] Received on "chat.team-mat.magnar"
Jeg og Christian setter oss og skriver litt Clojure

Det er verdt å merke seg at filtreringen av meldinger skjer på NATS-serveren – ikke på klienten. Med andre ord gir NATS deg stor frihet til å fordele arbeid/interesse mellom klienter med lav kostnad på klientsiden.

I senere innlegg skal vi se hvilke spennende muligheter som dukker opp når vi legger persistens på denne modellen.

Christian

Om NATS

Nyttig å vite om NATS er en serie med bloggposter om det distribuerte meldingssystemet NATS. Lyst til å lese videre? Her er det neste innlegget i serien:

NATS JetStream: Persistente køer og logger

JetStream er en bryter som gir NATS persistens. Det åpner opp for en haug med spennende bruksmønstre, så som distribuert arbeidskø (tenk RabbitMQ med flere) og strømming av persistente logger (tenk Kafka). Vi ser på hvordan det funker.