194 lines
7.8 KiB
Markdown
194 lines
7.8 KiB
Markdown
|
||
# Лабораторная работа 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 |