Cozi de mesaje: RabbitMQ, Kafka
Cozi de mesaje: RabbitMQ, Kafka
1) Când să alegeți
RabbitMQ (AMQP 0-9-1/1. 0, cozi clasice, cozi de cvorum, fluxuri)
Potrivit pentru: RPC/comenzi, flux de lucru, sarcini scurte, rutare fanout/subiect, confirmări flexibile, control prioritar.
Pro: semantică de rutare bogată (schimburi), "de bază. qos "(prefetch), per-mesaj TTL/întârziere, modele convenabile RPC (răspuns la), start ușor.
Contra: Istoria stocată în coadă, scalată orizontal între cozi/cioburi; Cost de transfer ridicat cu fluxuri foarte mari.
Apache Kafka (jurnal de evenimente, petreceri, grupuri de consumatori)
Potrivit pentru: fluxuri de evenimente, audit, evenimente de aprovizionare, ETL/integrări (Connect), mare RPS/MBps, reluare/re-procesare, flux de procesare (Streams/ksqlDB).
Pro: jurnal pe termen lung, scalare de către părți, reluare stabilă, compactare cheie.
Contra: model pull + parties - nu pentru RPC mici; comandă numai în cadrul părții; managementul schemei/interoperabilitatea este responsabilitatea echipei.
2) Semantica de livrare și invarianți
At-most-once: fără retraverse; rapid, risc de pierdere.
Cel puțin o dată: cu retrageri; necesită idempotență consumatorilor.
Exact o dată: realizabil în condiții limitate (producător idempotent Kafka TX++ chiuvetă consistentă; RabbitMQ - prin tabelul de eliminare a duplicatelor/cheile idempotente).
Comandă: RabbitMQ - comandă de coadă (poate fi încălcată cu retras/multi-consumatori); Kafka - ordine în partid, cheia stabilește partiționarea.
Invarianți de domenii: bani/solduri - prin reviste/saga și echipe idempotente; nu se bazează pe LWW.
3) Modele de integrare
Outbox/InBox: înregistrarea atomică a evenimentului în baza de date → publicarea la coadă (outbox) și consumul idempotent cu jurnalul de procesare (inbox).
DLQ (litere moarte): după N încercări/erori - în alertă DLQ +.
Reîncercare/întârziere: RabbitMQ - TTL + schimb de scrisori moarte; Kafka - încercați din nou subiecte cu backoff.
Cerere/Răspuns: RabbitMQ - 'reply _ to' + 'corelation _ id'; Kafka - rar, numai cu modele speciale.
Compensații: sagas peste evenimente; fiecare operație are un invers.
4) Design cheie și topologie
RabbitMQ
Schimburi: 'direct', 'topic', 'fanout', 'headers'.
Cheie de rutare: Specifică hitul (loviturile) cozii. Pentru prioritizare - cozi separate.
QoS: „prefetch” (de ex. 50-300) rata soldurilor/latenta.
Cozi de cvorum: cozi replicate pe Raft; înlocuire oglindită clasic.
Fluxuri: flux cu decalaje (Kafka-like) pentru debit mare/reluare.
Kafka
Subiect → partiții: planificați '# partiții' pe debitul țintă și paralelism (creșterea compatibilă înapoi este mai ușoară decât scăderea).
Cheie: toate înregistrările unei chei - într-o singură parte (garanția comenzii prin cheie).
Factor de replicare: 3 pentru subiecte productive, "min. insync. replici = 2 '+' acks = toate 'pentru fiabilitate.
Retenție: în funcție de timp/dimensiune; compactare - stochează ultimele valori prin cheie + pietre funerare pentru ștergere.
5) Retrai, DLQ, idempotenta
RabbitMQ
Repetă: per-mesaj TTL + DLX (schimb de litere moarte) cu backoff (de exemplu, 1m → 5m → 15m).
Idempotence: 'corelation _ id'/' message-id' + message table processed (TTL) sau deterministic commands.
Confirmări: manual 'basic. ack „după o tranzacție reușită;” de bază. nack (requeue = false) 'в DLQ.
Kafka
Repetiții: subiecte individuale; consumatorul se angajează să compenseze după efectul secundar de succes.
Prelucrarea exact odată (EOS): Activarea producătorului. idempotence = true ', producător/consumator tranzacțional,' read _ committed 'pe consumator; chiuveta (de exemplu, Kafka→Kafka sau Kafka→DB printr-o tranzacție) - sincroniza frumos.
Dedup: prin cheie/cheie idempotent pe partea de bază, sau prin intermediul subiectului comprimat.
6) Performanță și dimensiune
Little's Law: 'L = λ × W'
Pentru vorker: suprapunerea necesară "N stoc (1. 2–1. 5)`.
Prefetch RabbitMQ: Începeți cu 'prefetch = 100' și măsurați timpul p99/în timpul zborului.
Partiții Kafka: calcul din paralelismul de consum dorit și obiectiv de transfer (de exemplu, 1 lot este stabil 5-20 MB/s pe SSD/10GbE).
7) Observabilitate și alerte
În general:- Lag/Backlog (mesaje/octeți), vârsta mesajelor (p95/p99), rata de eroare a procesării, rata DLQ.
- Timpul „publikatsiya→obrabotka” (end-to-end).
- Harta dependenței: producător → broker → consumator.
- Conexiuni, canale, mesaje neautorizate, 'memory _ alarm',' disk _ free _ limit ',' queue length 'p95.
- Rapoarte despre Quorum (liderul, jurnalul Raft, ratează „cvorumul nu este suficient”).
- Partiții sub-replicate, ISR micșorează/extinde, modificările controlerului.
- Erori de producător (timeout, „latență cerere”), lag de consum pe grup/partiție.
- Broker I/O, pagină cache lovit, GC, ZooKeeper/sănătate KRaft.
8) Siguranță și multi-chirie
TLS criptare în tranzit, autentificare (SASL/PLAIN/SCRAM/OAuth, mTLS).
Autorizație: vhost/permissions (RabbitMQ), ACL la subiecte/grupuri (Kafka).
Cote: pentru conexiuni, canale, dimensiunea cozii/subiect, viteza de publicare/citire.
Izolarea prin medii (dev/stage/prod) și prin namespace/vhost.
9) Funcționare și reglare
RabbitMQ
Post schimburi/cozi la noduri (capital CPU/IO).
Cozi lenese (mesaje pe disc) pentru tampoane mari; evita „fierbinte” cozi fără sharding.
Cozi de cvorum pentru HA; Planificați dimensiunea jurnalului de plută și discul.
Politici TTL/limită de lungime, cozi prioritare numai pentru nevoi reale (costisitoare).
bash rabbitmqctl set_policy DLX "^task\." \
'{"dead-letter-exchange":"dlx","message-ttl":60000,"max-length":100000}' --apply-to queues
Kafka
SSD/NVMe, rețele rapide; OS tuning (swappiness scăzut, limite de fișiere).
'hacks = all', 'linger. ms „(butching),” compresie. type = zstd'/lz4 pentru lățime de bandă.
Opțiuni de consum: "max. poll. interval. ms', "max. sondaj. înregistrări "," adu ". min. bytes ".
Păstrare și compactare - echilibru de stocare/reluare.
java props. put("acks","all");
props. put("enable. idempotence", "true");
props. put("max. in. flight. requests. per. connection","1");
props. put("retries","10");
10) Integrări și ecosistem
Kafka Connect (Sinks/Sources), Schema Registry (Avro/JSON/Protobuf) și interoperabilitatea („ÎNAPOI/ÎNAINTE/COMPLET”).
Kafka Streams/ksqlDB: operații statale, ferestre, agregate.
RabbitMQ Lopată/Federație: transfer între clustere/centre.
Operatori K8s: Strimzi (Kafka), RabbitMQ Cluster Operator; Manifestele GitOps.
11) Lista de verificare a implementării (0-45 zile)
0-10 zile
Definiți cazurile de utilizare: comenzi/sarcini (RabbitMQ), evenimente/audituri (Kafka).
Selectați tastele („cheie de rutare ”/„ cheie de partiție”), setați SLO „publikatsiya→obrabotka”.
Politici de securitate de bază (TLS, ACL), cote, DLQ/TTL.
11-25 zile
Implementați outbox/inbox, idempotency și deadup.
Configurați retrageri cu backoff (Iepure: TTL + DLX; Kafka: încercați din nou subiecte).
Tablouri de bord: lag, vârstă, rată DLQ, latență end-to-end; alerte.
26-45 zile
Lățime de bandă de tuning: prefetch/acks (iepure); partiții/acks/lot (Kafka).
Proceduri DR (oglindire/replicare), teste de defectare a nodului.
Contracte de evenimente pentru documente (scheme) și politici de interoperabilitate.
12) Anti-modele
Un instrument „universal” pentru toate sarcinile.
Absența DLQ/TTL: otrăvuri eterne (mesaje otrăvitoare).
„Prefetch” nelimitat → înfometarea consumatorilor, creșterea p99.
Kafka fără chei → pierderea ordinii/părților fierbinți în mod implicit.
„Exact odată”, fără nevoie reală/disciplină, este un fals sentiment de securitate.
Secrete/conectări în cod, fără TLS/ACL.
Hardcode de scheme/versiuni de mesaje fără Registry și migrații.
13) Valorile maturității
Lag/vârstă SLO se efectuează ≥ 99% din timp; Rata DLQ sub control.
Idempotența acoperă 100% din căile critice; outbox/inbox implementat.
Retenția/compactarea sunt documentate, reluarea nu rupe consumatorii.
Sunt configurate alerte privind limitele ISR/URP (Kafka) și Raft/disc (Rabbit).
Contractele de evenimente sunt versionate (Schema Registry), compatibilitatea este testată în CI.
Zile regulate de joc: nod/broker/eșec AZ, verificare de recuperare.
14) Exemple de configurații (rezumat)
RabbitMQ: prefix și confirmări (pseudocod):python channel. basic_qos(prefetch_count=200)
for msg in consume("tasks"):
try:
handle(msg)
channel. basic_ack(msg. delivery_tag)
except Transient:
channel. basic_nack(msg. delivery_tag, request = False) # will go to DLQ
Kafka Consumer (idei):
java props. put("enable. auto. commit","false");
props. put("isolation. level","read_committed"); // при EOS
//...
poll -> process(idempotent) -> commitSync()
15) Concluzie
RabbitMQ și Kafka rezolvă diferite clase de probleme: comenzi/sarcini și rutare bogată împotriva unui jurnal de evenimente pe termen lung și streaming scalabil. Succes - în semantica corectă de livrare, disciplina idemptence, chei grijulii, retrays/DLQ, observabilitate și securitate strictă. Construiți practici de inginerie în jurul cozilor - outbox/inbox, scheme și politici GitOps - iar integrarea dvs. devine previzibilă, scalabilă și durabilă.