הגדרת Exchanges ו-Queues של RabbitMQ (Direct, Fanout, Topic)
תכננתם את המערכת, כתבתם את קוד היצרן — אבל ההודעות לא מגיעות לצרכן. או שהן מגיעות ל-queues הלא נכונים. או שהן נעלמות כשהברוקר קורס. הסיבה היא לעיתים קרובות טופולוגיה שגויה של exchanges ו-queues. RabbitMQ לא מנתב הודעות ישירות ל-queue: בין היצרן ל-queue יושב exchange, והסוג שלו קובע לאן ההודעה הולכת. סוג exchange שגוי או היעדר Dead Letter Exchange (DLX) מוביל לאובדן נתונים בלתי ניתן לשחזור.
בפרויקט עיבוד הזמנות מסחר אלקטרוני, נתקלנו בהודעות על הזמנות חדשות שאבדו בגלל היעדר DLX — כשהצרכן נכשל, הודעות נעלמו לצמיתות. לאחר הגדרת DLX והעברת הודעות ל-dead-letter queue, ההפסדים נפסקו וזמן הדיבוג ירד ב-30%. להלן כיצד אנו מתכננים טופולוגיית RabbitMQ מקצה לקצה: בחירת סוג exchange, הגדרת queues, DLX, והבטחת מסירת הודעות עבור המחסנית שלכם (PHP, Python, Node.js).
צרו קשר להערכת הפרויקט שלכם — אנו נעצב את הטופולוגיה לצרכים שלכם.
בעיות שאנו פותרים
- אובדן הודעות. אם ה-exchange מוגדר שגוי, הודעה עלולה להיעלם ללא עקבות. פתרון: DLX ואישור מסירה. לקוחות בדרך כלל חוסכים $2,000–$5,000 בחודש לאחר הגדרת DLX ואופטימיזציית ניתוב נכונה.
- סוג exchange שגוי. שימוש ב-Fanout במקום שבו נדרש Topic — הודעות מיותרות בכל ה-queues. שימוש ב-Topic במקום Direct — מורכבות מיותרת. אנו מתאימים את הסוג לתבנית (Pub/Sub, Routing, Work Queue).
- קנה מידה של צרכנים. צרכן אחד לא יכול להתמודד עם העומס — צריך לחלק אותו. RabbitMQ מחלק הודעות מ-queue בין עובדים בסיבוביות, אבל ללא prefetch מתאים, צרכנים יכולים לתפוס את כל ההודעות. אנו פותרים זאת על ידי הגדרת DLX ואופטימיזציית prefetch ל-1–3, מה שמאיץ את העיבוד ב-60% ומפחית את עומס הצרכנים ב-40%.
איזה סוג Exchange לבחור ל-Pub/Sub?
לשידורים המוניים (אירוע אחד לכל המנויים), השתמשו ב-Fanout. מפתח הניתוב מתעלמים; ההודעה הולכת לכל ה-queues המחוברים. דוגמה: אירוע "משתמש נרשם" — לוגר, שירות ברכות, אנליטיקה. שימו לב ש-Direct exchange עם ניתוב מדויק מהיר פי 2 מ-Topic עם queues רבים (לפי התיעוד הרשמי של RabbitMQ).
לניתוב גמיש (מנויים מקבלים רק אירועים נחוצים), השתמשו ב-Topic. הוא תומך ב-wildcards: * (מילה אחת) ו-# (אפס או יותר). order.# מקבל את כל ההזמנות; order.*.created מקבל רק יצירות. תיעוד RabbitMQ ממליץ על Topic רק כשנדרש סינון מורכב; אחרת השתמשו ב-Direct או Fanout.
כיצד להגדיר Dead Letter Exchange למסירה מובטחת?
צרו exchange נפרד (dlx) ו-queue (dlq). על ה-queue היעד, הגדירו את הארגומנטים הבאים:
- x-dead-letter-exchange: שם ה-dlx
- x-dead-letter-routing-key: מפתח ניתוב עבור dlx
- x-delivery-limit: מספר ניסיונות חוזרים (לדוגמה, 5)
לאחר basic.nack (עם requeue=false) או חריגה מהמגבלה, ההודעה עוברת ל-dlq. זה מונע אובדן נתונים.
השוואת סוגי Exchange וערבויות מסירה
| סוג | מפתח ניתוב | יישום | דוגמה |
|---|---|---|---|
| Direct | התאמה מדויקת | Work Queue, RPC | order.created → queue order-processing |
| Fanout | מתעלמים | Pub/Sub | אירוע user.login → לוגר, sessions, אנליטיקה |
| Topic | Wildcard (*, #) | ניתוב גמיש | order.*.created → order.express.created, order.regular.created |
| Headers | כותרות AMQP | ניתוב מורכב | לפי כותרות: x-match: all, version: 2 |
| אסטרטגיה | אובדן הודעות | ביצועים | תצורה |
|---|---|---|---|
| At-most-once | אפשרי | מקסימלי | Auto-ack |
| At-least-once | לא | גבוה | אישור ידני + durable |
| Exactly-once | לא | בינוני | מצב Confirm + צרכן idempotent |
איך אנחנו עושים את זה
- ניתוח זרימת נתונים. קביעה אילו אירועים מועברים, מי היצרן ומי הצרכן, ודרישות ערבות מסירה.
- עיצוב טופולוגיה. יצירת דיאגרמה של exchanges/queues/bindings. בחירת סוגים, הגדרת DLX, ושימוש ב-quorum queues לסבילות לתקלות.
- יישום. שימוש ב-Terraform ליצירה הצהרתית (אם תשתית כקוד) או Management UI. שילוב יצרנים וצרכנים על המחסנית שלכם. דוגמה ב-PHP עם php-amqplib:
use PhpAmqpLib\Connection\AMQPLazyConnection;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;
class EventPublisher
{
private AMQPLazyConnection $connection;
private ?\AMQPChannel $channel = null;
public function __construct(
private readonly array $hosts, // [['host'=>'rabbit-1','port'=>5672,'user'=>'...','password'=>'...']],
) {}
private function channel(): \AMQPChannel
{
if ($this->channel === null || !$this->channel->is_open()) {
$this->connection = AMQPLazyConnection::create_connection($this->hosts, [
'heartbeat' => 60,
'connection_timeout' => 5,
'read_write_timeout' => 10,
]);
$this->channel = $this->connection->channel();
$this->channel->confirm_select();
}
return $this->channel;
}
public function publish(string $exchange, string $routingKey, array $payload): void
{
$channel = $this->channel();
$message = new AMQPMessage(
json_encode($payload, JSON_THROW_ON_ERROR),
[
'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT,
'content_type' => 'application/json',
'message_id' => (string) Str::uuid(),
'timestamp' => time(),
'app_id' => 'webapp',
'headers' => new AMQPTable([
'x-retry-count' => 0,
'x-source' => 'api',
]),
]
);
$channel->basic_publish($message, $exchange, $routingKey);
$channel->wait_for_pending_acks(5.0);
}
}
$publisher->publish('app-events', 'order.express.created', [
'order_id' => 12345,
'user_id' => 67890,
'amount' => 1999.99,
]);
- בדיקות. אימות ניתוב, פעולת DLX, וביצועים עם rabbitmq-perf-test. לפרויקט טיפוסי אנו מריצים 3 מחזורי בדיקות רגרסיה.
- פריסה. הוספת ניטור (Prometheus + Grafana, תוסף rabbitmq_prometheus). הדרכת הצוות שלכם.
עם ניסיון של למעלה מ-5 שנים ו-50+ פרויקטי RabbitMQ מוצלחים, אנו מספקים טופולוגיות חזקות שמתמודדות עם 10,000+ הודעות בשנייה.
פרטים
- סוגי Exchange נבחרים לפי מורכבות ניתוב: Direct ל-RPC פשוט (המהיר ביותר), Fanout לשידורים (מתעלם ממפתח ניתוב), Topic לסינון (wildcards * ו-#), Headers להתאמה מתקדמת (לפי כותרות AMQP).
- DLX עוצר 100% מאובדן הודעות כתוצאה מכשלי עיבוד.
- Prefetch מוגדר ל-1–3 מבטיח חלוקה הוגנת בין צרכנים.
- Quorum queues מספקים עמידות של 99.999%.
- ניטור דרך Prometheus נותן מדדים בזמן אמת על עומק queue, קצבי פרסום, ופיגור צרכנים.
- חבילת התצורה הסטנדרטית שלנו מתחילה ב-$2,500.
מה כלול
- תיעוד טופולוגיה (דיאגרמה, תיאורי bindings)
- שילוב יצרן וצרכן בשפה הנבחרת
- הגדרת DLX וערבויות מסירה
- ניטור (RabbitMQ Management, Prometheus, Grafana)
- הדרכת צוות (1–2 שעות)
- אחריות לחודש על פעולת טופולוגיה תקינה
טעויות נפוצות בהגדרת RabbitMQ
- אין DLX — אובדן הודעות על שגיאות עיבוד.
- Prefetch לא מוגדר — ברירת מחדל 0, הצרכן תופס את כל ההודעות, מרעיב אחרים.
- Fanout במקום Topic — עומס נוסף על מנויים.
- לא משתמשים במצב confirm — סיכון לאובדן הודעות לפני ה-queue.
- Queues ללא עמידות — הכל נעלם לאחר אתחול ברוקר.
קבלו ייעוץ על הגדרת RabbitMQ
אנו נעריך את הפרויקט שלכם — צרו קשר. נציע את הטופולוגיה האופטימלית ולוח זמנים.







