Files
SSPR_25/ashahanov_ahmad_lab_3/README.md
2025-03-30 21:06:53 +04:00

8.8 KiB
Raw Blame History

Лабораторная работа №3: Распределённое приложение для обработки матрицы


Цель работы

Разработка распределённого приложения, состоящего из двух сервисов, взаимодействующих по протоколу HTTP (REST API).


Используемые технологии и инструменты

  • Java 17
  • Spring Boot 3.2.0
  • Maven (для сборки и управления зависимостями)
  • RestTemplate (для HTTP-запросов между сервисами)
  • cURL / Postman (для тестирования REST API)

Разбор кода

Модуль 1 (Сервис генерации матрицы)

Классы:

  1. MatrixMeanApplication
  • Главный класс, запускающий Spring Boot приложение.
  1. MatrixWithMean
  • Модель, содержащая два поля:
    • double[][] matrix — сгенерированная матрица
    • double mean — среднее арифметическое всех элементов матрицы
  1. MeanController
package org.example;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@RestController
@RequestMapping("/mean")
public class MeanController {

    @PostMapping("/compute")
    public ResponseEntity<Double> computeMean(@RequestBody double[][] matrix) {
        double sum = 0;
        int count = 0;
        for (double[] row : matrix) {
            for (double value : row) {
                sum += value;
                count++;
            }
        }
        double mean = count > 0 ? sum / count : 0;
        return ResponseEntity.ok(mean);
    }

    @PostMapping("/generate")
    public ResponseEntity<double[][]> generateMatrixAndProcess(@RequestBody String sizeStr) {
        int size;
        try {
            size = Integer.parseInt(sizeStr.trim());
        } catch (NumberFormatException e) {
            return ResponseEntity.badRequest().build();
        }

        double[][] matrix = new double[size][size];
        Random random = new Random();
        double sum = 0;
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                matrix[i][j] = random.nextDouble() * 100;
                sum += matrix[i][j];
            }
        }
        double mean = sum / (size * size);

        Map<String, Object> payload = new HashMap<>();
        payload.put("matrix", matrix);
        payload.put("mean", mean);

        RestTemplate restTemplate = new RestTemplate();
        String remoteUrl = "http://localhost:5002/matrix/process";
        ResponseEntity<double[][]> response =
                restTemplate.postForEntity(remoteUrl, payload, double[][].class);

        double[][] processedMatrix = response.getBody();
        return ResponseEntity.ok(processedMatrix);
    }
}

Контроллер с методами:

  • computeMean принимает POST-запрос с JSON-массивом и возвращает среднее значение.
  • generateMatrixAndProcess принимает POST-запрос с размером матрицы, генерирует её, вычисляет среднее, отправляет данные во 2-й сервис и возвращает обработанный результат.

Алгоритм работы 1-го сервиса:

  • Получает POST-запрос с размером матрицы.
  • Генерирует квадратную матрицу со случайными значениями.
  • Вычисляет среднее арифметическое всех элементов матрицы.
  • Отправляет JSON-объект во 2-й сервис.
  • Получает обработанный ответ и возвращает его клиенту.

Модуль 2 (Сервис обработки матрицы)

Классы:

  1. MatrixProcessingController
package org.example;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.stream.IntStream;

@RestController
@RequestMapping("/matrix")
public class MatrixProcessingController {

    @PostMapping("/process")
    public ResponseEntity<double[][]> processMatrix(@RequestBody MatrixProcessRequest request) {
        double[][] matrix = request.getMatrix();
        double mean = request.getMean();

        if (matrix == null || matrix.length == 0 || mean == 0) {
            return ResponseEntity.badRequest().build();
        }

        int rows = matrix.length;
        int cols = matrix[0].length;
        double[][] result = new double[rows][cols];

        IntStream.range(0, rows).parallel().forEach(i -> {
            for (int j = 0; j < cols; j++) {
                result[i][j] = matrix[i][j] / mean;
            }
        });

        return ResponseEntity.ok(result);
    }
}

Контроллер с методом processMatrix, который:

  • Принимает JSON с матрицей и средним значением.
  • Делит каждый элемент матрицы на среднее.
  • Возвращает обработанную матрицу.
  1. MatrixProcessRequest
  • Модель, содержащая два поля:
    • double[][] matrix — исходная матрица
    • double mean — среднее арифметическое

Алгоритм работы 2-го сервиса:

  • Получает JSON с матрицей и средним значением.
  • Делит каждый элемент матрицы на среднее арифметическое.
  • Возвращает обработанную матрицу.

Общий алгоритм работы системы

  1. Генерация матрицы
    • 1-й сервис получает POST-запрос, что означает создание матрицы n×n.
  2. Вычисление среднего
    • 1-й сервис вычисляет среднее арифметическое элементов матрицы.
  3. Передача данных
    • Отправляет JSON-объект с matrix и mean во 2-й сервис.
  4. Обработка матрицы
    • 2-й сервис получает данные, делит элементы матрицы на среднее значение и отправляет обратно.
  5. Вывод результата
    • 1-й сервис возвращает обработанную матрицу клиенту.

Запуск сервисов

Сборка проектов

Для каждого модуля команда:

mvn clean package

Запуск серверов

java -jar CT102/target/CT102-1.0-SNAPSHOT.jar
java -jar CT103/target/CT103-1.0-SNAPSHOT.jar

Тестирование

Отправка запроса на генерацию и обработку матрицы

curl -X POST -H "Content-Type: application/json" -d "5" http://localhost:5001/mean/generate

Этот запрос инициирует генерацию квадратной матрицы 5×5, вычисление среднего, передачу данных во 2-й сервис и возврат обработанной матрицы.

Пример входных данных:

POST-запрос к 1-му сервису отправляется число 5 в теле запроса.

Пример ответа:

{
    "processedMatrix": [
        [1.2, 0.8, 1.5, 1.1, 1.3],
        [0.9, 1.4, 1.0, 1.2, 0.7],
        [1.3, 1.1, 0.6, 1.5, 1.2],
        [1.0, 0.9, 1.4, 1.1, 1.3],
        [1.5, 1.2, 0.8, 1.0, 0.9]
    ]
}

Вывод

В результате работы было реализовано распределённое приложение, состоящее из двух сервисов:

  • Сервис 1 генерирует матрицу, вычисляет среднее арифметическое, передаёт данные в Сервис 2.
  • Сервис 2 выполняет обработку матрицы и возвращает результат.

Вся система взаимодействует через REST API, обеспечивая автоматическую передачу данных между сервисами.

Использование Spring Boot позволило легко организовать работу двух микросервисов, а Maven упростил управление зависимостями.