Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Распределенные вычисления

Python FastAPI Docker React TypeScript Vite Nginx Prometheus Grafana

Это небольшой стенд распределенной системы. Пользователь работает только с gateway: создает задачу через HTTP API, получает TCP-порт и подключается к нему. Сама задача запускается не на gateway, а в отдельном контейнере на одном из worker-узлов.

Проще говоря: gateway принимает запрос, выбирает свободный worker, worker поднимает контейнер с вычислителем, а gateway прокидывает TCP-трафик от пользователя до этого контейнера.

Архитектура

Схема архитектуры

В системе есть несколько частей:

  • gateway - единая точка входа. Хранит список workers и jobs, выбирает worker, выделяет порт и запускает TCP proxy.
  • worker - внутренний сервис, который запускает и удаляет контейнеры с задачами через Docker.
  • job-runner - контейнер с простой TCP-программой. Он отвечает на команды ping, stats, load, stop, help.
  • frontend - простой веб-интерфейс для просмотра состояния системы.
  • Prometheus и Grafana - мониторинг gateway, workers и активных jobs.

Пользователь не ходит напрямую в worker и job-runner. Снаружи видны только gateway API, frontend, мониторинг и диапазон TCP-портов для jobs.

Как это работает

  1. Пользователь отправляет POST /api/jobs на gateway.
  2. Gateway смотрит зарегистрированные workers.
  3. Выбирается worker с наименьшей загрузкой.
  4. Gateway резервирует свободный порт из диапазона 5000-5099.
  5. Worker запускает отдельный контейнер job-runner.
  6. Gateway запускает TCP proxy с выделенного порта на контейнер задачи.
  7. Пользователь подключается к этому порту через nc или другой TCP-клиент.

Пример пути для одной задачи:

client -> gateway:5000 -> TCP proxy -> job-runner:7001

На уровне TCP это два отдельных соединения: клиент соединяется с gateway, а gateway отдельно соединяется с job-runner.

TCP-соединения через gateway

Проверка сокетов показывает ту же картину:

Активные TCP-сокеты

Service discovery

Workers сами регистрируются на gateway после запуска:

POST /internal/workers/register

Потом они регулярно отправляют heartbeat:

POST /internal/workers/heartbeat

В heartbeat worker передает свой worker_id, capacity и текущее количество активных jobs. Если heartbeat долго не приходит, gateway считает worker недоступным и больше не отправляет на него новые задачи.

API

Основные пользовательские endpoints:

POST   /api/jobs
GET    /api/jobs
GET    /api/jobs/{job_id}
DELETE /api/jobs/{job_id}
GET    /api/workers
GET    /api/system/status
GET    /health
GET    /ready
GET    /metrics

После создания job gateway возвращает примерно такой ответ:

{
  "job_id": "job-8f34f05916",
  "status": "running",
  "worker_id": "worker-2",
  "port": 5001,
  "protocol": "tcp",
  "connect": "tcp://localhost:5001"
}

Команды внутри TCP-сессии:

ping
stats
load 1
help
stop

Структура проекта

.
├── docker-compose.yml
├── Makefile
├── gateway/
├── worker/
├── job-runner/
├── frontend/
├── monitoring/
├── load-tests/
├── media/
└── report/

Как запустить

Нужны Docker, Docker Compose и Python 3.

Собрать образы:

docker compose build

Запустить проект:

docker compose up -d

Проверить контейнеры:

docker compose ps

Локальные адреса:

Gateway API: http://localhost:18080
Frontend:    http://localhost:8081
Prometheus:  http://localhost:9090
Grafana:     http://localhost:3000
Job ports:   localhost:5000-5099

Проверить gateway:

curl http://localhost:18080/health
curl http://localhost:18080/ready
curl http://localhost:18080/api/workers

Создать задачу:

curl -X POST http://localhost:18080/api/jobs

Подключиться к задаче по TCP. Порт нужно взять из ответа gateway:

nc localhost 5000

Внутри соединения можно отправить:

ping
stats
load 1
help

Удалить задачу:

curl -X DELETE http://localhost:18080/api/jobs/JOB_ID

Тесты

Поставить зависимости для тестовых скриптов:

python3 -m venv .venv
source .venv/bin/activate
pip install -r load-tests/requirements.txt

Создать много jobs и посмотреть распределение по workers:

python3 load-tests/create_jobs.py --gateway http://localhost:18080 --count 30 --concurrency 5 --delete

Создать одну job и проверить TCP-команды:

python3 load-tests/tcp_test.py --gateway http://localhost:18080 --host localhost

То же самое можно запустить через Makefile:

make test-load
make tcp-test

Остановка

Остановить сервисы:

docker compose down --remove-orphans

Остановить сервисы и удалить сохраненное состояние gateway:

docker compose down -v --remove-orphans

Если после ручных проверок остались контейнеры jobs:

docker rm -f $(docker ps -aq --filter label=distributed-computing-platform.job=true)

About

A distributed computing prototype with a gateway, worker nodes, TCP proxying, Docker-based job containers, and monitoring.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages