RabbitMQ er en stor distribuert melding megler, men ikke så lett å administrere programmatisk. I denne veiledningen vil jeg vise deg hvordan du lager en klynge, legger til noder, fjern nodene, start og stopp. Som en bonus vil jeg dele en stofffil som lar deg ta full kontroll. Koden er tilgjengelig på GitHub.
RabbitMQ er en veldig populær meldingskø. Du kan få flere produsenter til å sende meldinger, og forbrukerne kan forbruke disse meldingene på en helt koblet måte. RabbitMQ er veldig populært av flere grunner:
RabbitMQ er implementert i Erlang, noe som er litt uvanlig, men en av grunnene til at den er så pålitelig.
I denne veiledningen vil jeg bruke en lokal Vagrant-klynge med tre noder. Hvis du allerede har tre tilgjengelige maskiner (virtuelle eller ikke), kan du bruke dem i stedet. Vær oppmerksom på porter og nettverk.
Følg instruksjonene for å installere VirtualBox.
Følg instruksjonene for å installere Vagrant
Her er en Vagrantfile som vil skape en lokal tre-node-klynge på maskinen din. OS er Ubuntu 14.04 (Trusty).
rubin # - * - modus: ruby - * - # vi: set ft = ruby: hosts = "rabbit-1" => "192.168.77.10", "kanin-2" => "192.168.77.11", "kanin -3 "=>" 192.168.77.12 " Vagrant.configure (" 2 ") do | config | config.vm.box = "trusty64" hostss.each_with_index do | (navn, ip), i | rmq_port = 5672 + jeg admin_port = 15672 + jeg config.vm.define navn gjør | maskin | machine.vm.network: private_network, ip: ip config.vm.hostname = "rabbit-% d"% [i + 1] config.vm.network: forwarded_port, gjest: 5672, guest_ip: ip, vert: rmq_port config. vm.network: forwarded_port, gjest: 15672, guest_ip: ip, vert: admin_port machine.vm.provider "virtualbox" do | v | v.name = navn sluttendens ende ende
For å opprette en tom klynge, skriv inn: vagrant opp
.
For å gjøre det enkelt å ssh inn i klusternoder, skriv: vagrant ssh-config >> ~ / .ssh / config
.
Hvis du skriver inn: katt ~ / .ssh / config
, Du bør se oppføringer for kanin-1, kanin-2 og kanin-3.
Nå kan du ssh til hver virtuell maskin ved navn: ssh kanin-1
.
Den enkleste måten er å redigere filen / etc / hosts. For eksempel, for kanin-1 legger du til adressene til kanin-2 og kanin-3.
vanlig 192.168.77.11 kanin-2 192.168.77.12 kanin-3
Gjenta prosessen for alle noder.
Jeg vil bruke apt-get her for Debian / Ubuntu operativsystemer. Hvis klyngen din kjører på et annet operativsystem, følger du instruksjonene på installasjonssiden for RabbitMQ.
Merk at noen ganger er en ganske utdatert versjon av RabbitMQ tilgjengelig som standard. Hvis du vil installere det nyeste og beste, kan du laste ned en .deb-pakke direkte eller legge til RabbitMQs apt-repository ved å bruke disse instruksjonene.
Den nåværende versjonen av RabbitMQ på Ubuntu 14.04 er 3,2, som er god nok til våre formål. Bekreft selv ved å skrive: apt-cache show rabbitmq-server
.
La oss gå videre og installere det på hver maskin:
vanlig sudo apt-get oppdatering sudo apt-get install rabbitmq-server -y
Du er velkommen til å bruke ditt favorittkonfigurasjonshåndteringsverktøy som kokk eller ansatt hvis du foretrekker det.
Merk at Erlang vil bli installert først som en forutsetning.
Administrasjonspluggen er veldig kul. Den gir deg en HTTP-basert API, samt en web GUI og et kommandolinjeverktøy for å administrere klyngen. Slik aktiverer du det:
Vanlige sudo rabbitmq-plugins aktiverer rabbitmq_management
Last ned den fra http://192.168.77.10:15672/cli/rabbitmqadmin. Merk at RabbitMQ dokumentasjonen er feil og forteller deg å laste ned fra http: //
Dette er en Python-basert HTTP-klient for RabbitMQ-styrings HTTP API. Det er veldig praktisk for scripting RabbitMQ clusters.
RabbitMQ implementerer AMQP 0.9.1-standarden (Advanced Message Queue Protocol). Merk at det allerede er en AMQP 1.0-standard, og RabbitMQ har et plugin for å støtte det, men det regnes som en prototype på grunn av utilstrekkelig bruk i virkeligheten..
I AMQP-modellen sender utgivere meldinger til en meldingsmegler (RabbitMQ er meldingsmegleren i dette tilfellet) via en utveksling. Meldingsmegleren distribuerer meldingene til køer basert på metadata knyttet til meldingen. Forbrukerne forbruker meldinger fra køer. Meldinger kan eller ikke er godkjent. RabbitMQ støtter en rekke programmeringsmodeller på toppen av disse konseptene som arbeidsøer, publiser-abonnere og RPC.
Det er tre skript som brukes til å administrere klyngen. Kaninmq-server-skriptet starter en RabbitMQ-server (start den). Kaninmqctl brukes til å styre klyngen (stopp, reset, klusternoder sammen og få status). Kaninmqadmin, som du lastet ned tidligere, brukes til å konfigurere og administrere klassen (erklære vhosts, brukere, utvekslinger og køer). Opprette en klynge innebærer bare rabbitmq-server og rabbitmqctl.
Først, la oss starte rabbitmq-serveren som en tjeneste (demon) på hver av våre vertene kanin-1, kanin-2 og kanin-3.
vanlig sudo service rabbitmq-server start
Dette vil starte både Erlang VM og RabbitMQ programmet hvis noden er nede. For å bekrefte at den kjører riktig, skriv inn:
vanlig sudo rabbitmqctl cluster_status
Utgangen skal være (for kanin-1):
vanlig kluster status av node 'kanin @ kanin-1' ... [noder, [plate, ['kanin @ rabbit-1']], running_nodes, ['kanin @ rabbit-1'], partisjoner , []] Ferdig.
Dette betyr at noden ikke er klynget med noen andre noder ennå, og det er en plate node. Den kjører også som du kan se at den vises i listen running_nodes.
For å stoppe serveren, utsted følgende kommando:
vanlig sudo rabbitmqctl stop_app
Så hvis du sjekker klyngestatusen:
vanlig sudo rabbitmqctl cluster_status
Utgangen skal være:
vanlig klusterstatus av node 'kanin @ kanin-1' ... [noder, [plate, ['kanin @ kanin-1']]] ferdig.
Ingen flere løpende noder.
Du kan gjenta prosessen for de andre noder (kanin-2 og kanin-3) og se at de kun kjenner seg selv.
Før du kan opprette en klynge, må alle noder i klyngen ha samme informasjonskapsel. Cookien er en fil som Erlang-kjøretiden bruker til å identifisere noder. Den ligger i /var/lib/rabbitmq/.erlang.cookie. Bare kopier innholdet fra kanin-1 til kanin-2 og kanin-3.
Å gruppere disse separate noder i en sammenhengende klynge tar litt arbeid. Her er prosedyren:
La oss gjøre dette. ssh til kanin-2 og kjør følgende kommandoer:
ren sudo rabbitmqctl stop_app sudo rabbitmqctl tilbakestilt sudo rabbitmqctl join_cluster kanin @ kanin-1
Skriv nå: sudo rabbitmqctl cluster_status
.
Utgangen skal være:
«Klar klusterstatus av node» kanin @ kanin-2 '... [noder, [plate, [' kanin @ kanin-1 ',' kanin @ kanin-2 ']] ... Ferdig. Som du kan se begge noder er nå gruppert. Hvis du gjentar dette på kanin-1, får du følgende utgang:
Klientstatus for node 'kanin @ kanin-1' ... [noder, [disk, ['kanin @ kanin-1', 'kanin @ kanin-2']], running_nodes, ['kanin @ kanin- 1 '], partisjoner, []] ferdig. "
Nå kan du starte kanin-2.
vanlig sudo rabbitmqctl start_app
Hvis du sjekker statusen igjen, kjøres begge noder:
vanlig klusterstatus av node 'kanin @ kanin-2' ... [noder, [plate, ['kanin @ kanin-1', 'kanin @ kanin-2']], running_nodes, ['kanin @ kanin -1 ',' kanin @ kanin-2 '], partisjoner, []] ferdig.
Merk at begge noder er disknoter, noe som betyr at de lagrer metadata på disken. La oss legge til kanin-3 som en RAM-node. ssh til kanin-3 og utsted følgende kommandoer:
ren sudo rabbitmqctl stop_app sudo rabbitmqctl tilbakestilt sudo rabbitmqctl join_cluster --ram kanin @ kanin-2 sudo rabbitmqctl start_app
Kontrollerer statusen viser:
vanlig kluster status av node 'kanin @ rabbit-3' ... [noder, [plate, ['kanin @ kanin-2', 'kanin @ kanin-1'], ram, ['kanin @ kanin-3 ']], running_nodes, [' kanin @ kanin-1 ',' kanin @ kanin-2 ',' kanin @ rabbit-3 '], partisjoner, []].
Alle klusternoder kjører. Disc noder er kanin-1 og kanin-2, og RAM-noden er kanin-3.
Gratulerer! Du har en fungerende RabbitMQ klynge.
Hva skjer hvis du vil endre klyngekonfigurasjonen din? Du må bruke kirurgisk presisjon når du legger til og fjerner noder fra klyngen.
Hva skjer hvis en nod ikke starter på nytt ennå, men du prøver å fortsette stop_app
, tilbakestille
og start_app
? Vel, stop_app-kommandoen lykkes tilsynelatende og returnerer "ferdig." Selv om målkoden er nede. Den neste kommandoen for tilbakestilling vil imidlertid mislykkes med en ekkel melding. Jeg brukte mye tid på å skrape hodet mitt og prøvde å finne ut det, fordi jeg antok at problemet var noe konfigurasjonsalternativ som bare berørte reset.
En annen gotcha er at hvis du vil nullstille den siste disknoden, må du bruke force_reset
. Forsøk å finne ut i det generelle tilfellet hvilken node var den siste disknoden, er ikke trivial.
RabbitMQ støtter også gruppering via konfigurasjonsfiler. Dette er flott når disknodene dine er oppe, fordi omstartede RAM-noder vil bare klynge basert på config-filen uten at du må koble dem eksplisitt. Igjen, det flyr ikke når du prøver å gjenopprette en ødelagt klynge.
Det kommer ned til dette: Du vet ikke hvilken som var den siste disknoden å gå ned. Du kjenner ikke klyngemetadataene til hver knutepunkt (kanskje det gikk ned mens du tilbakestilt). For å starte alle noder bruker jeg følgende algoritme:
Denne algoritmen vil fungere så lenge den siste disknoden din er fysisk OK.
Når alle klyngenoder er opp, kan du konfigurere dem igjen (husk at du ikke er sikker på hva som er klyngemetadataene til hver knute). Nøkkelen er å force_reset hver node. Dette sikrer at ethvert spor av tidligere klyngekonfigurasjon slettes fra alle noder. Først gjør du det for en plateknute:
vanlig stop_app force_reset start_app
Deretter for hver annen knute (enten disk eller RAM):
vanlig stop_app force_reset join_cluster [liste over disknoder] start_app
Du kan SSH i hver boks og utføre ovennevnte trinn på hver boks manuelt. Det fungerer, men det blir gammelt veldig fort. Det er også upraktisk om du vil bygge og rive ned en klynge som en del av en automatisert test.
En løsning er å bruke Fabric. En alvorlig gotcha jeg kjørte inn er at når jeg utførte byggeklustalgoritmen manuelt, virket det perfekt, men da jeg brukte Fabric, mislyktes det mystisk. Etter litt feilsøking la jeg merke til at nodene startet vellykket, men da jeg prøvde å stoppe, var nodene nede. Dette viste seg å være en Fabric nybegynner feil fra min side. Når du utsteder en ekstern kommando ved hjelp av Fabric, starter det et nytt skall på den eksterne maskinen. Når kommandoen er ferdig, er skallet lukket, og sender et SIGHUP (Hang-up-signal) til alle sine delprosesser, inkludert Erlang-noden. Bruke nohup tar vare på det. Et annet robuste alternativ er å kjøre RabbitMQ som en tjeneste (daemon).
Administrasjon betyr å skape virtuelle verter, brukere, utvekslinger og køer, innstillingsrettigheter og bindende køer til utveksling. Det første du bør gjøre hvis du ikke allerede har installert administrasjonspluggene. Jeg er ikke sikker på hvorfor du må aktivere det selv. Den skal være aktivert som standard.
Internett-brukergrensesnittet er fantastisk, og du bør definitivt gjøre deg kjent med det. Men for å administrere en klynge eksternt, finnes det en RESTful administrasjons-API du kan bruke. Det er også et Python kommandolinjeverktøy kalt rabbitmqadmin som krever Python 2.6+. Det er ganske enkelt å bruke rabbitmqadmin. Det eneste problemet jeg fant var at jeg bare kunne bruke standard gjestekontoen for å administrere klyngen. Jeg opprettet en annen administratorbruker som ble kalt "admin", satt sine tillatelser til alle (konfigurere / lese / skrive) og ga det en merket av "administrator" (tilleggskrav til administrasjons-API), men jeg fortsatte å få tillatelsesfeil.
Elmer-prosjektet lar deg spesifisere en klyngekonfigurasjon som en Python datastruktur (se sample_config.py) og vil sette opp alt for deg.