выполненное 2 задание
This commit is contained in:
38
yaruskin_salikh_lab_2/README.md
Normal file
38
yaruskin_salikh_lab_2/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Лабораторная 2 — два Java‑воркера под Docker Compose
|
||||
|
||||
## Цели и задачи
|
||||
- Реализовать два приложения, где выход первого является входом второго.
|
||||
- Собрать образы через Dockerfile и запустить вместе через docker-compose.
|
||||
- Отработать маунты каталогов с хоста в контейнеры.
|
||||
|
||||
## Описание программы
|
||||
- `worker-1`: читает каталог `/var/data`, берет первую строку из каждого файла и пишет их в `/var/result/data.txt`.
|
||||
- `worker-2`: читает числа из `/var/data/data.txt`, находит минимальное, считает число вхождений, сохраняет счетчик в `/var/result/result.txt` и выводит результат в консоль.
|
||||
|
||||
## Используемые технологии
|
||||
- Java 17 (Eclipse Temurin JDK).
|
||||
- Docker + Docker Compose (два сервиса, отдельные Dockerfile).
|
||||
|
||||
## Описание работы
|
||||
### Выбранные варианта:
|
||||
Вариант программы 1:
|
||||
- 2 Формирует файл /var/result/data.txt из первых строк всех файлов каталога /var/data.
|
||||
Вариант программы 2:
|
||||
- 4 Ищет наименьшее число из файла /var/data/data.txt и сохраняет количество таких чисел из последовательности в /var/result/result.txt.
|
||||
### Описание работы
|
||||
1. `worker-1` получает файлы с целыми числами (по одному набору в первой строке) из примонтированного каталога `/var/data` и формирует объединенный файл `data.txt` в `/var/result`.
|
||||
2. `worker-2` ждет появления `data.txt`, затем считывает все числа, находит минимум и количество его повторов, пишет счетчик в `result.txt`, выводит минимум и счетчик в stdout.
|
||||
|
||||
## Инструкция по запуску
|
||||
1. Docker и Docker Compose должны быть установлены установлены
|
||||
2. В каталог `input/` положите входные файлы с числами (в файлах уже есть тестовые данные).
|
||||
3. Из каталога `yaruskin_salikh_lab_2` выполните:
|
||||
```sh
|
||||
docker compose up --build
|
||||
```
|
||||
4. Результаты:
|
||||
- Объединенный файл после `worker-1`: `shared/data.txt`.
|
||||
- Итог `worker-2`: `output/result.txt` и вывод в логах контейнера `worker2`.
|
||||
|
||||
5. Ссылка на видео:
|
||||
https://disk.yandex.ru/i/httWu3SrCr2liw
|
||||
15
yaruskin_salikh_lab_2/docker-compose.yml
Normal file
15
yaruskin_salikh_lab_2/docker-compose.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
services:
|
||||
worker1:
|
||||
build: ./worker-1
|
||||
volumes:
|
||||
- ./input:/var/data:ro
|
||||
- ./shared:/var/result
|
||||
|
||||
worker2:
|
||||
build: ./worker-2
|
||||
depends_on:
|
||||
- worker1
|
||||
command: ["/bin/sh", "-c", "while [ ! -f /var/data/data.txt ]; do echo 'Waiting for data from worker1...'; sleep 1; done; exec java Main"]
|
||||
volumes:
|
||||
- ./shared:/var/data
|
||||
- ./output:/var/result
|
||||
1
yaruskin_salikh_lab_2/input/sample1.txt
Normal file
1
yaruskin_salikh_lab_2/input/sample1.txt
Normal file
@@ -0,0 +1 @@
|
||||
10 5 3 3 9
|
||||
1
yaruskin_salikh_lab_2/input/sample2.txt
Normal file
1
yaruskin_salikh_lab_2/input/sample2.txt
Normal file
@@ -0,0 +1 @@
|
||||
7 7 2 2 5 2
|
||||
1
yaruskin_salikh_lab_2/output/result.txt
Normal file
1
yaruskin_salikh_lab_2/output/result.txt
Normal file
@@ -0,0 +1 @@
|
||||
3
|
||||
2
yaruskin_salikh_lab_2/shared/data.txt
Normal file
2
yaruskin_salikh_lab_2/shared/data.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
10 5 3 3 9
|
||||
7 7 2 2 5 2
|
||||
14
yaruskin_salikh_lab_2/worker-1/Dockerfile
Normal file
14
yaruskin_salikh_lab_2/worker-1/Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
||||
# Используем официальный базовый образ Eclipse Temurin с JDK 17
|
||||
FROM eclipse-temurin:17-jdk-jammy
|
||||
|
||||
# Создаем рабочую директорию внутри контейнера
|
||||
WORKDIR /app
|
||||
|
||||
# Копируем исходный код приложения в образ
|
||||
COPY Main.java .
|
||||
|
||||
# Компилируем Java-файл в байткод
|
||||
RUN javac Main.java
|
||||
|
||||
# Запускаем приложение; каталоги /var/data и /var/result приходят через маунты
|
||||
CMD ["java", "Main"]
|
||||
47
yaruskin_salikh_lab_2/worker-1/Main.java
Normal file
47
yaruskin_salikh_lab_2/worker-1/Main.java
Normal file
@@ -0,0 +1,47 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Path inputDir = Paths.get("/var/data");
|
||||
Path outputDir = Paths.get("/var/result");
|
||||
Path outputFile = outputDir.resolve("data.txt");
|
||||
|
||||
try {
|
||||
Files.createDirectories(outputDir);
|
||||
if (!Files.isDirectory(inputDir)) {
|
||||
System.out.println("Input directory does not exist: " + inputDir);
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> firstLines = new ArrayList<>();
|
||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(inputDir)) {
|
||||
for (Path path : stream) {
|
||||
if (Files.isRegularFile(path)) {
|
||||
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
|
||||
String line = reader.readLine();
|
||||
if (line != null) {
|
||||
firstLines.add(line.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Files.write(outputFile, firstLines, StandardCharsets.UTF_8,
|
||||
java.nio.file.StandardOpenOption.CREATE,
|
||||
java.nio.file.StandardOpenOption.TRUNCATE_EXISTING);
|
||||
System.out.println("Collected " + firstLines.size() + " lines into " + outputFile);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Failed to build data file: " + e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
yaruskin_salikh_lab_2/worker-2/Dockerfile
Normal file
14
yaruskin_salikh_lab_2/worker-2/Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
||||
# Базовый образ с JDK 17: достаточен для компиляции и запуска Java-приложения
|
||||
FROM eclipse-temurin:17-jdk-jammy
|
||||
|
||||
# Рабочая директория, куда копируем исходники
|
||||
WORKDIR /app
|
||||
|
||||
# Копируем исходный файл приложения внутрь образа
|
||||
COPY Main.java .
|
||||
|
||||
# Компилируем Main.java
|
||||
RUN javac Main.java
|
||||
|
||||
# Точка входа контейнера — запуск скомпилированного класса
|
||||
CMD ["java", "Main"]
|
||||
60
yaruskin_salikh_lab_2/worker-2/Main.java
Normal file
60
yaruskin_salikh_lab_2/worker-2/Main.java
Normal file
@@ -0,0 +1,60 @@
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Path inputFile = Paths.get("/var/data/data.txt");
|
||||
Path outputDir = Paths.get("/var/result");
|
||||
Path outputFile = outputDir.resolve("result.txt");
|
||||
|
||||
try {
|
||||
if (!Files.exists(inputFile)) {
|
||||
System.err.println("Input file not found: " + inputFile);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
List<Integer> numbers = readNumbers(inputFile);
|
||||
if (numbers.isEmpty()) {
|
||||
System.err.println("Input file is empty or has no numbers.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
int minValue = numbers.stream().min(Integer::compareTo).orElseThrow();
|
||||
long count = numbers.stream().filter(n -> n == minValue).count();
|
||||
|
||||
Files.createDirectories(outputDir);
|
||||
Files.writeString(outputFile, String.valueOf(count), StandardCharsets.UTF_8,
|
||||
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
|
||||
System.out.println("Min value: " + minValue + ", count: " + count);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to process file: " + e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Integer> readNumbers(Path inputFile) throws IOException {
|
||||
List<String> lines = Files.readAllLines(inputFile, StandardCharsets.UTF_8);
|
||||
List<Integer> numbers = new ArrayList<>();
|
||||
|
||||
for (String line : lines) {
|
||||
if (line == null) {
|
||||
continue;
|
||||
}
|
||||
String[] parts = line.trim().split("\\s+");
|
||||
for (String part : parts) {
|
||||
if (!part.isEmpty()) {
|
||||
numbers.add(Integer.parseInt(part));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return numbers;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user