Files
SSPR_25/kuznetsov_danila_lab_3
..
2025-03-12 17:20:41 +04:00
2025-03-12 17:20:41 +04:00
2025-03-12 17:20:41 +04:00

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

1. Задание

Разработка распределённого приложения с использованием Spring Boot.
Нужно реализовать параллельный вариант алгоритма с применением сервис-ориентированного подхода, замерить время работы алгоритма и распределить функционал между двумя сервисами:

  • Compute Service: Находит минимальный элемент матрицы ниже главной диагонали.
  • Gateway Service: Принимает запросы от клиента и пересылает их на Compute Service.

Вариант: Определить минимальный элемент матрицы ниже главной диагонали.


2. Описание кода

Приложение состоит из двух частей, каждая из которых отдельное Spring Boot приложение.

2.1. Compute Service

Этот сервис отвечает за вычисления. Он принимает матрицу, запускает алгоритм поиска минимального элемента ниже главной диагонали, замеряет время выполнения и возвращает результат.

MatrixComputeApplication.java

package ru.kuznec;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MatrixComputeApplication {
    public static void main(String[] args) {
        SpringApplication.run(MatrixComputeApplication.class, args);
    }
}

MatrixComputeController.java

package ru.kuznec;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;

@RestController
public class MatrixComputeController {

    @Autowired
    private MatrixMinService matrixMinService;

    @PostMapping("/computeMin")
    public ResponseEntity<Map<String, Object>> computeMin(@RequestBody int[][] matrix) {
        long startTime = System.nanoTime();
        int min = matrixMinService.findMinBelowMainDiagonal(matrix);
        long endTime = System.nanoTime();
        double duration = (double) (endTime - startTime) / 1_000_000;
        
        Map<String, Object> response = new HashMap<>();
        response.put("minValue", min);
        response.put("durationMs", duration);
        return ResponseEntity.ok(response);
    }
}

MatrixMinService.java

package ru.kuznec;

import org.springframework.stereotype.Service;
import java.util.stream.IntStream;

@Service
public class MatrixMinService {

    public int findMinBelowMainDiagonal(int[][] matrix) {
        return IntStream.range(1, matrix.length)
                .parallel()
                .map(i -> {
                    int rowMin = Integer.MAX_VALUE;
                    for (int j = 0; j < i; j++) {
                        if (matrix[i][j] < rowMin) {
                            rowMin = matrix[i][j];
                        }
                    }
                    return rowMin;
                })
                .min()
                .orElse(Integer.MAX_VALUE);
    }
}

2.2. Gateway Service

Этот сервис принимает клиентские запросы на эндпоинте /findMin и пересылает их на Compute Service. В настройках Gateway указан URL Compute Service с его IP-адресом (в нашем случае, например, http://192.168.10.101:8080/computeMin).

MatrixGatewayApplication.java

package ru.kuznec;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MatrixGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(MatrixGatewayApplication.class, args);
    }
}

MatrixGatewayController.java

package ru.kuznec;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Map;

@RestController
public class MatrixGatewayController {

    @Autowired
    private RestTemplate restTemplate;

    // Адрес Compute Service (IP контейнера с Compute Service)
    private String computeServiceUrl = "http://192.168.10.101:8080/computeMin";

    @PostMapping("/findMin")
    public ResponseEntity<?> findMin(@RequestBody int[][] matrix) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<int[][]> request = new HttpEntity<>(matrix, headers);

        ResponseEntity<Map> response = restTemplate.exchange(
                computeServiceUrl,
                HttpMethod.POST,
                request,
                Map.class
        );
        return response;
    }
}

RestTemplateConfig.java

package ru.kuznec;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

3. Запуск приложения

Сборка каждого приложения приводит к созданию jar-файлов. Запускаем их на разных контейнерах:

  • Compute Service:
    На контейнере с IP 192.168.10.101 запускаем:

    java -jar Lab-3.jar --server.port=8080
    

    Compute Service будет доступен по адресу:

    http://192.168.10.101:8080/computeMin
    
  • Gateway Service:
    На контейнере с IP 192.168.10.102 запускаем:

    java -jar Lab-3.1.jar --server.port=8081
    

    Gateway Service будет доступен по адресу:

    http://192.168.10.102:8081/findMin
    

Gateway Service перенаправляет запросы на Compute Service по указанному адресу.


4. Проверка работы

Для проверки работы можно использовать curl, отправив запрос на Gateway Service:

curl -X POST http://192.168.10.102:8081/findMin \
     -H "Content-Type: application/json" \
     -d '[[5, 3, 8], [2, 6, 4], [7, 1, 9]]'

В ответ вы получите JSON с полями minValue (минимальное значение) и durationMs (время выполнения алгоритма в миллисекундах).