Gestionarea clusterului RabbitMQ

RabbitMQ este un broker de mesaje distribuit excelent, dar nu atât de ușor de administrat în mod programatic. În acest tutorial vă voi arăta cum să creați un cluster, să adăugați noduri, să eliminați nodurile, să începeți și să opriți. Ca bonus, voi distribui un fișier Fabric care vă va permite să vă controlați total. Codul este disponibil pe GitHub.

Introducere rapidă la RabbitMQ

RabbitMQ este o coadă de mesaje foarte populară. Puteți avea mai mulți producători care trimit mesaje și consumatorii pot consuma aceste mesaje într-un mod complet decuplat. RabbitMQ este foarte popular din mai multe motive:

  1. Este rapid și robust.
  2. Este o sursă deschisă, dar există suport comercial dacă doriți.
  3. Se execută pe sistemul dvs. de operare.
  4. Este dezvoltat activ.
  5. Este testat lupta.

RabbitMQ este implementat în Erlang, ceea ce este un pic neobișnuit, dar unul dintre motivele pentru care este atât de fiabil.

Cerințe preliminare

În scopul acestui tutorial voi folosi un cluster Vagrant local de trei noduri. Dacă aveți deja trei mașini disponibile (virtuale sau nu), le puteți utiliza în schimb. Acordați atenție porturilor și rețelelor.

Instalați VirtualBox

Urmați instrucțiunile pentru a instala VirtualBox.

Instalați vagabondul

Urmați instrucțiunile pentru a instala Vagrant

Creați un cluster RabbitMQ

Aici este un Vagrantfile care va crea un cluster local cu trei noduri pe mașina dvs. OS este Ubuntu 14.04 (Trusty).

rubin - - - - modul: ruby ​​- * - # vi: set ft = ruby: hosts = "rabbit-1" => "192.168.77.10", "rabbit-2" => "192.168.77.11" -3 "=>" 192.168.77.12 " Vagrant.configure (" 2 ") nu | config | config.vm.box = "trusty64" hosts.each_with_index nu | (nume, ip), i | rmq_port = 5672 + i admin_port = 15672 + i nume config.vm.definit | mașină | server.wm.network: private_network, ip: ip config.vm.hostname = "rabbit-% d"% [i + 1] config.vm.network: forwarded_port, oaspete: 5672, guest_ip: ip, host: rmq_port config. vm.network: forwarded_port, oaspete: 15672, guest_ip: ip, gazdă: admin_port machine.vm.provider "virtualbox" nu | v | v.name = nume sfârșit sfârșit sfârșit sfârșit

Pentru a crea un cluster gol, tastați: vagrant sus.

Configurarea SSH

Pentru a facilita ssh în nodurile de cluster, tastați: vagrantul ssh-config >> ~ / .ssh / config.

Dacă tastați: cat ~ / .ssh / config, ar trebui să vedeți intrări pentru iepure-1, iepure-2 și iepure-3.

Acum puteți ssh în fiecare mașină virtuală după nume: ssh iepure-1.

Asigurați-vă că nodurile sunt accesibile după nume

Cea mai ușoară cale este să editați fișierul / etc / hosts. De exemplu, pentru iepure-1 adăugați adresele iepure-2 și iepure-3.

simplu 192.168.77.11 iepure-2 192.168.77.12 iepure-3

Repetați procesul pentru toate nodurile.

Instalați RabbitMQ

Voi folosi apt-get aici pentru sistemele de operare Debian / Ubuntu. Dacă clusterul rulează pe un alt sistem de operare, urmați instrucțiunile de pe pagina de instalare RabbitMQ.

Rețineți că, uneori, o versiune mai degrabă depășită a RabbitMQ este disponibilă în mod implicit. Dacă doriți să instalați cel mai recent și cel mai mare, puteți să descărcați un pachet .deb direct sau să adăugați un depozit apt de la RabbitMQ, utilizând aceste instrucțiuni.

Versiunea actuală a lui RabbitMQ pe Ubuntu 14.04 este de 3.2, ceea ce este suficient de bun pentru scopurile noastre. Verificați pentru dvs. prin tastarea: apt-cache arată rabbitmq-server.

Să mergem mai departe și să o instalăm pe fiecare mașină:

simplu sudo apt-get actualizare sudo apt-get instala rabbitmq-server -y

Simțiți-vă liber să utilizați instrumentul preferat de gestionare a configurației, cum ar fi Chef sau Ansible dacă preferați.

Rețineți că Erlang va fi instalat mai întâi ca o condiție prealabilă.

Activați Pluginul de administrare RabbitMQ

Plugin-ul de gestionare este foarte cool. Acesta vă oferă un API bazat pe HTTP, precum și un GUI web și un instrument de linie de comandă pentru gestionarea clusterului. Iată cum se poate activa:

simple sudo rabbitmq-plugins permit rabbitmq_management

Obțineți Instrumentul pentru linia de comandă a managementului

Descărcați-l de la http://192.168.77.10:15672/cli/rabbitmqadmin. Rețineți că documentația RabbitMQ este incorectă și vă spune să descărcați de la http: //: 15672 / cli /.

Acesta este un client HTTP bazat pe Python pentru API-ul de administrare HTTP RabbitMQ. Este foarte convenabil pentru scrierea clusterelor RabbitMQ.

Concepte de bază RabbitMQ

RabbitMQ implementează standardul AMQP 0.9.1 (Advanced Message Queue Protocol). Rețineți că există deja un standard AMQP 1.0, iar RabbitMQ are un plugin pentru a-l susține, dar este considerat un prototip datorită utilizării insuficiente în lumea reală.

În modelul AMQP, editorii trimit mesaje către un broker de mesaje (RabbitMQ este brokerul de mesaje în acest caz) printr-un schimb. Brokerul de mesaje distribuie mesajele la cozi bazate pe metadatele asociate cu mesajul. Consumatorii consumă mesaje de la cozi. Mesajele pot sau nu să fie recunoscute. RabbitMQ suportă o varietate de modele de programare pe lângă aceste concepte, cum ar fi cozi de lucru, publicare-abonare și RPC.

Gestionarea clusterului

Există trei scripturi utilizate pentru a gestiona clusterul. Scenariul rabbitmq-server pornește un server RabbitMQ (lansați-l). Rabbitmqctl este folosit pentru a controla clusterul (oprire, resetare, noduri de cluster împreună și obținerea statutului). Rabbitmqadmin, pe care l-ați descărcat mai devreme, este folosit pentru a configura și administra clusterul (declara vhosts, utilizatori, schimburi și cozi). Crearea unui cluster implică doar rabbitmq-server și rabbitmqctl.

În primul rând, să începem serverul rabbitmq ca serviciu (daemon) pe fiecare dintre gazdele noștri iepure-1, iepure-2 și iepure-3.

serviciu simplu sudo rabbitmq-server începe

Aceasta va porni aplicația Erlang VM și RabbitMQ dacă nodul este în jos. Pentru a verifica dacă rulează corect, tastați:

simplu sudo rabbitmqctl cluster_status

Producția ar trebui să fie (pentru iepure-1):

starea Cluster statică a nodului "rabbit @ rabbit-1" ... [[noduri, [disk, ['rabbit @ rabbit-1']], running_nodes, ,[]]… Terminat.

Aceasta inseamna ca nodul nu este cluster cu nici un alt nod inca si este un nod de disc. Se execută, de asemenea, după cum puteți vedea că apare în lista run_nodes.

Pentru a opri serverul, lansați următoarea comandă:

simplu sudo rabbitmqctl stop_app

Apoi, dacă verificați starea clusterului:

simplu sudo rabbitmqctl cluster_status

Rezultatul ar trebui să fie:

stare clară a nodului "rabbit @ rabbit-1" ... [noduri, [disc, ['rabbit @ rabbit-1']].

Nu mai există noduri care rulează.

Puteți repeta procesul pentru celelalte noduri (iepure-2 și iepure-3) și vedeți că ei știu numai ei înșiși.

Cookie-ul Erlang

Înainte de a putea crea un cluster, toate nodurile din cluster trebuie să aibă același cookie. Cookie este un fișier pe care Erlang utilizează pentru a identifica nodurile. Acesta este situat în /var/lib/rabbitmq/.erlang.cookie. Trebuie doar să copiați conținutul de iepure-1 la iepure-2 și iepure-3.

Clustering Nodes Together

Pentru a grupa aceste noduri separate într-o grupare coezivă este nevoie de ceva lucru. Iată procedura:

  • Au un singur nod care rulează (de exemplu, iepure-1).
  • Opriți un alt nod (de exemplu, iepure-2).
  • Resetați nodul oprit (iepure-2).
  • Clustează celălalt nod la nodul rădăcină.
  • Porniți nodul oprit.

Să o facem. ssh în iepure-2 și executați următoarele comenzi:

simplu sudo rabbitmqctl stop_app sudo rabbitmqctl reset sudo rabbitmqctl join_cluster rabbit @ rabbit-1

Acum tastați: sudo rabbitmqctl cluster_status.

Rezultatul ar trebui să fie:

"Starea clusterului simplu al nodului" rabbit @ rabbit-2 "... [[noduri, [disc, ['rabbit @ rabbit-1', 'rabbit @ rabbit-2' ambele noduri sunt acum grupate.Dacă repetați acest lucru pe iepure-1 veți obține următorul rezultat:

Starea cluster a nodului "rabbit @ rabbit-1" ... [noduri, [disc, rabbit @ rabbit-1 ', rabbit @ 1 '], partiții, []] ... făcut. "

Acum, puteți începe iepure-2.

simplu sudo rabbitmqctl start_app

Dacă verificați din nou starea, ambele noduri se vor executa:

starea cluster a nodului "rabbit @ rabbit-2" ... [[noduri, [disc, rabbit @ rabbit-1 ', -1 ',' rabbit @ rabbit-2 '], partiții, []] terminate.

Rețineți că ambele noduri sunt noduri de disc, ceea ce înseamnă că ei stochează metadatele pe disc. Să adăugăm iepure-3 ca nod RAM. ssh la rabbit-3 și emiteți următoarele comenzi:

sudo rabbitmqctl sudo rabbitmqctl sudo rabbitmqctl sudo rabbitmqctl sudo rabbitmqctl start_app sudo rabbitmqctl join_cluster - ram rabbit @ rabbit-2

Verificarea stării arată:

starea cluster a nodului "rabbit @ rabbit-3" ... [[noduri, [disc, ['iepure @ rabbit-2', rabbit @ '], run_nodes, [' rabbit @ rabbit-1 ',' rabbit @ rabbit-2 ',' rabbit @ rabbit-3 '.

Toate nodurile de cluster sunt difuzate. Nodurile Disc sunt iepure-1 și iepure-2, iar nodul RAM este iepure-3.

Felicitări! Aveți un cluster RabbitMQ activ.

Real-World Complications

Ce se întâmplă dacă doriți să modificați configurația clusterului? Va trebui să utilizați precizia chirurgicală atunci când adăugați și eliminați noduri din cluster.

Ce se întâmplă dacă un nod nu este repornit încă, dar încercați să continuați stop_app, restabili și start_app? Păi, comanda stop_app va reuși cu repeziciune, returnând "done" chiar dacă nodul țintă este în jos. Cu toate acestea, comanda de resetare ulterioară va eșua cu un mesaj urât. Am petrecut mult timp scarpindu-mi capul incercand sa-mi dau seama, pentru ca am presupus ca problema a fost o optiune de configurare care a afectat doar resetarea.

Un alt motiv este că, dacă doriți să resetați ultimul nod de disc, trebuie să îl utilizați force_reset. Încercarea de a înțelege în cazul general care nod a fost ultimul nod de disc nu este banal.

RabbitMQ acceptă, de asemenea, gruparea prin fișierele de configurare. Acest lucru este grozav atunci când nodurile discului sunt sus, deoarece nodurile RAM reînnoite se vor clustera numai pe baza fișierului config, fără a trebui să le clustezi în mod explicit. Din nou, nu zboară când încerci să recuperezi un grup rupt.

Făcând clustering RabbitMQ fiabil

Se pune problema: nu știți care a fost ultimul nod de disc pentru a merge în jos. Nu cunoașteți metadatele de grupare ale fiecărui nod (poate că a scăzut în timp ce efectuați resetarea). Pentru a porni toate nodurile, folosesc următorul algoritm:

  • Porniți toate nodurile (cel puțin ultimul nod de disc ar trebui să poată porni).
  • Dacă nu poate începe nici un singur nod, sunteți găzduit. Doar salvați-vă.
  • Urmăriți toate nodurile care nu au reușit să pornească.
  • Încercați să porniți toate nodurile nereușite.
  • Dacă unele noduri nu au reușit să pornească a doua oară, sunteți găzduit. Doar salvați-vă.

Acest algoritm va funcționa atâta timp cât ultimul dvs. nod de disc este fizic OK.

Odată ce toate nodurile de cluster sunt în sus, le puteți reconfigura (amintiți-vă că nu sunteți sigur care sunt metadatele de clustere pentru fiecare nod). Cheia este de a forța_reset fiecare nodul. Acest lucru asigură că orice urmă de configurație cluster anterioară este șters de la toate nodurile. Mai intai o faci pentru un nod de disc:

simplu stop_app force_reset start_app

Apoi pentru fiecare alt nod (fie disc, fie RAM):

simplu stop_app force_reset join_cluster [listă de noduri de disc] start_app

Controlul unui cluster de la distanță

Puteți să faceți SSH în fiecare cutie și să efectuați manual pașii menționați mai sus pe fiecare casetă. Asta merge, dar devine foarte vechi. De asemenea, este impracticabil dacă doriți să construiți și să rupeți un cluster ca parte a unui test automatizat.

O soluție este de a folosi Fabric. Un gust grave pe care l-am întâlnit este că atunci când am efectuat algoritmul de construire a clusterului manual a funcționat perfect, dar când am folosit Fabric, a eșuat în mod misterios. După o depanare am observat că nodurile au început cu succes, dar până când am încercat să stop_app, nodurile au scăzut. Acest lucru sa dovedit a fi o greșeală Fabric newbie din partea mea. Când emiteți o comandă la distanță utilizând Fabric, aceasta pornește o coajă nouă pe aparatul de la distanță. Când comanda este terminată, shell-ul este închis, trimițând un SIGHUP (semnal Hang up) la toate subprocesele sale, inclusiv nodul Erlang. Utilizarea nohup are grijă de asta. O altă opțiune mai robustă este să rulați RabbitMQ ca serviciu (daemon).

Administrarea unui cluster programabil

Administrarea înseamnă crearea de gazde virtuale, utilizatori, schimburi și cozi, setarea permisiunilor și cozi de legare la schimburi. Primul lucru pe care ar trebui să-l faceți dacă nu ați făcut-o deja este să instalați pluginurile de management. Nu sunt sigur de ce trebuie să-l activați singur. Ar trebui să fie activată implicit.

Web UI este fantastic și ar trebui să te familiarizezi cu siguranța. Cu toate acestea, pentru a gestiona un cluster de la distanță, există un API de gestionare RESTful pe care îl puteți utiliza. Există, de asemenea, un instrument de linie de comandă Python numit rabbitmqadmin care necesită Python 2.6+. Utilizarea rabbitmqadmin este destul de simplă. Singura problemă pe care am găsit-o este că aș putea folosi numai contul implicit pentru clienți pentru administrarea clusterului. Am creat un alt administrator de admin numit "admin", i-am setat permisiunile tuturor (configura / read / write) și i-am dat o etichetă de "administrator" (cerință suplimentară a API-ului de management).

Proiectul Elmer vă permite să specificați o configurație de cluster ca o structură de date Python (consultați sample_config.py) și vă va configura totul.

Puncte de preluare-acasă

  1. RabbitMQ este rece.
  2. Povestea administratorului de cluster nu este aerisită.
  3. Administrarea programatică este esențială.
  4. Fabric este un instrument minunat pentru a controla de la distanță mai multe casete Unix.
Cod