From 9808787f2768b21be9e4de618f674d9635b66b41 Mon Sep 17 00:00:00 2001 From: Pavel <––ƒ––iputilin201@gmail.com> Date: Mon, 2 Dec 2024 23:12:59 +0400 Subject: [PATCH] putilin_pavel_lab_2 --- putilin_pavel_lab_2/README.md | 82 +++++++++++++++++++ .../data_generator/data_generator.py | 14 ++++ putilin_pavel_lab_2/docker-compose.yml | 25 ++++++ putilin_pavel_lab_2/worker_1/Dockerfile | 4 + putilin_pavel_lab_2/worker_1/app.py | 12 +++ putilin_pavel_lab_2/worker_2/Dockerfile | 4 + putilin_pavel_lab_2/worker_2/app.py | 9 ++ 7 files changed, 150 insertions(+) create mode 100644 putilin_pavel_lab_2/README.md create mode 100644 putilin_pavel_lab_2/data_generator/data_generator.py create mode 100644 putilin_pavel_lab_2/docker-compose.yml create mode 100644 putilin_pavel_lab_2/worker_1/Dockerfile create mode 100644 putilin_pavel_lab_2/worker_1/app.py create mode 100644 putilin_pavel_lab_2/worker_2/Dockerfile create mode 100644 putilin_pavel_lab_2/worker_2/app.py diff --git a/putilin_pavel_lab_2/README.md b/putilin_pavel_lab_2/README.md new file mode 100644 index 0000000..e52bdd3 --- /dev/null +++ b/putilin_pavel_lab_2/README.md @@ -0,0 +1,82 @@ +# Лабораторная работа №2 - Разработка простейшего распределённого приложения + +## Задание + +**Цель**: Разработать два приложения, результат работы первого из которых становится входными данными для второго. + +**Задачи**: +1. Разработать два приложения: + - **worker_1**: Считывает файл с целыми числами, умножает каждое число на 2 и сохраняет результат в новый файл. + - **worker_2**: Считывает файл, созданный `worker_1`, вычисляет сумму чисел и выводит результат. +2. Разработать файлы сборки Docker для каждого приложения. +3. Собрать файл `docker-compose.yml` для запуска обоих приложений. +4. Настроить монтирование директорий для обмена данными между контейнерами. +5. Организовать генерацию входных данных с помощью скрипта `data_gen.py`. +6. Правильно закоммитить решение с использованием `.gitignore` для исключения лишних файлов. + +## Описание решения + +### Программы + +1. **data_generator/data_gen.py**: + - Генерирует случайные целые числа и сохраняет их в файл `input.txt` в папке `data`. + +2. **worker_1/app.py**: + - Читает файл `input.txt`, умножает числа на 2 и сохраняет результат в `output_worker1.txt`. + +3. **worker_2/app.py**: + - Читает файл `output_worker1.txt`, вычисляет сумму чисел и выводит результат на экран. + +### Генерация данных + +Скрипт `data_gen.py` создаёт файл `input.txt` с 20 случайными числами в диапазоне от 1 до 100. Если папка `data` отсутствует, скрипт создаёт её автоматически. + +### Docker + +1. **Dockerfile для `worker_1`**: + - Устанавливает Python. + - Копирует скрипт `app.py`. + - Устанавливает рабочую директорию `/app`. + - Запускает `app.py`. + +2. **Dockerfile для `worker_2`**: + - Устанавливает Python. + - Копирует скрипт `app.py`. + - Устанавливает рабочую директорию `/app`. + - Запускает `app.py`. + +### Docker Compose + +Файл `docker-compose.yml` управляет запуском трёх сервисов: +1. **data_generator** — генерирует входные данные. +2. **worker_1** — обрабатывает данные из `input.txt` и создаёт `output_worker1.txt`. +3. **worker_2** — читает `output_worker1.txt`, вычисляет сумму чисел и выводит результат. + +Монтирование директорий обеспечивает обмен файлами между контейнерами. + +### Сборка и запуск + +1. Генерация данных: + ``` + docker-compose run data_generator + ``` +2. Запуск всех сервисов: + ``` + docker-compose up --build + ``` + +### Результаты + +После выполнения команд: +- **input.txt** — файл, созданный `data_generator`, содержащий случайные числа. +- **output_worker1.txt** — файл, созданный `worker_1`, содержащий числа, умноженные на 2. +- Конечный результат (сумма чисел) выводится в консоль `worker_2`. + +## Вывод + +В результате лабораторной работы было создано простейшее распределённое приложение с использованием Docker и Docker Compose. Реализация демонстрирует базовые подходы к созданию контейнеризированных приложений, обмену данными между контейнерами и автоматизации обработки данных. + +**Видео демонстрации**: + +Ссылка: https://cloud.mail.ru/public/83jj/3fGCcVQcK + diff --git a/putilin_pavel_lab_2/data_generator/data_generator.py b/putilin_pavel_lab_2/data_generator/data_generator.py new file mode 100644 index 0000000..0febf98 --- /dev/null +++ b/putilin_pavel_lab_2/data_generator/data_generator.py @@ -0,0 +1,14 @@ +import random +import os + +def generate_data(file_path, count=10): + # Создаём директорию, если она не существует + os.makedirs(os.path.dirname(file_path), exist_ok=True) + + with open(file_path, "w") as f: + numbers = [str(random.randint(1, 100)) for _ in range(count)] + f.write("\n".join(numbers)) + +if __name__ == "__main__": + generate_data("../data/input.txt", count=20) + print("Data generated successfully in 'data/input.txt'") diff --git a/putilin_pavel_lab_2/docker-compose.yml b/putilin_pavel_lab_2/docker-compose.yml new file mode 100644 index 0000000..d546578 --- /dev/null +++ b/putilin_pavel_lab_2/docker-compose.yml @@ -0,0 +1,25 @@ +version: "3.9" +services: + data_generator: + image: python:3.10-slim + volumes: + - ./data_generator:/app + - ./data:/data + working_dir: /app + command: python data_gen.py + + worker_1: + build: + context: ./worker_1 + volumes: + - ./data:/data + depends_on: + - data_generator + + worker_2: + build: + context: ./worker_2 + volumes: + - ./data:/data + depends_on: + - worker_1 diff --git a/putilin_pavel_lab_2/worker_1/Dockerfile b/putilin_pavel_lab_2/worker_1/Dockerfile new file mode 100644 index 0000000..e465753 --- /dev/null +++ b/putilin_pavel_lab_2/worker_1/Dockerfile @@ -0,0 +1,4 @@ +FROM python:3.10-slim +WORKDIR /app +COPY app.py /app +CMD ["python", "app.py"] diff --git a/putilin_pavel_lab_2/worker_1/app.py b/putilin_pavel_lab_2/worker_1/app.py new file mode 100644 index 0000000..f4c6432 --- /dev/null +++ b/putilin_pavel_lab_2/worker_1/app.py @@ -0,0 +1,12 @@ +def process_data(input_file, output_file): + with open(input_file, "r") as f: + numbers = [int(line.strip()) for line in f.readlines()] + + processed_numbers = [n * 2 for n in numbers] + + with open(output_file, "w") as f: + f.write("\n".join(map(str, processed_numbers))) + +if __name__ == "__main__": + process_data("/data/input.txt", "/data/output_worker1.txt") + print("Worker 1 processing complete.") diff --git a/putilin_pavel_lab_2/worker_2/Dockerfile b/putilin_pavel_lab_2/worker_2/Dockerfile new file mode 100644 index 0000000..e465753 --- /dev/null +++ b/putilin_pavel_lab_2/worker_2/Dockerfile @@ -0,0 +1,4 @@ +FROM python:3.10-slim +WORKDIR /app +COPY app.py /app +CMD ["python", "app.py"] diff --git a/putilin_pavel_lab_2/worker_2/app.py b/putilin_pavel_lab_2/worker_2/app.py new file mode 100644 index 0000000..e72fb65 --- /dev/null +++ b/putilin_pavel_lab_2/worker_2/app.py @@ -0,0 +1,9 @@ +def calculate_sum(input_file): + with open(input_file, "r") as f: + numbers = [int(line.strip()) for line in f.readlines()] + + total = sum(numbers) + print(f"The sum of the processed numbers is: {total}") + +if __name__ == "__main__": + calculate_sum("/data/output_worker1.txt")