diff --git a/senkin_alexander_lab_2/README.md b/senkin_alexander_lab_2/README.md new file mode 100644 index 0000000..a2e7af9 --- /dev/null +++ b/senkin_alexander_lab_2/README.md @@ -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 diff --git a/senkin_alexander_lab_2/data/file1.txt b/senkin_alexander_lab_2/data/file1.txt new file mode 100644 index 0000000..844cd1f --- /dev/null +++ b/senkin_alexander_lab_2/data/file1.txt @@ -0,0 +1,4 @@ +525 785 99856 +1000 7984 545102 +513 84651321 564 +654 6548 321315 diff --git a/senkin_alexander_lab_2/data/file2.txt b/senkin_alexander_lab_2/data/file2.txt new file mode 100644 index 0000000..0bfb23e --- /dev/null +++ b/senkin_alexander_lab_2/data/file2.txt @@ -0,0 +1,2 @@ +42432 54654 5212 +1524 458 3526 \ No newline at end of file diff --git a/senkin_alexander_lab_2/data/file3.txt b/senkin_alexander_lab_2/data/file3.txt new file mode 100644 index 0000000..8d723cb --- /dev/null +++ b/senkin_alexander_lab_2/data/file3.txt @@ -0,0 +1,3 @@ +546 546542 21354 +2548 545 4645 +546 5473 5464 diff --git a/senkin_alexander_lab_2/docker-compose.yml b/senkin_alexander_lab_2/docker-compose.yml new file mode 100644 index 0000000..abb8fa9 --- /dev/null +++ b/senkin_alexander_lab_2/docker-compose.yml @@ -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 + diff --git a/senkin_alexander_lab_2/img.png b/senkin_alexander_lab_2/img.png new file mode 100644 index 0000000..ee73beb Binary files /dev/null and b/senkin_alexander_lab_2/img.png differ diff --git a/senkin_alexander_lab_2/img_1.png b/senkin_alexander_lab_2/img_1.png new file mode 100644 index 0000000..99793fb Binary files /dev/null and b/senkin_alexander_lab_2/img_1.png differ diff --git a/senkin_alexander_lab_2/img_10.png b/senkin_alexander_lab_2/img_10.png new file mode 100644 index 0000000..325ccff Binary files /dev/null and b/senkin_alexander_lab_2/img_10.png differ diff --git a/senkin_alexander_lab_2/img_11.png b/senkin_alexander_lab_2/img_11.png new file mode 100644 index 0000000..a8bb949 Binary files /dev/null and b/senkin_alexander_lab_2/img_11.png differ diff --git a/senkin_alexander_lab_2/img_12.png b/senkin_alexander_lab_2/img_12.png new file mode 100644 index 0000000..2d418c2 Binary files /dev/null and b/senkin_alexander_lab_2/img_12.png differ diff --git a/senkin_alexander_lab_2/img_13.png b/senkin_alexander_lab_2/img_13.png new file mode 100644 index 0000000..eea699d Binary files /dev/null and b/senkin_alexander_lab_2/img_13.png differ diff --git a/senkin_alexander_lab_2/img_2.png b/senkin_alexander_lab_2/img_2.png new file mode 100644 index 0000000..99793fb Binary files /dev/null and b/senkin_alexander_lab_2/img_2.png differ diff --git a/senkin_alexander_lab_2/img_3.png b/senkin_alexander_lab_2/img_3.png new file mode 100644 index 0000000..a899a0d Binary files /dev/null and b/senkin_alexander_lab_2/img_3.png differ diff --git a/senkin_alexander_lab_2/img_4.png b/senkin_alexander_lab_2/img_4.png new file mode 100644 index 0000000..1430a93 Binary files /dev/null and b/senkin_alexander_lab_2/img_4.png differ diff --git a/senkin_alexander_lab_2/img_5.png b/senkin_alexander_lab_2/img_5.png new file mode 100644 index 0000000..4ee28c7 Binary files /dev/null and b/senkin_alexander_lab_2/img_5.png differ diff --git a/senkin_alexander_lab_2/img_6.png b/senkin_alexander_lab_2/img_6.png new file mode 100644 index 0000000..5254648 Binary files /dev/null and b/senkin_alexander_lab_2/img_6.png differ diff --git a/senkin_alexander_lab_2/img_7.png b/senkin_alexander_lab_2/img_7.png new file mode 100644 index 0000000..58dc043 Binary files /dev/null and b/senkin_alexander_lab_2/img_7.png differ diff --git a/senkin_alexander_lab_2/img_8.png b/senkin_alexander_lab_2/img_8.png new file mode 100644 index 0000000..ecae501 Binary files /dev/null and b/senkin_alexander_lab_2/img_8.png differ diff --git a/senkin_alexander_lab_2/img_9.png b/senkin_alexander_lab_2/img_9.png new file mode 100644 index 0000000..1e67c0d Binary files /dev/null and b/senkin_alexander_lab_2/img_9.png differ diff --git a/senkin_alexander_lab_2/result/data.txt b/senkin_alexander_lab_2/result/data.txt new file mode 100644 index 0000000..844cd1f --- /dev/null +++ b/senkin_alexander_lab_2/result/data.txt @@ -0,0 +1,4 @@ +525 785 99856 +1000 7984 545102 +513 84651321 564 +654 6548 321315 diff --git a/senkin_alexander_lab_2/result/result.txt b/senkin_alexander_lab_2/result/result.txt new file mode 100644 index 0000000..70ebc29 --- /dev/null +++ b/senkin_alexander_lab_2/result/result.txt @@ -0,0 +1 @@ +168690375 \ No newline at end of file diff --git a/senkin_alexander_lab_2/worker_1/Dockerfile b/senkin_alexander_lab_2/worker_1/Dockerfile new file mode 100644 index 0000000..0dd6ff3 --- /dev/null +++ b/senkin_alexander_lab_2/worker_1/Dockerfile @@ -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"] \ No newline at end of file diff --git a/senkin_alexander_lab_2/worker_1/go.mod b/senkin_alexander_lab_2/worker_1/go.mod new file mode 100644 index 0000000..b350c79 --- /dev/null +++ b/senkin_alexander_lab_2/worker_1/go.mod @@ -0,0 +1,3 @@ +module DAS_2023_1/senkin_alexander_lab_2/worker_1 + +go 1.20 diff --git a/senkin_alexander_lab_2/worker_1/worker_1.go b/senkin_alexander_lab_2/worker_1/worker_1.go new file mode 100644 index 0000000..9aed078 --- /dev/null +++ b/senkin_alexander_lab_2/worker_1/worker_1.go @@ -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 +} diff --git a/senkin_alexander_lab_2/worker_2/Dockerfile b/senkin_alexander_lab_2/worker_2/Dockerfile new file mode 100644 index 0000000..c4f6577 --- /dev/null +++ b/senkin_alexander_lab_2/worker_2/Dockerfile @@ -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"] \ No newline at end of file diff --git a/senkin_alexander_lab_2/worker_2/go.mod b/senkin_alexander_lab_2/worker_2/go.mod new file mode 100644 index 0000000..eb94b4c --- /dev/null +++ b/senkin_alexander_lab_2/worker_2/go.mod @@ -0,0 +1,3 @@ +module DAS_2023_1/senkin_alexander_lab_2/worker_2 + +go 1.20 diff --git a/senkin_alexander_lab_2/worker_2/worker_2.go b/senkin_alexander_lab_2/worker_2/worker_2.go new file mode 100644 index 0000000..5aca496 --- /dev/null +++ b/senkin_alexander_lab_2/worker_2/worker_2.go @@ -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) +} diff --git a/tasks/senkin-ae/lab_2/docker-compose.yml b/tasks/senkin-ae/lab_2/docker-compose.yml new file mode 100644 index 0000000..7170bfb --- /dev/null +++ b/tasks/senkin-ae/lab_2/docker-compose.yml @@ -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 +