← Назад к вопросам

Что такое шина данных?

1.2 Junior🔥 61 комментариев
#DevOps и инфраструктура

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое шина данных?

Шина данных (Data Bus, Event Bus, Message Bus) — это архитектурный паттерн, который позволяет различным компонентам системы асинхронно обмениваться сообщениями без прямой связи между ними. Это как почтальон, который передаёт письма между адресатами, не создавая прямых связей между ними.

Основная идея

Вместо того чтобы компоненты напрямую вызывали друг друга (tight coupling — плотная связь), они отправляют сообщения в общую шину, а другие компоненты слушают эти сообщения.

Реализация шины данных в Node.js

Пример 1: Простая реализация с EventEmitter

const EventEmitter = require('events');

class EventBus extends EventEmitter {}

const bus = new EventBus();

// Когда пользователь регистрируется, отправляем событие
function registerUser(email) {
  console.log('User registered:', email);
  
  // Отправляем событие в шину
  bus.emit('user:registered', { email, timestamp: Date.now() });
}

// Слушатели события
bus.on('user:registered', (data) => {
  console.log('Email service: Sending welcome email to', data.email);
});

bus.on('user:registered', (data) => {
  console.log('Analytics: User registered event logged');
});

registerUser('john@example.com');

Пример 2: С классами и типизацией

class EventBus {
  constructor() {
    this.handlers = {};
  }

  subscribe(eventName, handler) {
    if (!this.handlers[eventName]) {
      this.handlers[eventName] = [];
    }
    this.handlers[eventName].push(handler);
  }

  publish(eventName, data) {
    if (this.handlers[eventName]) {
      this.handlers[eventName].forEach(handler => {
        handler(data);
      });
    }
  }
}

class UserService {
  constructor(bus) {
    this.bus = bus;
  }

  registerUser(userData) {
    const user = { id: 1, ...userData };
    this.bus.publish('user.created', user);
    return user;
  }
}

class EmailService {
  constructor(bus) {
    this.bus = bus;
    this.bus.subscribe('user.created', (user) => {
      this.sendWelcomeEmail(user.email);
    });
  }

  sendWelcomeEmail(email) {
    console.log(`Sending welcome email to ${email}`);
  }
}

Message Queue (более продвинутая шина)

const amqp = require('amqplib');

async function setupMessageBus() {
  const connection = await amqp.connect('amqp://localhost');
  const channel = await connection.createChannel();

  // Объявляем очередь
  await channel.assertQueue('user.events');

  // Публикатор
  function publishEvent(eventType, data) {
    const message = JSON.stringify({ type: eventType, data });
    channel.sendToQueue('user.events', Buffer.from(message));
  }

  // Подписчик
  channel.consume('user.events', (msg) => {
    const event = JSON.parse(msg.content.toString());
    console.log('Event received:', event);
    channel.ack(msg);
  });
}

Когда использовать шину данных

  1. Слабая связь компонентов — компоненты не знают друг о друге
  2. Асинхронная обработка — отправить событие и не ждать ответа
  3. Масштабируемость — легко добавить новых слушателей
  4. Decoupling — разделение ответственности

Преимущества

  • Компоненты независимы
  • Легко добавлять новую функциональность (новых слушателей)
  • Проще тестировать (мокируем только шину)
  • Асинхронная обработка
  • Масштабируемость

Недостатки

  • Сложнее следить за потоком данных
  • Может быть сложнее отладить
  • Производительность может упасть при большом количестве событий

Пример с Express и Message Bus

const express = require('express');
const EventEmitter = require('events');

const app = express();
const bus = new EventEmitter();

app.post('/users', (req, res) => {
  const user = { id: 1, email: req.body.email };
  bus.emit('user:created', user);
  res.json({ success: true, user });
});

bus.on('user:created', async (user) => {
  console.log('Sending email to', user.email);
});

bus.on('user:created', (user) => {
  console.log(`[LOG] User created: ${user.email}`);
});

app.listen(3000, () => console.log('Server running'));

Шина данных — это мощный паттерн для построения масштабируемых, гибких систем, где компоненты взаимодействуют через сообщения, а не через прямые вызовы.