Merge pull request 'kochkareva_elizaveta_lab_2 is ready' (#146) from kochkareva_elizaveta_lab_2 into main

Reviewed-on: #146
This commit is contained in:
Alexey 2024-12-10 22:16:08 +04:00
commit 815e4e8ef5
20 changed files with 390 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

View File

@ -0,0 +1,194 @@
# Лабораторная работа 2.
### Задание
**Цель**: изучение техники создания простого распределённого приложения.
**Задачи**:
- Разработать два приложения такие, что результат первого является исходными данными для второго.
- Изучить файлы сборки образов docker и разработать их для созданных приложений.
- Собрать файл docker-compose.yml для запуска приложений.
- Разобраться с монтированием каталогов из хост-системы.
**Вариант**:
- Ищет в каталоге /var/data файл с самым коротким названием и перекладывает его в /var/result/data.txt.
- Сохраняет произведение первого и последнего числа из файла /var/data/data.txt в /var/result/result.txt.
### Как запустить лабораторную работу
В директории с файлом характеристик docker-compose.yaml выполнить команду:
```
docker-compose -f docker-compose.yaml up
```
### Описание лабораторной работы
#### Входные данный
В качестве входных данных представлены следующие файлы с соответствующим содержанием:
```
deadlock - file1: 9 5 0 1
diamond - file2: 3 5 8
himera - file3: 4 6 6
kjjuriositi - file4: 3 5 3
nitric-oxide - file5: 3 1 7
V3001TH - file6: 7 2 6
za - file7: 2 4 4
```
#### Первое приложение
Первое приложение выполняет задачу: Ищет в каталоге /var/data файл с самым коротким названием и перекладывает его в /var/result/data.txt.
Для этого напишем следующий код:
```java
File dataDir = new File("/var/data");
File resultDir = new File("/var/result");
// Получаем все файлы в каталоге /var/data
File[] files = dataDir.listFiles();
if (files != null && files.length > 0) {
// Ищем файл с самым коротким названием
File shortestFileName = files[0];
for (File file : files) {
if (file.getName().length() < shortestFileName.getName().length()) {
shortestFileName = file;
}
}
// Перекладываем файл в /var/result/data.txt
File destination = new File(resultDir, "data.txt");
try {
Files.move(shortestFileName.toPath(), destination.toPath(), StandardCopyOption.REPLACE_EXISTING);
System.out.println("Файл успешно перемещен.");
} catch (IOException e) {
System.out.println("Ошибка при перемещении файла: " + e.getMessage());
}
} else {
System.out.println("В каталоге /var/data нет файлов.");
}
```
Также создадим *Dockerfile*, который используется для создания образа контейнера данного приложения.
```dockerfile
# Используем образ Java для компиляции и запуска кода
FROM openjdk:11
# Создание директорий для файлов
RUN ["mkdir", "/var/data"]
RUN ["mkdir", "/var/result"]
# Устанавливаем рабочую директорию внутри контейнера
WORKDIR /app
# Копируем исходный код в контейнер
COPY src/Main.java .
# Компилируем исходный код
RUN javac Main.java
# Устанавливаем команду запуска приложения
CMD ["java", "Main"]
```
#### Второе приложение
Второе приложение выполняет задачу: Сохраняет произведение первого и последнего числа из файла /var/data/data.txt в /var/result/result.txt.
Для этого напишем следующий код:
```java
String inputFile = "/var/result/data.txt";
String outputFile = "/var/result/result.txt";
try (BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
String line;
while ((line = reader.readLine()) != null) {
String[] numbers = line.split("\\s+");
if (numbers.length > 0) {
int firstNumber = Integer.parseInt(numbers[0]);
int lastNumber = Integer.parseInt(numbers[numbers.length - 1]);
int result = firstNumber * lastNumber;
writer.write(String.valueOf(result));
writer.newLine();
}
}
} catch (IOException e) {
e.printStackTrace();
}
```
Также создадим *Dockerfile*, который используется для создания образа контейнера данного приложения.
```dockerfile
# Используем образ Java для компиляции и запуска кода
FROM openjdk:11
# Создание директорий для файлов
RUN ["mkdir", "/var/data"]
RUN ["mkdir", "/var/result"]
# Устанавливаем рабочую директорию внутри контейнера
WORKDIR /app
# Копируем исходный код в контейнер
COPY src/Main.java .
# Компилируем исходный код
RUN javac Main.java
# Устанавливаем команду запуска приложения
CMD ["java", "Main"]
```
### Разворачивание сервисов
Создадим файл docker-compose.yml, который определяет настройки для запуска нескольких сервисов в Docker с использованием Docker Compose.
Первый блок будет определять первый сервис worker-1. Он будет создан на основе контекста сборки /worker-1 и файла Dockerfile. Затем, указанные тома (volumes) будут примонтированы в контейнере. В данном случае, директория .\data на хосте будет примонтирована в /var/data внутри контейнера, а директория .\result на хосте будет примонтирована в /var/result внутри контейнера.
```dockerfile
worker-1:
build:
context: /worker-1
dockerfile: Dockerfile
volumes:
- .\data:/var/data
- .\result:/var/result
```
Второй блок будет определять второй сервис worker-2. Он зависит от сервиса worker-1, поэтому worker-1 будет запущен перед worker-2. Затем, он также будет создан на основе контекста сборки /worker-2 и файла Dockerfile. Аналогично, указанные тома будут примонтированы в контейнере.
```dockerfile
worker-2:
depends_on:
- worker-1
build:
context: /worker-2
dockerfile: Dockerfile
volumes:
- .\result:/var/data
- .\result:/var/result
```
### Запуск
![Сборка docker-compose](LaunchingServices.jpg)
![Первое приложение](FirstApp.jpg)
![Второе приложение](SecondApp.jpg)
Файлы директории data:
```
deadlock - file1: 9 5 0 1
diamond - file2: 3 5 8
himera - file3: 4 6 6
kjjuriositi - file4: 3 5 3
nitric-oxide - file5: 3 1 7
V3001TH - file6: 7 2 6
za - file7: 2 4 4
```
Файлы директории result:
```
data: 2 4 4
result: 8
```
### Видео
https://disk.yandex.ru/i/dFIB-vOqlAip9g

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -0,0 +1 @@
7 2 6

View File

@ -0,0 +1 @@
9 5 0 1

View File

@ -0,0 +1 @@
3 5 8

View File

@ -0,0 +1 @@
3 5 3

View File

@ -0,0 +1 @@
3 1 7

View File

@ -0,0 +1,19 @@
version: '3'
services:
worker-1:
build:
context: /worker-1
dockerfile: Dockerfile
volumes:
- .\data:/var/data
- .\result:/var/result
worker-2:
depends_on:
- worker-1
build:
context: /worker-2
dockerfile: Dockerfile
volumes:
- .\result:/var/data
- .\result:/var/result

View File

@ -0,0 +1 @@
4 6 6

View File

@ -0,0 +1 @@
24

View File

@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,13 @@
# Используем образ Java для компиляции и запуска кода
FROM openjdk:11
# Создание директорий для файлов
RUN ["mkdir", "/var/data"]
RUN ["mkdir", "/var/result"]
# Устанавливаем рабочую директорию внутри контейнера
WORKDIR /app
# Копируем исходный код в контейнер
COPY src/Main.java .
# Компилируем исходный код
RUN javac Main.java
# Устанавливаем команду запуска приложения
CMD ["java", "Main"]

View File

@ -0,0 +1,32 @@
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
public class Main {
public static void main(String[] args) {
File dataDir = new File("/var/data");
File resultDir = new File("/var/result");
// Получаем все файлы в каталоге
File[] files = dataDir.listFiles();
if (files != null && files.length > 0) {
// Ищем файл с самым коротким названием
File shortestFileName = files[0];
for (File file : files) {
if (file.getName().length() < shortestFileName.getName().length()) {
shortestFileName = file;
}
}
// Перекладываем файл
File destination = new File(resultDir, "data.txt");
try {
Files.move(shortestFileName.toPath(), destination.toPath(), StandardCopyOption.REPLACE_EXISTING);
System.out.println("Приложение 1: Файл успешно перемещен.");
} catch (IOException e) {
System.out.println("Приложение 1: Ошибка при перемещении файла: " + e.getMessage());
}
} else {
System.out.println("Приложение 1: В каталоге /var/data нет файлов.");
}
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,29 @@
### IntelliJ IDEA ###
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,13 @@
# Используем образ Java для компиляции и запуска кода
FROM openjdk:11
# Создание директорий для файлов
RUN ["mkdir", "/var/data"]
RUN ["mkdir", "/var/result"]
# Устанавливаем рабочую директорию внутри контейнера
WORKDIR /app
# Копируем исходный код в контейнер
COPY src/Main.java .
# Компилируем исходный код
RUN javac Main.java
# Устанавливаем команду запуска приложения
CMD ["java", "Main"]

View File

@ -0,0 +1,32 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
String inputFile = "/var/result/data.txt";
String outputFile = "/var/result/result.txt";
try (BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
String line;
while ((line = reader.readLine()) != null) {
String[] numbers = line.split("\\s+");
if (numbers.length > 0) {
int firstNumber = Integer.parseInt(numbers[0]);
int lastNumber = Integer.parseInt(numbers[numbers.length - 1]);
int result = firstNumber * lastNumber;
System.out.println("Приложение 2: Результат умножения первого и последнего числа: " + result);
writer.write(String.valueOf(result));
writer.newLine();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>