Отчёт по лабораторной работе №3
Разработка распределенного приложения с использованием фреймворка Spring Boot. Действия по варианту должны производиться в LXC контейнерах. Необходимо разработать параллельный вариант алгоритма с применением сервис-ориентированного подхода и фреймворка Spring Boot, замерить время его работы.
Вариант и задание
17 Упорядочить строки матрицы по убыванию суммы элементов.
Как запустить лабораторную работу
- развернуть три Worker-сервиса с разными IP-адресами и Master-сервис.
- Установить Java 17 и Maven в контейнерах.
- Собрать и запустить сервисы с помощью Maven:
mvn clean package
java -jar target/master-0.0.1-SNAPSHOT.jar # Запуск Master
java -jar target/worker-0.0.1-SNAPSHOT.jar # Запуск Worker
- Для запуска обработки выполнить GET-запрос к Master-сервису:
curl http://localhost:8080/start
Архитектура приложения
Приложение состоит из двух типов сервисов:
- Master (главный сервер) — управляет процессом, делит входные данные и собирает результаты.
- Worker (рабочие узлы) — принимают данные, обрабатывают их и отправляют обратно на Master.
Общий процесс работы:
- Master генерирует матрицу размером 1000x1000 со случайными значениями.
- Матрица делится на три части, которые отправляются на три Worker-сервиса.
- Каждый Worker вычисляет сумму элементов строк своей части матрицы и возвращает результаты.
- Master собирает суммы, сортирует строки матрицы по убыванию суммы и измеряет время выполнения.
Код Master
MasterApplication.java - основной класс Spring Boot-приложения для Master-сервиса:
@SpringBootApplication
public class MasterApplication {
public static void main(String[] args) {
SpringApplication.run(MasterApplication.class, args);
}
}
MasterController.java - контроллер Master-сервиса:
- Генерирует матрицу.
- Делит на части и отправляет на Worker-сервисы.
- Собирает результаты, сортирует матрицу и измеряет время работы.
@RestController
public class MasterController {
private final String[] workerUrls = {
"http://192.168.16.116:8081/calculateSum",
"http://192.168.16.117:8082/calculateSum",
"http://192.168.16.118:8083/calculateSum"
};
@Autowired
private RestTemplate restTemplate;
@GetMapping("/start")
public ResponseEntity<Map<String, Object>> start() {
long startTime = System.currentTimeMillis();
int[][] matrix = generateMatrix(1000, 1000);
int chunkSize = matrix.length / 3;
int[][] part1 = Arrays.copyOfRange(matrix, 0, chunkSize);
int[][] part2 = Arrays.copyOfRange(matrix, chunkSize, 2 * chunkSize);
int[][] part3 = Arrays.copyOfRange(matrix, 2 * chunkSize, matrix.length);
int[] sums1 = restTemplate.postForObject(workerUrls[0], part1, int[].class);
int[] sums2 = restTemplate.postForObject(workerUrls[1], part2, int[].class);
int[] sums3 = restTemplate.postForObject(workerUrls[2], part3, int[].class);
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;
Map<String, Object> response = new HashMap<>();
response.put("durationMs", duration);
return ResponseEntity.ok(response);
}
}
Код Worker
WorkerApplication.java - основной класс Spring Boot-приложения для Worker-сервиса:
@SpringBootApplication
public class WorkerApplication {
public static void main(String[] args) {
SpringApplication.run(WorkerApplication.class, args);
}
}
WorkerController.java - контроллер Worker-сервиса, обрабатывает запросы Master-сервера:
@RestController
public class WorkerController {
@PostMapping("/calculateSum")
public int[] calculateSum(@RequestBody int[][] matrixPart) {
int[] sums = new int[matrixPart.length];
for (int i = 0; i < matrixPart.length; i++) {
sums[i] = Arrays.stream(matrixPart[i]).sum();
}
return sums;
}
}
Вывод программы
Master
=== Генерация матрицы 1000x1000 завершена ===
=== Отправка данных на Worker Services ===
Отправка части 1 на Worker 1 (строки 0-332)"
Отправка части 2 на Worker 2 (строки 333-665)"
Отправка части 3 на Worker 3 (строки 666-999)"
=== Получение результатов от Worker Services ===
Результаты от Worker 1: 333 строк
Результаты от Worker 2: 333 строк
Результаты от Worker 3: 334 строк
=== Объединенные суммы строк ===
Всего сумм: 1000
=== Матрица отсортированна ===
=== Время выполнения ===
534 мс
Worker
=== Получена часть матрицы для обработки ===
Количество строк: 333
Строка 0: сумма = 23511
Строка 1: сумма = 54312
Строка 2: сумма = 57424
...
Строка 320: сумма = 12564
Строка 321: сумма = 95643
Строка 322: сумма = 33422
=== Обработка завершена ===
Выводы по работе
В ходе лабораторной работы было реализовано распределённое приложение на основе Spring Boot, использующее сервис-ориентированную архитектуру для параллельной обработки данных. Spring Boot + REST API обеспечивает простоту разработки и масштабируемость, но уступает Apache Ignite и MPI в производительности из-за сетевых накладных расходов. Apache Ignite оптимизирован для распределённых вычислений и работы с большими данными, а MPI обеспечивает максимальную эффективность за счёт прямого обмена сообщениями, но сложен в реализации. Выбор зависит от приоритета между удобством и вычислительной мощностью.