senkin_alexander_lab_2 is ready

This commit is contained in:
Mamoru777 2023-10-22 20:57:20 +04:00
parent a1c75ee3cf
commit 302501cb58
29 changed files with 296 additions and 0 deletions

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />

View File

@ -0,0 +1,53 @@
# Лабораторная работа №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
Разработка ведется на языке Go
![img.png](img.png)
# Запуск
Запуск контейнеров производится командой "docker-compose up -d"
# Работа программы
- Создание двух деррикторий: worker_1 и worker_2 для реализаций двух программ.
- Создание go.mod для обоих программ и реализация этих программ.
- Описание Dockerfile для создания образов для обоих программ.
- ![img_2.png](img_2.png) ![img_3.png](img_3.png)
- Создание двух репозиториев: data, result, для монтирования их в контейнеры, а также заполнение папки data тремя файлами.
- ![img_4.png](img_4.png)
- Описание docker-compose для запуска контейнеров, реализуется build для создания образов на основе dockerfile и у второго контейнера описавыется зависимость depends_on от первого контейнера, чтобы сначала успевал запуститься первый контейнер, а за ним запускался второй. Также описываются volumes, для монтирование папок data и result в контейнеры.
- ![img_5.png](img_5.png)
- Сборка и запуска контейнеров.
- ![img_6.png](img_6.png)
- Проверка в Docker Desktop контейнеров и образов.
- ![img_7.png](img_7.png)
- ![img_8.png](img_8.png)
- Смотрим, что выдает нам первый воркер в консоль. Он говорит, что первый файл с названием file1.txt имеет 4 строки, и это больше, чем в других файлах. Также текст этого файла был скопирован в файл data.txt
- ![img_9.png](img_9.png)
- Смотрим, что выдает нам второй воркер в консоль. Он говорит, что результат умножения сохранен в файл result.txt, а также выдает нам число, лежащее в этом файле.
- ![img_10.png](img_10.png)
- Смотрим, что при запуске контейнеров действительно в папке result создалось два файла data.txt и result.txt
- ![img_11.png](img_11.png)
- Смотрим, что лежит в эти файлах. В файле data.txt действительно лежат числа из file1.txt, а в файле result.txt лежит результат умножения первого на последнее число.
- ![img_12.png](img_12.png)
- ![img_13.png](img_13.png)
# Видео
Видео с разбором лабораторной работы - https://youtu.be/JHDQOQBBPUs

View File

@ -0,0 +1,4 @@
525 785 99856
1000 7984 545102
513 84651321 564
654 6548 321315

View File

@ -0,0 +1,2 @@
42432 54654 5212
1524 458 3526

View File

@ -0,0 +1,3 @@
546 546542 21354
2548 545 4645
546 5473 5464

View File

@ -0,0 +1,18 @@
services:
worker1:
build:
context: /worker_1
dockerfile: Dockerfile
volumes:
- C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\data:/var/data
- C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\result:/var/result
worker2:
build:
context: /worker_2
dockerfile: Dockerfile
volumes:
- C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\data:/var/data
- C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\result:/var/result
depends_on:
- worker1

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,4 @@
525 785 99856
1000 7984 545102
513 84651321 564
654 6548 321315

View File

@ -0,0 +1 @@
168690375

View File

@ -0,0 +1,13 @@
FROM golang:latest
WORKDIR /app
COPY go.mod .
RUN go mod download
COPY worker_1.go .
RUN go build -o myapp
CMD ["/app/myapp"]

View File

@ -0,0 +1,3 @@
module DAS_2023_1/senkin_alexander_lab_2/worker_1
go 1.20

View File

@ -0,0 +1,71 @@
package main
import (
"bytes"
"io/ioutil"
"log"
"os"
"path/filepath"
)
func main() {
sourceDir := "/var/data"
destinationFile := "/var/result/data.txt"
if _, err := os.Stat(destinationFile); os.IsNotExist(err) {
file, err := os.Create(destinationFile)
if err != nil {
log.Println("Ошибка при создании файла:", err)
return
}
file.Close()
}
files, err := ioutil.ReadDir(sourceDir)
if err != nil {
log.Println("Ошибка при чтении каталога:", err)
return
}
var maxLines int
var maxLinesFile string
for _, file := range files {
if !file.IsDir() {
filePath := filepath.Join(sourceDir, file.Name())
lines, err := countLines(filePath)
if err != nil {
log.Printf("Ошибка при подсчете строк в файле %s: %v\n", filePath, err)
continue
}
if lines > maxLines {
maxLines = lines
maxLinesFile = filePath
}
}
}
if maxLinesFile != "" {
data, err := ioutil.ReadFile(maxLinesFile)
if err != nil {
log.Printf("Ошибка при чтении файла: %v\n", err)
return
}
err = ioutil.WriteFile(destinationFile, data, 0644)
if err != nil {
log.Printf("Ошибка при записи файла: %v\n", err)
return
}
log.Printf("Файл %s с наибольшим количеством строк (%d) скопирован в %s\n", maxLinesFile, maxLines, destinationFile)
} else {
log.Println("Не удалось найти файлы в каталоге /var/data.")
}
}
func countLines(filePath string) (int, error) {
data, err := ioutil.ReadFile(filePath)
if err != nil {
return 0, err
}
lines := len(bytes.Split(data, []byte("\n"))) - 1
return lines, nil
}

View File

@ -0,0 +1,13 @@
FROM golang:latest
WORKDIR /app
COPY go.mod .
RUN go mod download
COPY worker_2.go .
RUN go build -o myapp
CMD ["/app/myapp"]

View File

@ -0,0 +1,3 @@
module DAS_2023_1/senkin_alexander_lab_2/worker_2
go 1.20

View File

@ -0,0 +1,89 @@
package main
import (
"bufio"
"fmt"
"io/ioutil"
"log"
"os"
"strconv"
"strings"
)
func main() {
dataFilePath := "/var/result/data.txt"
resultFilePath := "/var/result/result.txt"
if _, err := os.Stat(resultFilePath); os.IsNotExist(err) {
file, err := os.Create(resultFilePath)
if err != nil {
log.Println("Ошибка при создании файла:", err)
return
}
file.Close()
}
_, err := os.Stat(dataFilePath)
if err != nil {
log.Fatal("Файл data.txt не сущесвует, выполните первую программу перед запуском второй")
}
data, err := ioutil.ReadFile(dataFilePath)
if err != nil {
fmt.Printf("Ошибка при чтении файла %s: %v\n", dataFilePath, err)
return
}
content := string(data)
lines := bufio.NewScanner(strings.NewReader(content))
first := 0
last := 0
firstFound := false
var numbersFound bool
for lines.Scan() {
line := lines.Text()
numbers := strings.Fields(line)
if len(numbers) > 0 {
// Преобразуем первое и последнее число в числа с плавающей точкой
if !firstFound {
first, err = strconv.Atoi(numbers[0])
if err != nil {
log.Fatalf("Ошибка при преобразовании первого числа: %v", err)
}
firstFound = true
}
last, err = strconv.Atoi(numbers[len(numbers)-1])
if err != nil {
log.Fatalf("Ошибка при преобразовании последнего числа: %v", err)
}
numbersFound = true
}
}
if err := lines.Err(); err != nil {
log.Printf("Ошибка при чтении файла: %v\n", err)
return
}
if !numbersFound {
log.Fatalf("Не найдены числа в файле %s", dataFilePath)
}
result := first * last
outputContent := fmt.Sprintf("%d", result)
if err := ioutil.WriteFile(resultFilePath, []byte(outputContent), 0644); err != nil {
log.Printf("Ошибка при записи результата в файл: %v\n", err)
return
}
log.Printf("Результат (%d) сохранен в файл %s\n", result, resultFilePath)
dataResult, err := ioutil.ReadFile(resultFilePath)
if err != nil {
fmt.Printf("Ошибка при чтении файла %s: %v\n", resultFilePath, err)
return
}
contentResult := string(dataResult)
log.Println("Результат, лежащий в файле result - ", contentResult)
}

View File

@ -0,0 +1,18 @@
services:
worker1:
build:
context: C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\worker_1
dockerfile: Dockerfile
volumes:
- C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\data:/var/data
- C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\result:/var/result
worker2:
build:
context: C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\worker_2
dockerfile: Dockerfile
volumes:
- C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\data:/var/data
- C:\Users\Mamoru\GolandProjects\DAS_2023_1\senkin_alexander_lab_2\result:/var/result
depends_on:
- worker1