Вопрос проверяет понимание механизмов обеспечения надежности доставки сообщений в распределенных системах при временной недоступности брокера.
В распределенных системах брокер сообщений (RabbitMQ, Kafka) может быть временно недоступен из-за сетевых сбоев или перезагрузки. Если приложение в этот момент пытается отправить сообщение, оно может быть потеряно. Для обеспечения надежности применяют локальное хранение сообщений с последующей ретрансляцией.
Самый распространенный подход — паттерн Transactional Outbox. Сообщение сохраняется в локальную базу данных в той же транзакции, что и бизнес-данные. Отдельный фоновый процесс (publisher) читает неотправленные сообщения и отправляет их брокеру. После успешной отправки сообщение помечается как отправленное или удаляется.
// Пример на Node.js с PostgreSQL
async function createOrder(orderData) {
const client = await pool.connect();
try {
await client.query('BEGIN');
// 1. Сохраняем заказ
await client.query('INSERT INTO orders ...', [orderData]);
// 2. Сохраняем сообщение в outbox
await client.query(
'INSERT INTO outbox (event_type, payload, status) VALUES ($1, $2, $3)',
['order.created', JSON.stringify(orderData), 'pending']
);
await client.query('COMMIT');
} catch (e) {
await client.query('ROLLBACK');
throw e;
} finally {
client.release();
}
}
// Фоновый процесс отправки
async function processOutbox() {
const messages = await pool.query(
"SELECT * FROM outbox WHERE status = 'pending' ORDER BY created_at LIMIT 100"
);
for (const msg of messages.rows) {
try {
await broker.send(msg.event_type, msg.payload);
await pool.query('UPDATE outbox SET status = $1 WHERE id = $2', ['sent', msg.id]);
} catch (err) {
// Логируем ошибку, повторная попытка позже
console.error('Failed to send message', msg.id, err);
}
}
}Паттерн Outbox с использованием локальной БД — стандартный способ гарантировать доставку сообщений при сбоях брокера. Он подходит для микросервисных архитектур, где важна целостность данных. Для высоконагруженных систем можно комбинировать с механизмами повторных попыток и мониторингом DLQ.