forked from sevastyan_b/SSPR_25
Лабораторная работа №3: Распределённое приложение для обработки матрицы
Цель работы
Разработка распределённого приложения, состоящего из двух сервисов, взаимодействующих по протоколу HTTP (REST API).
Используемые технологии и инструменты
- Java 17
- Spring Boot 3.2.0
- Maven (для сборки и управления зависимостями)
- RestTemplate (для HTTP-запросов между сервисами)
- cURL / Postman (для тестирования REST API)
Разбор кода
Модуль 1 (Сервис генерации матрицы)
Классы:
- MatrixMeanApplication
- Главный класс, запускающий Spring Boot приложение.
- MatrixWithMean
- Модель, содержащая два поля:
double[][] matrix— сгенерированная матрицаdouble mean— среднее арифметическое всех элементов матрицы
- 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 (Сервис обработки матрицы)
Классы:
- 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 с матрицей и средним значением.
- Делит каждый элемент матрицы на среднее.
- Возвращает обработанную матрицу.
- MatrixProcessRequest
- Модель, содержащая два поля:
double[][] matrix— исходная матрицаdouble mean— среднее арифметическое
Алгоритм работы 2-го сервиса:
- Получает JSON с матрицей и средним значением.
- Делит каждый элемент матрицы на среднее арифметическое.
- Возвращает обработанную матрицу.
Общий алгоритм работы системы
- Генерация матрицы
- 1-й сервис получает POST-запрос, что означает создание матрицы n×n.
- Вычисление среднего
- 1-й сервис вычисляет среднее арифметическое элементов матрицы.
- Передача данных
- Отправляет JSON-объект с
matrixиmeanво 2-й сервис.
- Отправляет JSON-объект с
- Обработка матрицы
- 2-й сервис получает данные, делит элементы матрицы на среднее значение и отправляет обратно.
- Вывод результата
- 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 упростил управление зависимостями.