Лабораторная Работа №3

This commit is contained in:
Samecoins
2025-03-30 18:56:03 +04:00
parent e9885e265b
commit 3769ba1d41
23 changed files with 406 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MatrixMeanApplication {
public static void main(String[] args) {
SpringApplication.run(MatrixMeanApplication.class, args);
}
}

View File

@@ -0,0 +1,22 @@
package org.example;
public class MatrixWithMean {
private double[][] matrix;
private double mean;
public double[][] getMatrix() {
return matrix;
}
public void setMatrix(double[][] matrix) {
this.matrix = matrix;
}
public double getMean() {
return mean;
}
public void setMean(double mean) {
this.mean = mean;
}
}

View File

@@ -0,0 +1,61 @@
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);
}
}

View File

@@ -0,0 +1 @@
server.port=5001

View File

@@ -0,0 +1 @@
server.port=5001

View File

@@ -0,0 +1,3 @@
artifactId=CT102
groupId=org.example
version=1.0-SNAPSHOT

View File

@@ -0,0 +1,3 @@
org\example\MatrixWithMean.class
org\example\MatrixMeanApplication.class
org\example\MeanController.class

View File

@@ -0,0 +1,3 @@
D:\SPPR\ashahanov_ahmad_lab_3\CT102\src\main\java\org\example\MeanController.java
D:\SPPR\ashahanov_ahmad_lab_3\CT102\src\main\java\org\example\MatrixMeanApplication.java
D:\SPPR\ashahanov_ahmad_lab_3\CT102\src\main\java\org\example\MatrixWithMean.java

View File

@@ -0,0 +1,22 @@
package org.example;
public class MatrixProcessRequest {
private double[][] matrix;
private double mean;
public double[][] getMatrix() {
return matrix;
}
public void setMatrix(double[][] matrix) {
this.matrix = matrix;
}
public double getMean() {
return mean;
}
public void setMean(double mean) {
this.mean = mean;
}
}

View File

@@ -0,0 +1,11 @@
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MatrixProcessingApplication {
public static void main(String[] args) {
SpringApplication.run(MatrixProcessingApplication.class, args);
}
}

View File

@@ -0,0 +1,33 @@
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);
}
}

View File

@@ -0,0 +1,2 @@
server.port=5002
CT102.url=http://192.168.2.102:5001/mean/compute

View File

@@ -0,0 +1,2 @@
server.port=5002
CT102.url=http://localhost:5001/mean/compute

View File

@@ -0,0 +1,3 @@
artifactId=CT103
groupId=org.example
version=1.0-SNAPSHOT

View File

@@ -0,0 +1,3 @@
org\example\MatrixProcessingApplication.class
org\example\MatrixProcessRequest.class
org\example\MatrixProcessingController.class

View File

@@ -0,0 +1,3 @@
D:\SPPR\ashahanov_ahmad_lab_3\CT103\src\main\java\org\example\MatrixProcessingApplication.java
D:\SPPR\ashahanov_ahmad_lab_3\CT103\src\main\java\org\example\MatrixProcessingController.java
D:\SPPR\ashahanov_ahmad_lab_3\CT103\src\main\java\org\example\MatrixProcessRequest.java

View File

@@ -0,0 +1,222 @@
# Лабораторная работа №3: Распределённое приложение для обработки матрицы
***
## Цель работы
Разработка распределённого приложения, состоящего из двух сервисов, взаимодействующих по протоколу HTTP (REST API).
***
## Используемые технологии и инструменты
- **Java 17**
- **Spring Boot 3.2.0**
- **Maven** (для сборки и управления зависимостями)
- **RestTemplate** (для HTTP-запросов между сервисами)
- **cURL / Postman** (для тестирования REST API)
***
## Разбор кода
### Модуль 1 (Сервис генерации матрицы)
#### **Классы:**
1. **MatrixMeanApplication**
- Главный класс, запускающий Spring Boot приложение.
2. **MatrixWithMean**
- Модель, содержащая два поля:
- `double[][] matrix` — сгенерированная матрица
- `double mean` — среднее арифметическое всех элементов матрицы
3. **MeanController**
```java
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);
}
}
3. ```
Контроллер с методами:
- **computeMean** принимает POST-запрос с JSON-массивом и возвращает среднее значение.
- **generateMatrixAndProcess** принимает POST-запрос с размером матрицы, генерирует её, вычисляет среднее, отправляет данные во 2-й сервис и возвращает обработанный результат.
#### **Алгоритм работы 1-го сервиса:**
- Получает POST-запрос с размером матрицы.
- Генерирует квадратную матрицу со случайными значениями.
- Вычисляет среднее арифметическое всех элементов матрицы.
- Отправляет JSON-объект во 2-й сервис.
- Получает обработанный ответ и возвращает его клиенту.
### Модуль 2 (Сервис обработки матрицы)
#### **Классы:**
1. **MatrixProcessingController**
```java
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);
}
}
1. ```
Контроллер с методом **processMatrix**, который:
- Принимает JSON с матрицей и средним значением.
- Делит каждый элемент матрицы на среднее.
- Возвращает обработанную матрицу.
2. **MatrixProcessRequest**
- Модель, содержащая два поля:
- `double[][] matrix` исходная матрица
- `double mean` среднее арифметическое
#### **Алгоритм работы 2-го сервиса:**
- Получает JSON с матрицей и средним значением.
- Делит каждый элемент матрицы на среднее арифметическое.
- Возвращает обработанную матрицу.
***
## Общий алгоритм работы системы
1. **Генерация матрицы**
- 1-й сервис получает POST-запрос, что означает создание матрицы n×n.
2. **Вычисление среднего**
- 1-й сервис вычисляет среднее арифметическое элементов матрицы.
3. **Передача данных**
- Отправляет JSON-объект с `matrix` и `mean` во 2-й сервис.
4. **Обработка матрицы**
- 2-й сервис получает данные, делит элементы матрицы на среднее значение и отправляет обратно.
5. **Вывод результата**
- 1-й сервис возвращает обработанную матрицу клиенту.
***
## Запуск сервисов
### Сборка проектов
Для каждого модуля команда:
```bash
mvn clean package
```
### Запуск серверов
```bash
java -jar CT102/target/CT102-1.0-SNAPSHOT.jar
java -jar CT103/target/CT103-1.0-SNAPSHOT.jar
```
***
## Тестирование
### Отправка запроса на генерацию и обработку матрицы
```bash
curl -X POST -H "Content-Type: application/json" -d "5" http://localhost:5001/mean/generate
```
Этот запрос инициирует генерацию квадратной матрицы 5×5, вычисление среднего, передачу данных во 2-й сервис и возврат обработанной матрицы.
### Пример входных данных:
POST-запрос к **1-му сервису** отправляется число `5` в теле запроса.
### Пример ответа:
```json
{
"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** упростил управление зависимостями.