Telegram-бот знакомств на микросервисной архитектуре: анкеты, геопоиск, взаимные лайки, рейтинг пользователей, асинхронные уведомления и полный стек наблюдаемости.
Стек: Python 3.11+ · aiogram 3 · FastAPI · SQLAlchemy 2 (async) · PostgreSQL + PostGIS · Redis · RabbitMQ · Celery · MinIO (S3) · Dishka (DI) · Prometheus + Grafana + Loki · Docker Compose · uv
- Пошаговое заполнение анкеты через FSM: имя, фамилия, возраст, пол, био, город или геолокация, до 3 фото
- Настройка предпочтений: пол и диапазон возраста
- Подбор анкет по геолокации (PostGIS,
ST_DWithin/ST_Distance) с учётом предпочтений и рейтинга - Лайки/дизлайки, автоматическое определение мэтча и обмен контактами
- Просмотр списка тех, кто лайкнул, и ответная оценка
- Рейтинг анкет: стартовый балл по полноте профиля + начисления за мэтчи, чаты и рефералов, топ пользователей
- Реферальная система через deep-link
start - Push-уведомления о лайках и мэтчах из очередей RabbitMQ
- Rate limit, обработка медиагрупп, проверка наличия username — на уровне middleware
- Метрики каждого сервиса в Prometheus, логи контейнеров в Loki, дашборд в Grafana
| Команда | Действие |
|---|---|
/start |
Регистрация и заполнение анкеты (поддерживает deep-link рефералов) |
/view |
Просмотр подходящих анкет |
/profile |
Свой профиль: статистика, сброс, удаление |
/referral |
Получить реферальную ссылку |
/top |
Топ пользователей по рейтингу |
┌──────────────┐
Telegram ───▶ │ api_gateway │ aiogram 3, FSM в Redis
└──────┬───────┘
│ HTTP (httpx)
┌──────────────────┼────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌────────────────┐ ┌────────────────┐
│profile_service│ │matching_service│ │ rating_service │
│ :8000 │ │ :8002 │ │ :8001 │
│ Postgres+MinIO│ │ Postgres+PostGIS│ │ Postgres │
└───────────────┘ └────────┬───────┘ └────────────────┘
│ RabbitMQ (likes, matches)
▼
┌──────────────────────┐
│ notification_service │ Celery beat + worker
└──────────────────────┘
| Сервис | Порт | Ответственность |
|---|---|---|
api_gateway |
— | Telegram-бот на aiogram: хендлеры, FSM-состояния, клавиатуры, middleware; ходит в остальные сервисы по HTTP |
profile_service |
8000 | CRUD анкет, хранение фото в MinIO (S3) |
matching_service |
8002 | Лайки, мэтчи, предпочтения, геопоиск на PostGIS; публикует события в RabbitMQ |
rating_service |
8001 | Расчёт и обновление рейтинга, статистика, топ |
notification_service |
— | Celery-задача разбора очереди likes и consumer очереди matches, отправка уведомлений в Telegram |
ai_service |
— | Экспериментальный сервис семантического подбора: эмбеддинги rubert-tiny2 в ClickHouse, поиск ближайших по косинусной близости |
Базовый префикс REST API — /api/v1, у каждого сервиса своя БД. Схемы: docs/diagram.png, docs/db.jpg.
Стартовое значение — 800 баллов плюс бонус до 200 за полноту анкеты: заполненность полей (0.30), количество фото (0.25), наличие описания (0.20). Дальше рейтинг меняется от активности: мэтч даёт базовые +25 с поправкой на разницу рейтингов, приглашённый друг — до +250 с убывающей отдачей, общение — бонус от суммарного рейтинга пары.
git clone https://github.com/Rubsun/dating_bot.git
cd dating_bot
# указать токен бота
$EDITOR components/api_gateway/configs/app.docker.toml
docker compose up -d --buildПоднимутся сервисы приложения, три Postgres (один с PostGIS), Redis, RabbitMQ, MinIO, Prometheus, Grafana, Loki и Promtail.
uv sync
docker compose up -d profile_service_db rating_service_db matching_service_db redis rabbitmq s3
uv run uvicorn components.profile_service.main:app --port 8000
uv run uvicorn components.rating_service.main:app --port 8001
uv run uvicorn components.matching_service.main:app --port 8002
uv run python -m components.api_gateway.main
./components/notification_service/startup.shКаждый сервис читает TOML-конфиг, путь задаётся переменной окружения:
| Переменная | Значение по умолчанию в Compose |
|---|---|
API_GATEWAY_CONFIG_PATH |
./components/api_gateway/configs/app.docker.toml |
PROFILE_SERVICE_CONFIG_PATH |
./components/profile_service/configs/app.docker.toml |
RATING_SERVICE_CONFIG_PATH |
./components/rating_service/configs/app.docker.toml |
MATCHING_SERVICE_CONFIG_PATH |
./components/matching_service/configs/app.docker.toml |
NOTIFICATION_SERVICE_CONFIG_PATH |
./components/notification_service/configs/app.docker.toml |
Локальные варианты — configs/app.toml рядом с каждым сервисом. Креды БД и MinIO — в configs/db.env и configs/minio.env.
| Интерфейс | Адрес |
|---|---|
| Grafana | http://localhost:3000 (admin / admin) |
| Prometheus | http://localhost:9090 |
| RabbitMQ Management | http://localhost:15672 |
| Loki | http://localhost:3100 |
Метрики FastAPI собираются через prometheus-fastapi-instrumentator, логи контейнеров — Promtail → Loki, дашборд провижинится из grafana/provisioning/dashboards.
components/
api_gateway/ # Telegram-бот (aiogram): handlers, states, keyboards, middlewares
profile_service/ # анкеты, фото в MinIO
matching_service/ # лайки, мэтчи, геопоиск
rating_service/ # рейтинг и статистика
notification_service/ # Celery beat/worker, consumer RabbitMQ
ai_service/ # эмбеддинги и ClickHouse (эксперимент)
shared/ # общий logging-конфиг
configs/ # env-файлы инфраструктуры
grafana/, prometheus/ # провижининг мониторинга
docs/ # схемы архитектуры и БД
Линтер flake8 (конфиг в .flake8) запускается в GitHub Actions на каждый push:
uv run flake8 .