17 KiB
Архитектура системы 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}- Получить подписку по IDGET /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}- Получить пользователя по IDGET /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
Использование:
- Создание/получение данных пользователей
- Управление подписками
- Запросы, требующие немедленного ответа
Потоки данных
Основной поток (Мониторинг и уведомления)
-
Сканирование:
- TelegramListener подключается к Telegram MTProto
- Получает новые сообщения из каналов
- Публикует
MessageReceivedв RabbitMQ
-
Обработка:
- TextMatcher получает
MessageReceived - Проверяет сообщение на совпадение с подписками
- Сохраняет историю в БД
- Публикует
TextSubscriptionMatchedв RabbitMQ
- TextMatcher получает
-
Уведомление:
- TelegramClient получает
TextSubscriptionMatched - Получает данные пользователя из Users API
- Отправляет уведомление через Telegram Bot API
- TelegramClient получает
Поток редактирования сообщений
-
Обновление:
- TelegramListener получает
UpdateEditChannelMessage - Публикует
MessageEditedв RabbitMQ
- TelegramListener получает
-
Повторная проверка:
- TextMatcher получает
MessageEdited - Проверяет, было ли это сообщение ранее найдено
- Если было, публикует
TextSubscriptionUpdated
- TextMatcher получает
-
Уведомление об обновлении:
- TelegramClient получает
TextSubscriptionUpdated - Отправляет обновленное уведомление пользователю
- TelegramClient получает
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 эндпоинт:
- telegram-listener: http://localhost:5040/health
- text-matcher: http://localhost:5041/health
- users: http://localhost:5042/health
- telegram-client: http://localhost:5050/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 строго типизированы
Дополнительная информация
- README.md - Общая документация проекта
- CONFIGURATION.md - Руководство по конфигурации
- _deploy/README.md - CI/CD и деплой
- CLAUDE.md - Инструкции для AI-ассистента
Последнее обновление: 16 октября 2025