Mağazamızın bildiriş servisi məktublar göndərməlidir: «sifariş ödənildi», «mal göndərildi». Məktublar çoxdur, yavaş göndərilir, itirmək isə olmaz. Keçən dərsdə belə iş üçün mesaj brokerinin lazım olduğunu müəyyən etdik. Bu gün RabbitMQ-nu qaldıracaq, Node.js-də ilk göndərəni (producer) və qəbul edəni (consumer) yazacaq və worker çökəndə brokerin mesajları necə itirmədiyinə baxacağıq.

RabbitMQ nədir

RabbitMQ — açıq mənbəli ən populyar mesaj brokerlərindən biridir. O, Erlang-da yazılıb, ayrıca server kimi işləyir və tətbiqlərlə AMQP 0-9-1 protokolu ilə ünsiyyət qurur (başqa protokolları, məsələn, MQTT-ni də dəstəkləyir). Bütün populyar dillər üçün müştəri kitabxanaları var, ona görə Node.js, Python və Java-dakı servislər eyni broker vasitəsilə mesaj mübadiləsi edə bilir. Node.js-də amqplib kitabxanasından istifadə edəcəyik.

AMQP modeli: beş element

Poçtu xatırlayın: məktubu qutuya atırsınız, çeşidləmə mərkəzi onun hara gedəcəyini müəyyən edir, poçtalyon isə ünvanlıya çatdırır. AMQP-də quruluş eynidir:

  • Producer — mesajları dərc edən tətbiq.
  • Exchange — «çeşidləmə mərkəzi»: mesajı qəbul edir və onu hansı növbələrə qoyacağına qərar verir. Mesajları özü saxlamır.
  • Binding — «exchange → növbə» qaydası, bağlama açarı (binding key) ilə.
  • Queue — növbə: mesajlar götürülənə qədər onları saxlayır.
  • Consumer — mesajları növbədən götürüb emal edən tətbiq.
Mesaj producer, exchange, binding, növbə və consumer yolunu keçir, sonra ack gəlir
Mesaj producer, exchange, binding, növbə və consumer yolunu keçir, sonra ack gəlir

Vacib: producer növbəyə heç vaxt birbaşa yazmır, yalnız exchange-ə. Amma RabbitMQ-da adsız standart exchange (default exchange, adı boş sətirdir) var: hər növbə avtomatik olaraq ona öz adı ilə bağlanır. Ona görə channel.sendToQueue('emails', body) — channel.publish('', 'emails', body) üçün qısa yazılışdır. Exchange-in digər növlərini növbəti dərsdə öyrənəcəyik.

RabbitMQ-nu Docker-də qaldırırıq

Siz PostgreSQL və Redis-i Docker Compose ilə artıq işə salmısınız, RabbitMQ da eyni cür qaldırılır. management şəkilçisi olan image lazımdır: ona veb interfeys daxil edilib.

yaml
services:
  rabbitmq:
    image: rabbitmq:4-management
    hostname: rabbitmq
    ports:
      - "5672:5672"     # AMQP: applications connect here
      - "15672:15672"   # management UI in the browser
    volumes:
      - rabbitmq-data:/var/lib/rabbitmq

volumes:
  rabbitmq-data:

5672 portu tətbiqlər (AMQP), 15672 portu isə veb interfeys üçündür. hostname parametri təsadüfi deyil: RabbitMQ məlumatı node adı ilə saxlayır, bu ad host adından götürülür, sabit ad olmasa konteyner yenidən yaradılanda əvvəlki məlumat tapılmaz. Brokeri qaldırır və müştəri kitabxanasını quraşdırırıq:

bash
docker compose up -d
npm install amqplib