lab 2 is ready #86
84
volkov_rafael_lab_2/README.md
Normal file
@ -0,0 +1,84 @@
|
||||
# Лабораторная работа №2 - Разработка простейшего распределенного приложения
|
||||
|
||||
Цель: изучение техники создания простого распределенного приложения.
|
||||
|
||||
Задачи:
|
||||
|
||||
- Согласно вышему варианту (выбирайте любой) разработать два приложения такие, что результат первого является исходными данными для второго.
|
||||
- Изучить файлы сборки образов docker и разработать их для созданных приложений.
|
||||
- Собрать файл docker-compose.yml для запуска приложений. Разобраться с монтированием каталогов из хост-системы.
|
||||
- Правильно закоммитить результат без лишних файлов.
|
||||
- Оформить pull request по правилам и отправить его на проверку.
|
||||
|
||||
# Описание заданий двух приложений
|
||||
|
||||
Вариант первого приложения(worker-1): 1 - Ищет в каталоге /var/data файл с наибольшим количеством строк и перекладывает его в /var/result/data.txt
|
||||
Вариант второго приложения(worker-2): 0 - сохраняет произведение первого и последнего числа из файла /var/result/data.txt в /var/result/result.txt
|
||||
|
||||
<p>
|
||||
<div>Cтруктура проекта</div>
|
||||
<img src="screens/img1.png" width="650" title="Cтруктура проекта">
|
||||
</p>
|
||||
|
||||
# Работа программы
|
||||
|
||||
- Создано две директории: worker-1 и worker-2 для двух программ.
|
||||
- Dockerfile для образов обоих программ.
|
||||
<p>
|
||||
<div>Worker-1 Dockerfile</div>
|
||||
<img src="screens/img2.png" width="650" title="Worker-1 Dockerfile">
|
||||
</p>
|
||||
<p>
|
||||
<div>Worker-2 Dockerfile</div>
|
||||
<img src="screens/img3.png" width="650" title="Worker-2 Dockerfile">
|
||||
</p>
|
||||
- Содержимое в файлах в папке data
|
||||
<p>
|
||||
<img src="screens/img4.png" width="50" title="1">
|
||||
</p>
|
||||
<p>
|
||||
<img src="screens/img5.png" width="50" title="2">
|
||||
</p>
|
||||
<p>
|
||||
<img src="screens/img6.png" width="50" title="3">
|
||||
</p>
|
||||
- Описание docker-compose: запускает контейнеры, реализует build для создания образов на основе dockerfile и у второго контейнера описавыется зависимость depends_on от первого контейнера, чтобы сначала запустился первый контейнер, а за ним запустился второй. Также описываются volumes, для монтирование папок data и result в контейнеры.
|
||||
<p>
|
||||
<div>docker-compose</div>
|
||||
<img src="screens/img7.png" width="650" title="docker-compose">
|
||||
</p>
|
||||
<p>
|
||||
<div>Сборка и запуска контейнеров</div>
|
||||
<img src="screens/img8.png" width="650" title="Сборка и запуска контейнеров">
|
||||
</p>
|
||||
<p>
|
||||
<div>Docker Desktop контейнеры и образы</div>
|
||||
<img src="screens/img9.png" width="650" title="Docker Desktop контейнеры и образы">
|
||||
</p>
|
||||
<p>
|
||||
<img src="screens/img10.png" width="650" title="Проверка в Docker Desktop контейнеров и образов">
|
||||
</p>
|
||||
<p>
|
||||
<div>Консоль первого воркера</div>
|
||||
<img src="screens/img11.png" width="650" title="Консоль первого воркера">
|
||||
</p>
|
||||
<p>
|
||||
<div>Консоль второго воркера</div>
|
||||
<img src="screens/img12.png" width="650" title="Консоль второго воркера">
|
||||
</p>
|
||||
<p>
|
||||
<div>Результат работы контейнера, папка result два файла data.txt и result.txt</div>
|
||||
<img src="screens/img13.png" width="150" title="Результат работы контейнера, папка result два файла data.txt и result.txt">
|
||||
</p>
|
||||
<p>
|
||||
<div>Содержимое data.txt</div>
|
||||
<img src="screens/img14.png" width="50" title="Содержимое data.txt">
|
||||
</p>
|
||||
<p>
|
||||
<div>Содержимое result.txt</div>
|
||||
<img src="screens/img15.png" width="150" title="Содержимое result.txt">
|
||||
</p>
|
||||
|
||||
# Видео
|
||||
|
||||
Видео с разбором лабораторной работы - https://drive.google.com/file/d/1-sLDH9PPFeHlEqzfLtcerbGs8sCALaxe/view?usp=sharing
|
3
volkov_rafael_lab_2/data/f1.txt
Normal file
@ -0,0 +1,3 @@
|
||||
11 12 13
|
||||
21 22
|
||||
31 34
|
2
volkov_rafael_lab_2/data/f2.txt
Normal file
@ -0,0 +1,2 @@
|
||||
45
|
||||
23 78
|
4
volkov_rafael_lab_2/data/f3.txt
Normal file
@ -0,0 +1,4 @@
|
||||
52 345
|
||||
23 345
|
||||
23 67
|
||||
23 20
|
17
volkov_rafael_lab_2/docker-compose.yml
Normal file
@ -0,0 +1,17 @@
|
||||
services:
|
||||
worker-1:
|
||||
build:
|
||||
context: /worker-1
|
||||
dockerfile: Dockerfile
|
||||
volumes:
|
||||
- D:\RVIP\volkov_rafael_lab_2\data:/var/data
|
||||
- D:\RVIP\volkov_rafael_lab_2\result:/var/result
|
||||
worker-2:
|
||||
build:
|
||||
context: /worker-2
|
||||
dockerfile: Dockerfile
|
||||
volumes:
|
||||
- D:\RVIP\volkov_rafael_lab_2\data:/var/data
|
||||
- D:\RVIP\volkov_rafael_lab_2\result:/var/result
|
||||
depends_on:
|
||||
- worker-1
|
4
volkov_rafael_lab_2/result/data.txt
Normal file
@ -0,0 +1,4 @@
|
||||
52 345
|
||||
23 345
|
||||
23 67
|
||||
23 20
|
1
volkov_rafael_lab_2/result/result.txt
Normal file
@ -0,0 +1 @@
|
||||
1040
|
BIN
volkov_rafael_lab_2/screens/img1.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
volkov_rafael_lab_2/screens/img10.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
volkov_rafael_lab_2/screens/img11.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
volkov_rafael_lab_2/screens/img12.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
volkov_rafael_lab_2/screens/img13.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
volkov_rafael_lab_2/screens/img14.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
volkov_rafael_lab_2/screens/img15.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
volkov_rafael_lab_2/screens/img2.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
volkov_rafael_lab_2/screens/img3.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
volkov_rafael_lab_2/screens/img4.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
volkov_rafael_lab_2/screens/img5.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
volkov_rafael_lab_2/screens/img6.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
volkov_rafael_lab_2/screens/img7.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
volkov_rafael_lab_2/screens/img8.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
volkov_rafael_lab_2/screens/img9.png
Normal file
After Width: | Height: | Size: 24 KiB |
29
volkov_rafael_lab_2/worker-1/.gitignore
vendored
Normal 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
|
18
volkov_rafael_lab_2/worker-1/Dockerfile
Normal file
@ -0,0 +1,18 @@
|
||||
# Используем образ с Java
|
||||
FROM openjdk:21
|
||||
|
||||
# Создаем директории для данных и результата внутри контейнера
|
||||
RUN mkdir /var/data
|
||||
RUN mkdir /var/result
|
||||
|
||||
# Создаем директорию приложения внутри контейнера
|
||||
WORKDIR /app
|
||||
|
||||
# Копируем исходные файлы вашего Java-приложения внутрь контейнера
|
||||
COPY src /app/src
|
||||
|
||||
# Компилируем Java-код
|
||||
RUN javac /app/src/FileCopyMaxLines.java
|
||||
|
||||
# Запускаем Java-приложение
|
||||
CMD ["java", "-cp", "/app/src", "FileCopyMaxLines"]
|
58
volkov_rafael_lab_2/worker-1/src/FileCopyMaxLines.java
Normal file
@ -0,0 +1,58 @@
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
|
||||
public class FileCopyMaxLines {
|
||||
public static void main(String[] args) {
|
||||
String sourceDir = "/var/data";
|
||||
String destinationFile = "/var/result/data.txt";
|
||||
|
||||
try {
|
||||
// Создаем файл, если он не существует
|
||||
File file = new File(destinationFile);
|
||||
if (!file.exists()) {
|
||||
if (!file.createNewFile()) {
|
||||
System.err.println("Ошибка при создании файла.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Читаем содержимое каталога
|
||||
File[] files = new File(sourceDir).listFiles();
|
||||
if (files != null) {
|
||||
int maxLines = 0;
|
||||
String maxLinesFile = null;
|
||||
|
||||
// Ищем файл с наибольшим количеством строк
|
||||
for (File f : files) {
|
||||
if (!f.isDirectory()) {
|
||||
String filePath = f.getAbsolutePath();
|
||||
int lines = countLines(filePath);
|
||||
if (lines > maxLines) {
|
||||
maxLines = lines;
|
||||
maxLinesFile = filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (maxLinesFile != null) {
|
||||
// Копируем содержимое файла с наибольшим количеством строк в целевой файл
|
||||
Path sourcePath = Paths.get(maxLinesFile);
|
||||
byte[] data = Files.readAllBytes(sourcePath);
|
||||
Files.write(Paths.get(destinationFile), data, StandardOpenOption.CREATE);
|
||||
System.out.printf("Файл %s с наибольшим количеством строк (%d) скопирован в %s\n", maxLinesFile, maxLines, destinationFile);
|
||||
} else {
|
||||
System.out.println("Не удалось найти файлы в каталоге /var/data.");
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Метод для подсчета количества строк в файле
|
||||
private static int countLines(String filePath) throws IOException {
|
||||
byte[] data = Files.readAllBytes(Paths.get(filePath));
|
||||
return new String(data).split("\r\n|\r|\n").length;
|
||||
}
|
||||
}
|
14
volkov_rafael_lab_2/worker-1/worker-1.iml
Normal file
@ -0,0 +1,14 @@
|
||||
<?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>
|
||||
<component name="SonarLintModuleSettings">
|
||||
<option name="uniqueId" value="a8341579-2851-407d-ad6a-b2b7f768ee65" />
|
||||
</component>
|
||||
</module>
|
29
volkov_rafael_lab_2/worker-2/.gitignore
vendored
Normal 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
|
18
volkov_rafael_lab_2/worker-2/Dockerfile
Normal file
@ -0,0 +1,18 @@
|
||||
# Используем образ с Java
|
||||
FROM openjdk:21
|
||||
|
||||
# Создаем директории для данных и результата внутри контейнера
|
||||
RUN mkdir /var/data
|
||||
RUN mkdir /var/result
|
||||
|
||||
# Создаем директорию приложения внутри контейнера
|
||||
WORKDIR /app
|
||||
|
||||
# Копируем исходные файлы вашего Java-приложения внутрь контейнера
|
||||
COPY src /app/src
|
||||
|
||||
# Компилируем Java-код
|
||||
RUN javac /app/src/MultiplyFirstLast.java
|
||||
|
||||
# Запускаем Java-приложение
|
||||
CMD ["java", "-cp", "/app/src", "MultiplyFirstLast"]
|
79
volkov_rafael_lab_2/worker-2/src/MultiplyFirstLast.java
Normal file
@ -0,0 +1,79 @@
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class MultiplyFirstLast {
|
||||
public static void main(String[] args) {
|
||||
String dataFilePath = "/var/result/data.txt";
|
||||
String resultFilePath = "/var/result/result.txt";
|
||||
|
||||
try {
|
||||
// Создаем файл, если он не существует
|
||||
File resultFile = new File(resultFilePath);
|
||||
if (!resultFile.exists()) {
|
||||
if (!resultFile.createNewFile()) {
|
||||
System.err.println("Ошибка при создании файла.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Проверяем существование файла data.txt
|
||||
File dataFile = new File(dataFilePath);
|
||||
if (!dataFile.exists()) {
|
||||
System.err.println("Файл data.txt не существует. Пожалуйста, выполните первую программу перед запуском второй.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Читаем содержимое файла data.txt
|
||||
StringBuilder content = new StringBuilder();
|
||||
try (Scanner scanner = new Scanner(dataFile)) {
|
||||
while (scanner.hasNextLine()) {
|
||||
content.append(scanner.nextLine()).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
String[] lines = content.toString().split("\\r?\\n");
|
||||
|
||||
int first = 0;
|
||||
int last = 0;
|
||||
boolean firstFound = false;
|
||||
boolean numbersFound = false;
|
||||
|
||||
for (String line : lines) {
|
||||
String[] numbers = line.split("\\s+");
|
||||
if (numbers.length > 0) {
|
||||
// Преобразуем первое и последнее число в числа с плавающей точкой
|
||||
if (!firstFound) {
|
||||
first = Integer.parseInt(numbers[0]);
|
||||
firstFound = true;
|
||||
}
|
||||
last = Integer.parseInt(numbers[numbers.length - 1]);
|
||||
numbersFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!numbersFound) {
|
||||
System.err.printf("Не найдены числа в файле %s%n", dataFilePath);
|
||||
return;
|
||||
}
|
||||
|
||||
int result = first * last;
|
||||
String outputContent = String.valueOf(result);
|
||||
|
||||
// Записываем результат в файл result.txt
|
||||
try (FileWriter writer = new FileWriter(resultFilePath)) {
|
||||
writer.write(outputContent);
|
||||
}
|
||||
|
||||
System.out.printf("Результат (%d) сохранен в файл %s%n", result, resultFilePath);
|
||||
|
||||
// Читаем и выводим результат из файла result.txt
|
||||
String resultContent = new String(Files.readAllBytes(Paths.get(resultFilePath)));
|
||||
System.out.println("Результат, лежащий в файле result - " + resultContent);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
14
volkov_rafael_lab_2/worker-2/worker-2.iml
Normal file
@ -0,0 +1,14 @@
|
||||
<?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>
|
||||
<component name="SonarLintModuleSettings">
|
||||
<option name="uniqueId" value="ca0d01ae-0c7f-4c2c-b85f-2442b28d754e" />
|
||||
</component>
|
||||
</module>
|