forked from sevastyan_b/SSPR_25
Лабораторная Работа №3
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
server.port=5001
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
server.port=5001
|
||||
@@ -0,0 +1,3 @@
|
||||
artifactId=CT102
|
||||
groupId=org.example
|
||||
version=1.0-SNAPSHOT
|
||||
@@ -0,0 +1,3 @@
|
||||
org\example\MatrixWithMean.class
|
||||
org\example\MatrixMeanApplication.class
|
||||
org\example\MeanController.class
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
server.port=5002
|
||||
CT102.url=http://192.168.2.102:5001/mean/compute
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
server.port=5002
|
||||
CT102.url=http://localhost:5001/mean/compute
|
||||
@@ -0,0 +1,3 @@
|
||||
artifactId=CT103
|
||||
groupId=org.example
|
||||
version=1.0-SNAPSHOT
|
||||
@@ -0,0 +1,3 @@
|
||||
org\example\MatrixProcessingApplication.class
|
||||
org\example\MatrixProcessRequest.class
|
||||
org\example\MatrixProcessingController.class
|
||||
@@ -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
|
||||
222
ashahanov_ahmad_lab_3/README.md
Normal file
222
ashahanov_ahmad_lab_3/README.md
Normal 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** упростил управление зависимостями.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user