forked from Alexey/DAS_2024_1
Compare commits
2 Commits
polevoy_se
...
emelyanov_
| Author | SHA1 | Date | |
|---|---|---|---|
| 0590f7b532 | |||
| 0eec58a347 |
23
emelyanov_artem_lab_2/README.md
Normal file
23
emelyanov_artem_lab_2/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Распределённое приложение для поиска файлов и обработки чисел
|
||||
## Описаниe
|
||||
Данное распределённое приложение состоит из двух консольных Java-приложений, которые работают в контейнерах Docker. Приложения выполняют следующие задачи:
|
||||
|
||||
### file-finder:
|
||||
Ищет самый большой файл в директории /var/data и копирует его в /var/result/data.txt.
|
||||
### number-processor:
|
||||
Считывает числа из файла /var/result/data.txt и сохраняет произведение первого и последнего числа в файл /var/result/result.txt.
|
||||
|
||||
#### Приложения работают совместно через Docker Compose, используя общий том для передачи файлов между контейнерами.
|
||||
|
||||
### Как запустить
|
||||
1. #### Подготовка данных
|
||||
Убедитесь, что в директории data находятся файлы, которые вы хотите обработать. Это могут быть текстовые файлы с числами.
|
||||
|
||||
2. #### Сборка и запуск контейнеров
|
||||
Выполните команду для сборки и запуска контейнеров с помощью Docker Compose: docker-compose up --build
|
||||
|
||||
3. #### Результаты выполнения
|
||||
#### Приложение file-finder находит самый большой файл в директории /var/data (локально это монтируемая директория data/) и копирует его в файл /var/result/data.txt.
|
||||
#### Приложение number-processor читает файл /var/result/data.txt и сохраняет произведение первого и последнего числа в файл /var/result/result.txt.
|
||||
|
||||
#### Ссылка на видео https://drive.google.com/file/d/1u7nwZdUI4KHC4NzUAXdOABflYswokGwx/view
|
||||
31
emelyanov_artem_lab_2/app_1/.gitignore
vendored
Normal file
31
emelyanov_artem_lab_2/app_1/.gitignore
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
### 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
|
||||
/.idea/modules.xml
|
||||
/.idea/vcs.xml
|
||||
8
emelyanov_artem_lab_2/app_1/.idea/.gitignore
generated
vendored
Normal file
8
emelyanov_artem_lab_2/app_1/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
17
emelyanov_artem_lab_2/app_1/Dockerfile
Normal file
17
emelyanov_artem_lab_2/app_1/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
# Используем базовый образ с установленной JDK
|
||||
FROM openjdk:17-jdk-slim
|
||||
|
||||
# Создаем директорию для исходных файлов
|
||||
RUN mkdir /var/data
|
||||
|
||||
# Создаем директорию для приложения
|
||||
WORKDIR /app
|
||||
|
||||
#Копируем исходные файлы приложения внутрь контейнера
|
||||
COPY src /app/src
|
||||
|
||||
#Компилируем код
|
||||
RUN javac /app/src/Main.java
|
||||
|
||||
# Определяем команду для запуска приложения
|
||||
CMD ["java", "-cp", "/app/src", "Main"]
|
||||
64
emelyanov_artem_lab_2/app_1/src/Main.java
Normal file
64
emelyanov_artem_lab_2/app_1/src/Main.java
Normal file
@@ -0,0 +1,64 @@
|
||||
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) {
|
||||
|
||||
/*
|
||||
Ищет в каталоге /var/data самый большой по объёму файл и перекладывает его в /var/result/data.txt.
|
||||
*/
|
||||
|
||||
File sourceDir = new File("/var/data");
|
||||
File targetFile = new File("/var/result/data.txt");
|
||||
|
||||
// Проверяем, что sourceDir существует и является директорией
|
||||
if (!sourceDir.exists() || !sourceDir.isDirectory()) {
|
||||
System.out.println("Каталог " + sourceDir + " не существует или не является директорией.");
|
||||
return;
|
||||
}
|
||||
|
||||
File[] files = sourceDir.listFiles();
|
||||
if (files == null || files.length == 0) {
|
||||
System.out.println("Каталог " + sourceDir + " пуст.");
|
||||
return;
|
||||
}
|
||||
|
||||
long maxFileSize = -1L;
|
||||
File maxFile = null;
|
||||
|
||||
// Находим файл с максимальным размером
|
||||
for (File item : files) {
|
||||
if (item.isFile() && item.length() > maxFileSize) {
|
||||
maxFileSize = item.length();
|
||||
maxFile = item;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxFile != null) {
|
||||
// Проверяем, существует ли конечная директория, если нет — создаем её
|
||||
File targetDir = targetFile.getParentFile();
|
||||
if (!targetDir.exists()) {
|
||||
boolean dirCreated = targetDir.mkdirs();
|
||||
if (dirCreated) {
|
||||
System.out.println("Директория " + targetDir + " была успешно создана.");
|
||||
} else {
|
||||
System.out.println("Не удалось создать директорию " + targetDir);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Копируем файл
|
||||
Files.copy(maxFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
System.out.println("Самый большой файл: " + maxFile.getName() + " был скопирован в /var/result/data.txt");
|
||||
} catch (IOException e) {
|
||||
System.out.println("Ошибка копирования файла: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
System.out.println("Файлы для копирования не найдены.");
|
||||
}
|
||||
}
|
||||
}
|
||||
30
emelyanov_artem_lab_2/app_2/.gitignore
vendored
Normal file
30
emelyanov_artem_lab_2/app_2/.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
### 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
|
||||
/.idea/misc.xml
|
||||
10
emelyanov_artem_lab_2/app_2/.idea/.gitignore
generated
vendored
Normal file
10
emelyanov_artem_lab_2/app_2/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
/modules.xml
|
||||
/vcs.xml
|
||||
17
emelyanov_artem_lab_2/app_2/Dockerfile
Normal file
17
emelyanov_artem_lab_2/app_2/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
# Используем базовый образ с установленной JDK
|
||||
FROM openjdk:17-jdk-slim
|
||||
|
||||
# Создаем директорию для исходных файлов
|
||||
RUN mkdir /var/data
|
||||
|
||||
# Создаем директорию для приложения
|
||||
WORKDIR /app
|
||||
|
||||
#Копируем исходные файлы приложения внутрь контейнера
|
||||
COPY src /app/src
|
||||
|
||||
#Компилируем код
|
||||
RUN javac /app/src/Main.java
|
||||
|
||||
# Определяем команду для запуска приложения
|
||||
CMD ["java", "-cp", "/app/src", "Main"]
|
||||
46
emelyanov_artem_lab_2/app_2/src/Main.java
Normal file
46
emelyanov_artem_lab_2/app_2/src/Main.java
Normal file
@@ -0,0 +1,46 @@
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main {
|
||||
|
||||
// Сохраняет произведение первого и последнего числа из файла /var/result/data.txt в /var/result/result.txt.
|
||||
public static void main(String[] args) {
|
||||
|
||||
File sourceFile = new File("/var/result/data.txt");
|
||||
File targetFile = new File("/var/result/result.txt");
|
||||
|
||||
int firstNumber = 0;
|
||||
int lastNumber = 0;
|
||||
boolean isFirstNumber = true;
|
||||
|
||||
try (Scanner scanner = new Scanner(sourceFile)) {
|
||||
// Считываем числа
|
||||
while (scanner.hasNextInt()) {
|
||||
int currentNumber = scanner.nextInt();
|
||||
|
||||
if (isFirstNumber) {
|
||||
firstNumber = currentNumber; // Сохраняем первое число
|
||||
isFirstNumber = false;
|
||||
}
|
||||
|
||||
lastNumber = currentNumber; // Последнее число обновляется на каждом шаге
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
System.out.println("Файл не найден: " + ex.getMessage());
|
||||
return; // Выходим, если файл не найден
|
||||
}
|
||||
|
||||
// Рассчитываем произведение первого и последнего числа
|
||||
int result = firstNumber * lastNumber;
|
||||
|
||||
// Сохраняем результат в файл
|
||||
try (PrintWriter writer = new PrintWriter(targetFile)) {
|
||||
writer.println(result);
|
||||
System.out.println("Произведение первого и последнего числа: " + result);
|
||||
} catch (FileNotFoundException ex) {
|
||||
System.out.println("Ошибка записи в файл: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
10
emelyanov_artem_lab_2/data/1.txt
Normal file
10
emelyanov_artem_lab_2/data/1.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
2
|
||||
32
|
||||
1
|
||||
2
|
||||
3
|
||||
54
|
||||
64
|
||||
4
|
||||
3
|
||||
3
|
||||
12
emelyanov_artem_lab_2/data/2.txt
Normal file
12
emelyanov_artem_lab_2/data/2.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
12
|
||||
4
|
||||
12
|
||||
3
|
||||
21
|
||||
3
|
||||
12
|
||||
1
|
||||
3
|
||||
32
|
||||
2
|
||||
5
|
||||
9
emelyanov_artem_lab_2/data/3.txt
Normal file
9
emelyanov_artem_lab_2/data/3.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
12
|
||||
2
|
||||
1
|
||||
2
|
||||
4
|
||||
3
|
||||
1
|
||||
2
|
||||
3
|
||||
21
emelyanov_artem_lab_2/docker-compose.yml
Normal file
21
emelyanov_artem_lab_2/docker-compose.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
version: '3'
|
||||
services:
|
||||
file-finder:
|
||||
build:
|
||||
context: ./app_1 # Путь к первому приложению
|
||||
dockerfile: Dockerfile
|
||||
volumes:
|
||||
- C:/Users/Admin/Desktop/УлГТУ/Распределенные вычисления и приложения/DAS_2024_1/emelyanov_artem_lab_2/data:/var/data # Монтируем директорию с файлами
|
||||
- shared-result:/var/result
|
||||
|
||||
number-processor:
|
||||
build:
|
||||
context: ./app_2 # Путь ко второму приложению
|
||||
dockerfile: Dockerfile
|
||||
depends_on:
|
||||
- file-finder
|
||||
volumes:
|
||||
- shared-result:/var/result
|
||||
|
||||
volumes:
|
||||
shared-result: # Объявляем общий том
|
||||
@@ -1,42 +0,0 @@
|
||||
services: # Начало объявления сервисов
|
||||
gitea: # Указывается название сервиса
|
||||
image: gitea/gitea:1.22.2 # Указание названия образа (и/или его версии), который будет взят для создания контейнера
|
||||
restart: always # Указывается политика перезапуска, в данном случае всегда перезапускать контейнер, если он остановился
|
||||
environment: # Указываются переменные среды
|
||||
- GITEA__database__DB_TYPE=postgres # Тип базы данных
|
||||
- GITEA__database__HOST=postgres:5432 # Хост бд. Название сервиса это а-ля доменное имя и внутри сети разрешается в ip нужного контейнера
|
||||
- GITEA__database__NAME=gitea # Название базы данных
|
||||
- GITEA__database__USER=superuser # Пользователь базы данных
|
||||
- GITEA__database__PASSWD=superpassword # Пароль пользователя базы данных
|
||||
ports: # Перечисляются пробросы портов на хостовую машину. Слева порт хостовой машины, справа порт контейнера
|
||||
- "3000:3000" # Web интерфейс
|
||||
- "222:22" # SSH
|
||||
volumes: # Указываются монтированные тома, папки, файлы. В данном случае в папку /data монтируется объявленный ниже том gitea
|
||||
- gitea:/data
|
||||
depends_on: # Указывается зависимость запуска контейнера от другого сервиса, в данном случае запускается только после запуска сервиса бд
|
||||
- postgres
|
||||
# Дальше всё по аналогии, различаются лишь названия, переменные окружения, образы, порты и тома
|
||||
postgres:
|
||||
image: postgres:14
|
||||
restart: always
|
||||
environment:
|
||||
- POSTGRES_USER=superuser
|
||||
- POSTGRES_PASSWORD=superpassword
|
||||
- POSTGRES_DB=gitea
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres:/var/lib/postgresql/data
|
||||
|
||||
rabbitmq:
|
||||
image: rabbitmq:3-management
|
||||
environment:
|
||||
RABBITMQ_DEFAULT_USER: superuser
|
||||
RABBITMQ_DEFAULT_PASS: superpassword
|
||||
ports:
|
||||
- "5672:5672"
|
||||
- "15672:15672"
|
||||
|
||||
volumes: # Перечисление томов, которые можно использовать как в одном, так и в нескольких сервисах
|
||||
postgres:
|
||||
gitea:
|
||||
@@ -1,25 +0,0 @@
|
||||
# Лабораторная работа №1
|
||||
В рамках данной лабораторной работы будут развёрнуты следующие сервисы:
|
||||
1. **Gitea** - система управления версиями
|
||||
2. **Postgres** - реляционая база данных
|
||||
3. **Rabbitmq** - брокер сообщений
|
||||
|
||||
Инструкции к запуску контейнеров и пояснения к ним находятся в файле ```docker-compose.yml```
|
||||
|
||||
## Порядок запуска
|
||||
#### 1. Установить docker или убедиться, что он установлен
|
||||
#### 2. Перейти в папку с файлом ```docker-compose.yml```
|
||||
#### 3. Выполнить команду в терминале: ```docker-compose up --build --remove-orphans```
|
||||
|
||||
Проверить успешность запуска можно командой ```docker ps -a```. Если всё прошло успешно, то в терминале будет написано:
|
||||
```
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
1a794331b32b gitea/gitea:1.22.2 "/usr/bin/entrypoint…" 20 seconds ago Up 18 seconds 0.0.0.0:3000->3000/tcp, 0.0.0.0:222->22/tcp polevoy_sergey_lab_1-gitea-1
|
||||
b5fe33c61c1d rabbitmq:3-management "docker-entrypoint.s…" 20 seconds ago Up 19 seconds 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 15691-15692/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp rabbitmq
|
||||
3d2db73d15c5 postgres:14 "docker-entrypoint.s…" 20 seconds ago Up 19 seconds 0.0.0.0:5432->5432/tcp polevoy_sergey_lab_1-postgres-1
|
||||
```
|
||||
|
||||
Работать со всеми перечисленными сервисами можно сразу после запуска за исключением **gitea**. После первого запуска необходимо зайти на сервис, выполнить первоначальную настройку и создать суперпользователя.
|
||||
|
||||
## Видеодемонстрация работы
|
||||
### Видео доступно по [ссылке](https://disk.yandex.ru/i/3Out4mUV6NEJuA)
|
||||
Reference in New Issue
Block a user