DAS_2023_1/podkorytova_yulia_lab_3/README.md
2024-01-10 00:13:23 +04:00

7.6 KiB
Raw Blame History

Лабораторная работа 3. REST API, Gateway и синхронный обмен между микросервисами

Задание на лабораторную работу

  1. Создать 2 микросервиса, реализующих CRUD на связанных сущностях.
  2. Реализовать механизм синхронного обмена сообщениями между микросервисами.
  3. Реализовать шлюз на основе прозрачного прокси-сервера nginx.

Как запустить лабораторную работу

Для сборки и запуска программ необходимо перейти в директорию с файлом docker-compose.yaml и выполнить команду:

docker-compose up -d

Описание работы

Были созданы два микросервиса на java, каждый реализует CRUD-операции: список записей, подробности конкретной записи, создание, удаление и изменение записи. Микросервисы реализованы при помощи фреймворка spring.

Описание сущностей:

  • user - пользователь. Поля: id (уникальный идентификатор пользователя), fullName (ФИО), phoneNumber (номер телефона), role (роль - ученик/репетитор).
  • message - сообщение. Поля: id (уникальный идентификатор сообщения), text (текст), status (статус - отправлено/получено/прочитано), date (дата отправки), userId (id пользователя).

Сущности связаны отношением один-ко-многим (пользователь-сообщения).

Реализация синхронного обмена:

Синхронный обмен между сообщениями реализуется при помощи RestTemplate. При получении информации о сообщении через GET запрос к user-service получаются данные о пользователе-отправителе сообщения.

Пример реализации при получении записи о сообщении в MessageService:

private final MessageRepository messageRepository;
private final RestTemplate restTemplate;
private final String URL = "http://user-service:8085/user/";

@Autowired
public MessageService(MessageRepository messageRepository, RestTemplate restTemplate) {
    this.messageRepository = messageRepository;
    this.restTemplate = restTemplate;
}

@Transactional(readOnly = true)
public MessageWithUserInfoDto findMessage(Long id) {
    final Message message = messageRepository.findById(id).orElse(null);
    if (message == null) {
        throw new MessageNotFoundException(id);
    }
    UserInfoDto userInfo = restTemplate.getForObject(URL + message.getUserId(), UserInfoDto.class);
    return new MessageWithUserInfoDto(message, userInfo);
}

Dockerfile

Используется базовый образ openjdk:17-jdk, на основе которого будет создан контейнер. Внутри контейнера создается директория /usr/src/app/, после устанавливается рабочая директория и файлы из каталога, где находится Dockerfile, копируются внутрь контейнера в директорию /usr/src/app/. Выполняется сборка проекта с помощью инструмента gradlew. Задается порт и указывается точка входа для контейнера. Запуск java-приложения осуществляется посредством запуска jar-файла.

Содержимое Dockerfile для сервиса user-service:

FROM openjdk:17
RUN mkdir -p /usr/src/app/
WORKDIR /usr/src/app/
COPY . /usr/src/app/
RUN ./gradlew clean build
EXPOSE 8085
ENTRYPOINT ["java","-jar","build/libs/user-service-1.0-SNAPSHOT.jar"]

Аналогично был составлен Dockerfile для сервиса message-service.

Файл конфигурации nginx.conf

Файл nginx.conf содержит конфигурацию для сервера nginx. Конфигурация позволяет перенаправлять запросы, начинающиеся с /user-service/ на сервер user-service на порту 8085, а запросы, начинающиеся с /message-service/, на сервер message-service на порту 8086.

server {
listen      80;
listen      [::]:80;
server_name localhost;

    location /user-service/ {
        proxy_pass       http://user-service:8085/;
        proxy_set_header Host      $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Prefix /user-service;
    }

    location /message-service/ {
        proxy_pass       http://message-service:8086/;
        proxy_set_header Host      $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Prefix /message-service;
    }
}

Файл конфигурации docker-compose.yml

В файле docker-compose.yml указана версия синтаксиса Docker Compose, определен список сервисов, которые будут развернуты в приложении, и определена сеть с именем "network", которая будет использоваться для связи между контейнерами. Файл определяет три сервиса: user-service, message-service и nginx. Для сервисов user-service и message-service используются образы приложений, созданные при помощи Dockerfile. Сервис nginx использует образ nginx. Параметр depends_on определяет зависимости сервисов (nginx зависит от сервисов user-service и message-service и разворачивается только после их запуска), в ports настраивается проброс портов.

version: '3'

services:
  user-service:
    build:
      context: /user-service
      dockerfile: Dockerfile
    ports:
      - 8085:8085
    networks:
      - network

  message-service:
    build:
      context: /message-service
      dockerfile: Dockerfile
    ports:
      - 8086:8086
    networks:
      - network

  nginx:
    image: nginx
    ports:
      - 8087:80
    networks:
      - network
    volumes:
      - ./nginx-conf:/etc/nginx/conf.d
    depends_on:
      - user-service
      - message-service

networks:
  network:
    driver: bridge

Скриншоты

Результаты сборки и запуска программ в консоли

Образы в Dockerhub

Контейнеры в Dockerhub

Информация по пользователю

Информация по сообщению

Ссылка на видео:

https://drive.google.com/file/d/19pw4LWiuzK2tDHlSSbKbxNWPsvbUzWwd/view?usp=sharing