Uw RabbitMQ-cluster beheren

RabbitMQ is een geweldige gedistribueerde broker voor berichten, maar niet zo eenvoudig om programmatisch te beheren. In deze zelfstudie laat ik je zien hoe je een cluster maakt, knooppunten toevoegt, knooppunten verwijdert, start en stop. Als een bonus deel ik een Fabric-bestand waarmee je totale controle kunt nemen. De code is beschikbaar op GitHub.

Snelle inleiding tot RabbitMQ

RabbitMQ is een erg populaire berichtenwachtrij. U kunt ervoor zorgen dat meerdere producenten berichten verzenden en dat consumenten deze berichten volledig ontkoppeld kunnen consumeren. RabbitMQ is om verschillende redenen erg populair:

  1. Het is snel en robuust.
  2. Het is open source, maar er is commerciële ondersteuning als je het wilt.
  3. Het werkt op uw besturingssysteem.
  4. Het wordt actief ontwikkeld.
  5. Het is getest op de strijd.

RabbitMQ is geïmplementeerd in Erlang, wat een beetje ongebruikelijk is, maar een van de redenen waarom het zo betrouwbaar is.

voorwaarden

Voor deze tutorial gebruik ik een lokaal Vagrant-cluster van drie knooppunten. Als u al drie beschikbare machines hebt (virtueel of niet), kunt u ze in plaats daarvan gebruiken. Besteed aandacht aan de havens en netwerken.

Installeer VirtualBox

Volg de instructies om VirtualBox te installeren.

Installeer Vagrant

Volg de instructies om Vagrant te installeren

Maak een RabbitMQ-cluster

Hier is een Vagrantbestand dat een lokaal cluster met drie knooppunten op uw machine zal maken. Het besturingssysteem is Ubuntu 14.04 (Trusty).

ruby # - * - mode: ruby ​​- * - # vi: set ft = ruby: hosts = "rabbit-1" => "192.168.77.10", "rabbit-2" => "192.168.77.11", "rabbit -3 "=>" 192.168.77.12 " Vagrant.configure (" 2 ") do | config | config.vm.box = "trusty64" hosts.each_with_index do | (naam, ip), i | rmq_port = 5672 + i admin_port = 15672 + i config.vm.define naam do | machine | machine.vm.network: private_network, ip: ip config.vm.hostname = "konijn-% d"% [i + 1] config.vm.network: forwarded_port, gast: 5672, guest_ip: ip, host: rmq_port config. vm.network: forwarded_port, guest: 15672, guest_ip: ip, host: admin_port machine.vm.provider "virtualbox" do | v | v.name = naam end-end end end

Als u een leeg cluster wilt maken, typt u: zwervend op.

SSH configureren

Als u het gemakkelijk wilt maken om in de clusterknooppunten te sshtsen, typt u: vagrant ssh-config >> ~ / .ssh / config.

Als u typt: cat ~ / .ssh / config, u zou vermeldingen moeten zien voor konijn-1, konijn-2 en konijn-3.

Nu kunt u op naam van elke virtuele machine ssh: ssh konijn-1.

Zorg ervoor dat de knooppunten bereikbaar zijn op naam

De gemakkelijkste manier is om het bestand / etc / hosts te bewerken. Voeg bijvoorbeeld voor konijn-1 de adressen toe van konijn-2 en konijn-3.

gewoon 192.168.77.11 konijn-2 192.168.77.12 konijn-3

Herhaal het proces voor alle knooppunten.

KonijnMQ installeren

Ik zal hier apt-get gebruiken voor Debian / Ubuntu-besturingssystemen. Als uw cluster op een ander besturingssysteem wordt uitgevoerd, volgt u de instructies op de RabbitMQ-installatiepagina.

Merk op dat soms een nogal verouderde versie van RabbitMQ standaard beschikbaar is. Als je de nieuwste en beste wilt installeren, kun je een .deb-pakket rechtstreeks downloaden of RabbitMQ's apt-repository toevoegen, met behulp van deze instructies.

De huidige versie van RabbitMQ op Ubuntu 14.04 is 3.2, wat goed genoeg is voor onze doeleinden. Controleer het zelf door te typen: apt-cache show rabbitmq-server.

Laten we doorgaan en het op elke machine installeren:

eenvoudige sudo apt-get update sudo apt-get installeer konijnmq-server -y

Voel je vrij om je favoriete configuratiebeheertool zoals Chef of Ansible te gebruiken als je dat wilt.

Merk op dat Erlang eerst als een vereiste zal worden geïnstalleerd.

Schakel de RabbitMQ Management Plugin in

De management plug-in is echt gaaf. Het biedt u een op HTTP gebaseerde API en een web-GUI en een opdrachtregelprogramma om het cluster te beheren. Hier is hoe het in te schakelen:

simpele sudo rabbitmq-plug-ins maken rabbitmq_management mogelijk

Verkrijg de Management Command-Line Tool

Download het van http://192.168.77.10:15672/cli/rabbitmqadmin. Merk op dat de RabbitMQ-documentatie niet correct is en u vertelt om te downloaden van http: //: 15672 / cli /.

Dit is een op Python gebaseerde HTTP-client voor de KonijnMQ-beheer-HTTP-API. Het is erg handig voor het scripten van RabbitMQ-clusters.

Basic RabbitMQ-concepten

RabbitMQ implementeert de AMQP 0.9.1-standaard (Advanced Message Queue Protocol). Merk op dat er al een AMQP 1.0-standaard is en RabbitMQ een plug-in heeft om het te ondersteunen, maar het wordt als een prototype beschouwd vanwege onvoldoende gebruik in de praktijk.

In het AMQP-model verzenden uitgevers berichten via een centrale naar een berichtbroker (RabbitMQ is in dit geval de berichtenmakelaar). De berichtenbroker verspreidt de berichten naar wachtrijen op basis van metagegevens die aan het bericht zijn gekoppeld. Consumenten consumeren berichten uit wachtrijen. Berichten kunnen al dan niet worden bevestigd. RabbitMQ ondersteunt een verscheidenheid aan programmeermodellen bovenop deze concepten, zoals werkvoorraden, publish-subscribe en RPC.

Uw cluster beheren

Er zijn drie scripts gebruikt om het cluster te beheren. Het konijnmq-server script start een RabbitMQ-server (start het op). De rabbitmqctl wordt gebruikt om het cluster te besturen (stop, reset, clusterknooppunten samen en verkrijg status). De rabbitmqadmin, die je eerder hebt gedownload, wordt gebruikt om het cluster te configureren en te beheren (vhosts, gebruikers, uitwisselingen en wachtrijen te declareren). Het maken van een cluster omvat alleen rabbitmq-server en rabbitmqctl.

Laten we eerst de rabbitmq-server starten als een service (daemon) op elk van onze hosts konijn-1, konijn-2 en konijn-3.

eenvoudige sudo-service start van konijnmq-server

Hiermee start u zowel de Erlang VM- als de RabbitMQ-toepassing als het knooppunt niet beschikbaar is. Ga als volgt te werk om te controleren of het correct werkt:

gewoon sudo konijnmqctl cluster_status

De uitvoer zou moeten zijn (voor konijn-1):

plain Clusterstatus van knoop 'rabbit @ rabbit-1' ... [nodes, [disc, ['rabbit @ rabbit-1']], running_nodes, ['rabbit @ rabbit-1'], partitions ,[]]… gedaan.

Dit betekent dat het knooppunt nog niet is geclusterd met andere knooppunten en dat het een schijfknooppunt is. Het wordt ook uitgevoerd, zoals u kunt zien dat het in de lijst running_nodes wordt weergegeven.

Om de server te stoppen, geeft u de volgende opdracht:

gewoon sudo rabbitmqctl stop_app

Dan als u de clusterstatus controleert:

gewoon sudo konijnmqctl cluster_status

De uitvoer moet zijn:

plain Clusterstatus van knoop 'rabbit @ rabbit-1' ... [nodes, [disc, ['rabbit @ rabbit-1']]] ... klaar.

Geen draaiende knooppunten meer.

Je kunt het proces voor de andere knooppunten (konijn-2 en konijn-3) herhalen en zien dat ze alleen zichzelf kennen.

De Erlang-cookie

Voordat u een cluster kunt maken, moeten alle knooppunten in het cluster dezelfde cookie hebben. De cookie is een bestand dat door de Erlang-runtime wordt gebruikt om knooppunten te identificeren. Het bevindt zich in /var/lib/rabbitmq/.erlang.cookie. Kopieer de inhoud van konijn-1 naar konijn-2 en konijn-3.

Clusters van knooppunten samen

Het groeperen van deze afzonderlijke knooppunten in een samenhangend cluster kost wat werk. Hier is de procedure:

  • Laat een enkel knooppunt draaien (bijvoorbeeld konijn-1).
  • Stop een ander knooppunt (bijvoorbeeld konijn-2).
  • Reset het gestopte knooppunt (konijn-2).
  • Clusteer het andere knooppunt naar het basisknooppunt.
  • Start het gestopte knooppunt.

Laten we dit doen. ssh in rabbit-2 en voer de volgende opdrachten uit:

gewoon sudo konijnmqctl stop_app sudo konijnmqctl reset sudo konijnmqctl join_cluster konijn @ konijn-1

Typ nu: sudo rabbitmqctl cluster_status.

De uitvoer moet zijn:

"plain Cluster status of node 'rabbit @ rabbit-2' ... [nodes, [disc, ['rabbit @ rabbit-1', 'rabbit @ rabbit-2']]] ... Klaar Zoals je kunt zien beide knooppunten zijn nu geclusterd. Als u dit op konijn-1 herhaalt, krijgt u de volgende uitvoer:

Clusterstatus van knoop 'konijn @ konijn-1' ... [knooppunten, [schijf, ['konijn @ konijn-1', 'konijn @ konijn-2']], running_nodes, ['konijn @ konijn- 1 '], partitions, []] ... klaar. "

Nu kunt u konijn-2 starten.

gewoon sudo rabbitmqctl start_app

Als u de status opnieuw controleert, zullen beide knooppunten actief zijn:

plain Clusterstatus van knoop 'rabbit @ rabbit-2' ... [nodes, [disc, ['rabbit @ rabbit-1', 'rabbit @ rabbit-2']], running_nodes, ['rabbit @ rabbit -1 ',' rabbit @ rabbit-2 '], partitions, []] ... klaar.

Merk op dat beide knooppunten schijfknooppunten zijn, wat betekent dat ze hun metagegevens op schijf opslaan. Laten we konijn-3 toevoegen als een RAM-knooppunt. ssh naar rabbit-3 en geef de volgende opdrachten:

gewoon sudo konijnmqctl stop_app sudo konijnmqctl reset sudo konijnmqctl join_cluster --ram konijn @ konijn-2 sudo rabbitmqctl start_app

Controle van de status toont:

plain Clusterstatus van knoop 'rabbit @ rabbit-3' ... [nodes, [disc, ['rabbit @ rabbit-2', 'rabbit @ rabbit-1'], ram, ['rabbit @ rabbit-3 ']], running_nodes, [' rabbit @ rabbit-1 ',' rabbit @ rabbit-2 ',' rabbit @ rabbit-3 '], partitions, []] ... gedaan.

Alle clusterknooppunten zijn actief. De schijfknooppunten zijn konijn-1 en konijn-2 en het RAM-knooppunt is konijn-3.

Gefeliciteerd! Je hebt een werkende RabbitMQ-cluster.

Real-World Complicaties

Wat gebeurt er als u uw clusterconfiguratie wilt wijzigen? U moet chirurgische precisie gebruiken bij het toevoegen en verwijderen van knooppunten uit het cluster.

Wat gebeurt er als een knooppunt nog niet opnieuw is opgestart, maar u probeert door te gaan? stop_app, reset en start_app? Nou, het stop_app-commando zal ogenschijnlijk lukken door "done" terug te sturen, zelfs als het doelknooppunt niet beschikbaar is. De volgende resetopdracht mislukt echter met een vervelende boodschap. Ik heb veel tijd besteed aan het krabben van mijn hoofd om het uit te zoeken, omdat ik aannam dat het probleem een ​​configuratie-optie was die alleen de reset beïnvloedde.

Een andere gotcha is dat als je het laatste schijfknooppunt opnieuw wilt instellen, je dit moet gebruiken force_reset. In het algemeen proberen uit te vogelen welk knooppunt het laatste schijfknooppunt was, is niet triviaal.

RabbitMQ ondersteunt ook clustering via configuratiebestanden. Dit is geweldig wanneer uw schijfknooppunten omhoog zijn, omdat herstelde RAM-knooppunten alleen op basis van het configuratiebestand zullen clusteren zonder dat u ze expliciet hoeft te clusteren. Nogmaals, het vliegt niet wanneer u probeert een gebroken cluster te herstellen.

Betrouwbare RabbitMQ-clustering

Het komt hierop neer: u weet niet wat het laatste schijfknooppunt was om naar beneden te gaan. U kent de clusteringmetadata van elk knooppunt niet (misschien is het tijdens het resetten naar beneden gegaan). Om alle knooppunten te starten, gebruik ik het volgende algoritme:

  • Start alle knooppunten (in ieder geval moet het laatste schijfknooppunt kunnen starten).
  • Als niet eens een enkel knooppunt kan starten, wordt je afgespoten. Gewoon redden.
  • Blijf op de hoogte van alle knooppunten die niet konden starten.
  • Probeer alle mislukte knooppunten te starten.
  • Als sommige knooppunten de tweede keer niet zijn gestart, wordt je afgespoten. Gewoon redden.

Dit algoritme werkt zolang uw laatste schijfknooppunt fysiek in orde is.

Als alle clusterknooppunten op zijn, kunt u ze opnieuw configureren (onthoud dat u niet zeker weet wat de metagegevens van de clustering van elk knooppunt zijn). De sleutel is om force_reset elk knooppunt. Dit zorgt ervoor dat elk spoor van de vorige clusterconfiguratie uit alle knooppunten wordt gewist. Doe het eerst voor één schijfknooppunt:

gewoon stop_app force_reset start_app

Dan voor elk ander knooppunt (schijf of RAM):

plain stop_app force_reset join_cluster [lijst met schijfknooppunten] start_app

Een cluster op afstand besturen

Je kunt SSH gebruiken in elk vak en de bovengenoemde stappen op elk vak handmatig uitvoeren. Dat werkt, maar het wordt echt snel oud. Ook is het onpraktisch als u een cluster wilt bouwen en afbreken als onderdeel van een geautomatiseerde test.

Een oplossing is om Fabric te gebruiken. Een serieuze fout die ik tegenkwam, was dat toen ik het algoritme van het buildcluster handmatig uitvoerde het perfect werkte, maar toen ik Fabric gebruikte, mislukte het op mysterieuze wijze. Na wat foutopsporing merkte ik dat de knooppunten met succes begonnen, maar tegen de tijd dat ik probeerde te stoppen_app, waren de knooppunten naar beneden. Dit bleek een nieuwe fout van Fabric te zijn van mijn kant. Wanneer u een opdracht op afstand geeft met Fabric, wordt een nieuwe shell op de externe computer gestart. Wanneer de opdracht is voltooid, wordt de shell gesloten en wordt een SIGHUP (Hang up-signaal) verzonden naar al zijn subprocessen, inclusief het Erlang-knooppunt. Het gebruik van nohup zorgt daarvoor. Een andere meer robuuste optie is om RabbitMQ als een service (daemon) uit te voeren.

Een cluster programmatisch beheren

Beheer betekent het maken van virtuele hosts, gebruikers, uitwisselingen en wachtrijen, het instellen van machtigingen en het binden van wachtrijen aan uitwisselingen. Het eerste dat u moet doen als u dat nog niet hebt gedaan, is het installeren van de beheerplug-ins. Ik weet niet zeker waarom je het zelf moet inschakelen. Het moet standaard worden ingeschakeld.

De webinterface is fantastisch en je moet je er zeker mee vertrouwd maken. Om een ​​cluster op afstand te beheren, is er echter een RESTful management-API die u kunt gebruiken. Er is ook een opdrachtregelprogramma voor Python, rabbitmqadmin genaamd, dat Python 2.6+ vereist. Konijnmqadmin gebruiken is vrij eenvoudig. Het enige probleem dat ik heb gevonden is dat ik alleen het standaard gastaccount zou kunnen gebruiken om het cluster te beheren. Ik heb een andere administrator-gebruiker gemaakt met de naam 'admin', stel de rechten ervan in op alle (configure / read / write) en gaf het een tag van 'administrator' (extra vereiste van de management-API), maar ik kreeg steeds toestemmingsfouten.

Met het Elmer-project kunt u een clusterconfiguratie opgeven als een Python-gegevensstructuur (zie sample_config.py) en alles voor u instellen.

Take-Home Points

  1. RabbitMQ is cool.
  2. Het verhaal van de clusterbeheerder is niet luchtdicht.
  3. Programmatische administratie is de sleutel.
  4. Fabric is een geweldig hulpmiddel om meerdere Unix-boxen op afstand te bedienen.