flea/architecture.md
2025-10-16 22:11:06 +04:00

17 KiB
Raw Permalink Blame History

Архитектура системы NOCR

Диаграмма взаимодействия между сервисами системы мониторинга Telegram-каналов.

classDiagram
    TelegramListener --|> Bus : publishes
    Bus --|> TextMatcher : subscribes
    TextMatcher --|> Bus : publishes
    Bus --|> TelegramClient : subscribes
    TelegramClient --|> Users : REST API
    TelegramClient --|> TextMatcher : REST API

    class Bus{
        <<RabbitMQ Message Broker>>
        +MessageReceived events
        +MessageEdited events
        +TextSubscriptionMatched events
        +TextSubscriptionUpdated events
    }

    class TelegramListener {
        <<Сканер каналов>>
        +publishes: MessageReceived
        +publishes: MessageEdited
        ---
        WTelegramClient (MTProto API)
        Хранение сессий пользователей
    }

    class TextMatcher {
        <<Обработчик совпадений>>
        +publishes: TextSubscriptionMatched
        +publishes: TextSubscriptionUpdated
        -subscribes: MessageReceived
        -subscribes: MessageEdited
        ---
        REST API:
        +long Create(CreateTextMatchRequest)
        +TextMatchData? GetById(long id)
        +TextMatchData[] GetByUserId(long userId)
        +void Delete(long id)
        +void Activate(long id)
        +void Disable(long id)
        ---
        БД: История совпадений (MariaDB)
        Проверка регулярных выражений
    }

    class Users {
        <<Управление пользователями>>
        ---
        REST API:
        +long Create(CreateUserRequest)
        +UserData? GetById(long id)
        +UserData? GetByIdentity(type, identity)
        ---
        БД: Пользователи и настройки (MariaDB)
    }

    class TelegramClient {
        <<Telegram Bot интерфейс>>
        -subscribes: TextSubscriptionMatched
        -subscribes: TextSubscriptionUpdated
        ---
        Telegram.Bot (Bot API)
        Обработка команд пользователей
        Отправка уведомлений
        ---
        REST клиенты:
        -Users.Create()
        -Users.GetById()
        -Users.GetByIdentity()
        -TextMatcher.GetByUserId()
        -TextMatcher.Create()
    }

Описание компонентов

1. TelegramListener (Сканер каналов)

Технологии: .NET 8, WTelegramClient, Rebus

Ответственность:

  • Подключение к Telegram через MTProto API
  • Подписка на открытые каналы и чаты
  • Получение новых и отредактированных сообщений
  • Публикация событий в RabbitMQ

Публикуемые события:

  • MessageReceived - новое сообщение получено
  • MessageEdited - сообщение отредактировано

Примечание: WTelegram отправляет оба события (UpdateNewChannelMessage и UpdateEditChannelMessage) для одного и того же сообщения. TelegramListener публикует отдельные события, чтобы избежать дублирования уведомлений.


2. TextMatcher (Обработчик совпадений)

Технологии: .NET 8, Entity Framework Core, MariaDB, Rebus

Ответственность:

  • Подписка на события сообщений от TelegramListener
  • Проверка совпадений с пользовательскими подписками (regex, ключевые слова)
  • Хранение истории совпадений в БД
  • Публикация событий о найденных совпадениях
  • REST API для управления подписками

Подписывается на события:

  • MessageReceived - проверка нового сообщения
  • MessageEdited - обновление ранее найденного совпадения

Публикуемые события:

  • TextSubscriptionMatched - новое совпадение найдено
  • TextSubscriptionUpdated - обновление ранее найденного совпадения

REST API эндпоинты:

  • POST /api/textmatch - Создать новую подписку
  • GET /api/textmatch/{id} - Получить подписку по ID
  • GET /api/textmatch/user/{userId} - Получить все подписки пользователя
  • DELETE /api/textmatch/{id} - Удалить подписку
  • POST /api/textmatch/{id}/activate - Активировать подписку
  • POST /api/textmatch/{id}/disable - Отключить подписку

3. TelegramClient (Telegram Bot)

Технологии: .NET 8, Telegram.Bot, Rebus, RestEase

Ответственность:

  • Интерфейс бота для взаимодействия с пользователями
  • Обработка команд бота (/start, /subscribe, /list и т.д.)
  • Подписка на события совпадений
  • Отправка уведомлений пользователям
  • Интеграция с Users и TextMatcher через REST API

Подписывается на события:

  • TextSubscriptionMatched - отправка уведомления о новом совпадении
  • TextSubscriptionUpdated - уведомление об обновлении

REST клиенты:

  • Users API: управление пользователями
  • TextMatcher API: управление подписками

4. Users (Управление пользователями)

Технологии: .NET 8, Entity Framework Core, MariaDB

Ответственность:

  • CRUD операции для пользователей
  • Хранение предпочтений и настроек
  • REST API для других сервисов

REST API эндпоинты:

  • POST /api/users - Создать нового пользователя
  • GET /api/users/{id} - Получить пользователя по ID
  • GET /api/users/identity/{type}/{identity} - Найти пользователя по Telegram ID

5. RabbitMQ (Message Bus)

Технологии: RabbitMQ 3.x, Rebus

Ответственность:

  • Асинхронная доставка событий между сервисами
  • Гарантия доставки сообщений
  • Очереди и обмены (exchanges)

Настройка:

  • Direct Exchange: nocr.direct - для точечной маршрутизации
  • Topic Exchange: nocr.topics - для публикации/подписки по топикам
  • Очереди: Каждый сервис имеет свою input queue

Паттерны взаимодействия

Event-Driven Architecture (Асинхронная)

TelegramListener → RabbitMQ → TextMatcher → RabbitMQ → TelegramClient

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

  • Слабая связанность сервисов
  • Масштабируемость (можно добавить несколько обработчиков)
  • Отказоустойчивость (сообщения не теряются при падении сервиса)

Request-Response (Синхронная)

TelegramClient → REST API → Users
TelegramClient → REST API → TextMatcher

Использование:

  • Создание/получение данных пользователей
  • Управление подписками
  • Запросы, требующие немедленного ответа

Потоки данных

Основной поток (Мониторинг и уведомления)

  1. Сканирование:

    • TelegramListener подключается к Telegram MTProto
    • Получает новые сообщения из каналов
    • Публикует MessageReceived в RabbitMQ
  2. Обработка:

    • TextMatcher получает MessageReceived
    • Проверяет сообщение на совпадение с подписками
    • Сохраняет историю в БД
    • Публикует TextSubscriptionMatched в RabbitMQ
  3. Уведомление:

    • TelegramClient получает TextSubscriptionMatched
    • Получает данные пользователя из Users API
    • Отправляет уведомление через Telegram Bot API

Поток редактирования сообщений

  1. Обновление:

    • TelegramListener получает UpdateEditChannelMessage
    • Публикует MessageEdited в RabbitMQ
  2. Повторная проверка:

    • TextMatcher получает MessageEdited
    • Проверяет, было ли это сообщение ранее найдено
    • Если было, публикует TextSubscriptionUpdated
  3. Уведомление об обновлении:

    • TelegramClient получает TextSubscriptionUpdated
    • Отправляет обновленное уведомление пользователю

Clean Architecture

Каждый сервис следует принципам Clean Architecture:

┌─────────────────────────────────────────┐
│  Host (API / Entry Point)              │  ← ASP.NET Core, Controllers
├─────────────────────────────────────────┤
│  AppServices (Business Logic)          │  ← Use Cases, Handlers
├─────────────────────────────────────────┤
│  Core (Domain / Shared)                │  ← Entities, Interfaces
├─────────────────────────────────────────┤
│  Persistence (Data Access)             │  ← EF Core, Repositories
├─────────────────────────────────────────┤
│  Async.Api.Contracts (Event Contracts) │  ← RabbitMQ Events (NuGet)
├─────────────────────────────────────────┤
│  Api.Contracts (REST Contracts)        │  ← DTOs, Requests (NuGet)
├─────────────────────────────────────────┤
│  Migrator (Database Migrations)        │  ← EF Core Migrations
└─────────────────────────────────────────┘

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

  • Независимость от фреймворков
  • Тестируемость
  • Независимость от UI/Database
  • Переиспользование контрактов через NuGet

Базы данных

TextMatcher Database (MariaDB)

Порт: 3316 (локально), 3306 (Docker/K8s)

Таблицы:

  • TextMatches - Пользовательские подписки
  • MatchHistory - История найденных совпадений
  • __EFMigrationsHistory - История миграций EF Core

Users Database (MariaDB)

Порт: 3326 (локально), 3306 (Docker/K8s)

Таблицы:

  • Users - Пользователи системы
  • UserPreferences - Настройки пользователей
  • __EFMigrationsHistory - История миграций EF Core

Развертывание

Docker Compose (Локальная разработка)

┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│ telegram-   │  │ telegram-   │  │ text-       │  │ users       │
│ listener    │  │ client      │  │ matcher     │  │             │
│ :5040       │  │ :5050       │  │ :5041       │  │ :5042       │
└──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘
       │                │                │                │
       └────────────────┴────────────────┴────────────────┘
                              │
                    ┌─────────┴─────────┐
                    │   RabbitMQ        │
                    │   :5672, :15672   │
                    └───────────────────┘
                              │
              ┌───────────────┴───────────────┐
              │                               │
      ┌───────┴────────┐            ┌────────┴────────┐
      │ text-matcher-  │            │ users-db        │
      │ db :3316       │            │ :3326           │
      └────────────────┘            └─────────────────┘

Kubernetes (Production)

  • Namespace: nocr
  • Services: ClusterIP для внутренней коммуникации
  • Deployments: С health checks и resource limits
  • Secrets: Для Telegram API credentials и Bot tokens
  • ConfigMaps: Для конфигурации окружения

Мониторинг и наблюдаемость

Health Checks

Каждый сервис предоставляет /health эндпоинт:

Логирование

  • Структурированное логирование через Serilog
  • Логи выводятся в stdout для Docker/K8s
  • Централизованное логирование через kubectl logs

Метрики

  • RabbitMQ Management UI: http://localhost:15672
  • Мониторинг очередей и exchanges
  • Просмотр активных подключений

Масштабирование

Горизонтальное масштабирование

Можно масштабировать:

  • TextMatcher - несколько инстансов обрабатывают сообщения параллельно
  • TelegramClient - несколько инстансов отправляют уведомления параллельно
  • Users - stateless API, можно масштабировать без ограничений

Ограничения:

  • ⚠️ TelegramListener - один инстанс на одну Telegram сессию (ограничение WTelegram)

Вертикальное масштабирование

  • Увеличение CPU/RAM для сервисов
  • Оптимизация запросов к БД
  • Настройка connection pools

Безопасность

Секреты

  • Telegram API credentials хранятся в K8s Secrets
  • Bot tokens хранятся в K8s Secrets
  • Database credentials в environment variables

Сетевая безопасность

  • Все сервисы работают в приватной сети
  • Только TelegramClient имеет доступ к внешним API
  • RabbitMQ защищен credentials

Валидация

  • Входящие данные валидируются в AppServices
  • REST API использует Data Annotations
  • Event contracts строго типизированы

Дополнительная информация


Последнее обновление: 16 октября 2025