Skip to content

litvidan/crackhash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CrackHash — отказоустойчивая система распределённого взлома MD5

Распределённая система на Kotlin для подбора MD5‑хэшей методом перебора. Основана на микросервисной архитектуре с брокером сообщений RabbitMQ и документоориентированным хранилищем MongoDB.
Все компоненты автоматически восстанавливаются после сбоев и могут быть развёрнуты в Docker Swarm на одном или нескольких хостах.


Архитектура

Система состоит из трёх логических сервисов, запускаемых в Docker-контейнерах:

1. Gateway (Менеджер)

  • Принимает от клиентов GraphQL-запросы (мутации crackHash и запросы hashStatus).
  • Делит общую задачу перебора на независимые части.
  • Сохраняет состояние каждой задачи в отказоустойчивой MongoDB (Replica Set).
  • Публикует части задач в очередь RabbitMQ (JSON-сообщения).
  • Подписывается на очередь ответов и сохраняет найденные слова в MongoDB.
  • При старте восстанавливает задачи, которые были в работе до падения менеджера.

2. Worker (Рабочий)

  • Подписывается на очередь задач RabbitMQ.
  • Выполняет перебор MD5 в заданном диапазоне (генерирует слова, вычисляет хэш).
  • При нахождении совпадения немедленно публикует результат в очередь ответов.
  • В случае сбоя воркера RabbitMQ автоматически переотправляет задачу другому экземпляру.

3. Инфраструктурные компоненты

  • MongoDB Replica Set (3 узла) — персистентное хранение всех задач и результатов.
  • RabbitMQ — брокер сообщений с персистентными очередями и ручным подтверждением (manual ack).
  • Docker Swarm — оркестрация контейнеров на кластере из 5 узлов (1 менеджер + 4 воркера).
    Это нужно, чтобы gateway держался отдельно, чтобы его перезапуск не влиял на базу или worker.
    RabbitMQ лучше тоже держать отдельно, чтобы брокер не конкурировал с БД.

Отказоустойчивость

Вид сбоя Поведение системы
Остановка менеджера Состояние задач сохранено в MongoDB. При перезапуске менеджер заново отправляет в очередь задачи со статусом PENDING_WORKER и получает накопившиеся ответы.
Остановка primary‑узла MongoDB Replica Set автоматически выбирает нового лидера. Система продолжает работу без потери данных.
Остановка RabbitMQ Gateway сохраняет задачи в БД со статусом PENDING_QUEUE и повторяет отправку после восстановления брокера. Сообщения в очередях персистентны и не теряются при рестарте RabbitMQ.
Падение воркера во время обработки Сообщение остаётся неподтверждённым (unacked). RabbitMQ возвращает его в очередь и передаёт другому воркеру.
Отсутствие доступных воркеров в момент создания задачи Сообщения накапливаются в очереди и будут обработаны сразу после появления воркеров.

Технологии

  • Язык: Kotlin
  • Фреймворк: Ktor (Gateway)
  • API: GraphQL (graphql-kotlin)
  • Брокер сообщений: RabbitMQ (AMQP 0-9-1)
  • Хранилище: MongoDB 7.0 (Replica Set, Write Concern majority)
  • Сериализация: JSON (kotlinx.serialization)
  • Оркестрация: Docker, Docker Swarm
  • Эмуляция кластера: Docker-in-Docker (dind)
  • Нагрузочное тестирование: k6

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

CrackHash/
├── common/                # общие классы (модели сообщений, сервис RabbitMQ)
├── gateway/               # Ktor-приложение с GraphQL API и логикой менеджера
├── worker/                # вычислительный сервис – перебор MD5
├── docker-compose.yml     # описание стека (для Docker Swarm)
├── docker-compose.local.yml # описание для локального запуска
├── mongo-init.js          # скрипт инициализации репликасета MongoDB
├── index.html             # простой веб-клиент
├── gateway/src/test/test.ps1          # скрипт для запуска задачи
├── gateway/src/test/check_status.ps1  # скрипт проверки статуса
└── README.md

Быстрый локальный запуск (Docker Compose)

Используется для разработки и отладки. Все сервисы запускаются на одном хосте в bridge-сети.

  1. Убедитесь, что Docker Desktop запущен и переключён на Linux‑контейнеры.

  2. Создайте docker-compose.local.yml на основе основного файла, заменив драйвер сети на bridge (или просто используйте готовый файл, где уже стоит driver: bridge).
    В текущем docker-compose.yml уже указан driver: bridge – его можно использовать как есть для локального запуска.

  3. Соберите и запустите стек:

    docker compose -f docker-compose.local.yml up --build

    Для масштабирования используйте:

    docker compose -f docker-compose.local.yml up --scale worker=3

Первый раз MongoDB скачается с Docker Hub, а Gateway и Worker соберутся из исходников.

  1. Дождитесь инициализации репликасета
    Сервис mongo-init выполнит скрипт mongo-init.js и выведет Replica set initiated.
    В логах Gateway должно появиться Responding at http://0.0.0.0:8080.

  2. Отправьте тестовую задачу (PowerShell):

    .\gateway\src\test\test.ps1

    Вы получите requestId.

  3. Проверьте статус:

    .\gateway\src\test\check_status.ps1 -RequestId "ваш-requestId"

    Статус сменится с IN_PROGRESS на READY, когда все части обработаны.

  4. Графический веб-клиент: откройте index.html в браузере, введите хэш и максимальную длину, нажмите «Взломать».

  5. Остановка:

    docker compose -f docker-compose.local.yml down -v

Запуск в Docker Swarm (на одной машине)

Для эмуляции кластера из 5 узлов используется Docker-in-Docker (dind).

Подготовка образов

.\make_images.ps1

Создание виртуальных узлов и деплой

  1. Запустите 5 dind‑контейнеров:

    .\create_nodes.ps1
  2. Инициализируйте Swarm и получите токены присоединения к кластеру:

         docker exec -it node-1 sh -c "docker swarm init"
         docker exec -it node-1 sh -c "docker swarm join-token manager"
  3. Присоедините их к кластеру:

    .\attach_nodes_to_cluster.ps1 -WorkerToken <ваш токен воркера> -ManagerToken <ваш токен менеджера>
  4. Навесьте метки узлов (для фиксированного размещения сервисов):

    .\adding_labels_to_nodes.ps1
  5. Перенесите нужные файлы и образы на узлы (на которых они потребуются):

    .\load_data_to_nodes.ps1
  6. Задеплойте стек:

    docker exec -it node-1 sh -c "docker stack deploy -c /docker-compose.yml crackhash"
  7. Проверьте состояние:

    docker exec -it node-1 sh -c "docker stack services crackhash"
    docker exec -it node-1 sh -c "docker stack ps crackhash"
  8. Инициализация репликасета MongoDB – сервис mongo-init сделает это автоматически.

  9. Тестирование – Gateway доступен на порту 8080 любого узла Swarm (mesh‑сеть). Используйте test.ps1 и index.html.


Просмотр содержимого MongoDB

Подключитесь к контейнеру primary‑узла (обычно mongo1):

# Локальный запуск
docker exec -it crackhash-mongo1-1 mongosh
# В Swarm – узнайте ID контейнера через docker ps и выполните docker exec

Внутри оболочки:

use crackhash
db.tasks.find().pretty()

Для поиска конкретной задачи:

db.tasks.find({ requestId: "идентификатор" }).pretty()

Дополнительные скрипты

  • gateway/src/test/test.ps1 – отправляет GraphQL‑мутацию на взлом.
  • gateway/src/test/result_test.ps1 – запрашивает статус по requestId.

Web‑клиент

Файл index.html содержит простой веб‑интерфейс:

  • Поле для MD5‑хэша и максимальной длины слова.
  • Кнопка «Взломать» отправляет мутацию, затем автоматически опрашивает статус.
  • Отображает найденные слова.

Для работы требует включённого CORS на Gateway (добавлен плагин ktor-server-cors).


Заключение

Данная система демонстрирует принципы построения отказоустойчивых распределённых приложений:

  • Асинхронная обработка через очереди сообщений.
  • Персистентное хранение состояния с автоматическим восстановлением.
  • Репликация базы данных для защиты от потери узла.
  • Оркестрация контейнеров для автоматического перезапуска и масштабирования.

About

A distributed system for calculating MD5 hashes. Developed as part of the "Distributed Information Systems" course at the NSU Faculty of Information Technologies.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors