DAS_2023_1/mashkova_margarita_lab_3
2023-12-14 09:39:03 +04:00
..
groupe-service mashkova_margarita_lab_3 ready 2023-12-14 09:39:03 +04:00
nginx-conf mashkova_margarita_lab_3 ready 2023-12-14 09:39:03 +04:00
student-service mashkova_margarita_lab_3 ready 2023-12-14 09:39:03 +04:00
build_images.png mashkova_margarita_lab_3 ready 2023-12-14 09:39:03 +04:00
containers.png mashkova_margarita_lab_3 ready 2023-12-14 09:39:03 +04:00
docker-compose.yml mashkova_margarita_lab_3 ready 2023-12-14 09:39:03 +04:00
images.png mashkova_margarita_lab_3 ready 2023-12-14 09:39:03 +04:00
README.md mashkova_margarita_lab_3 ready 2023-12-14 09:39:03 +04:00
results.png mashkova_margarita_lab_3 ready 2023-12-14 09:39:03 +04:00

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

ПИбд-42 Машкова Маргарита

Задание

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

Запуск программы

В директории с файлом docker-compose.yml выполнить команду:

docker-compose up -d

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

2 микросервиса, реализующих CRUD на связанных сущностях:

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

  • Groupe - группа в университете, содержит 2 атрибута: id и name.

P.S. Слово group специально написано неправильно, т.к. такое слово зарезервиравано в СУБД :)

  • Student - студент, сущность содержит 4 атрибута: id, name, surname, groupeId.

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

Данные микросервисы, выполняющие CRUD операции над сущностями, реализованы при помощи фреймворка spring.

Реализация механизма синхронного обмена сообщениями между микросервисами:

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

private final RestTemplate restTemplate = new RestTemplate();
private final String URL = "http://groupe-service:8080/groupe/";

public StudentInfoDto findStudentInfo(Integer id){
        Student student = studentRepository.findById(id)
                .orElseThrow(() -> new RuntimeException(String.format("Student with id %s was not found", id)));

        GroupeInfoDto group = restTemplate.getForObject(URL + student.getGroupeId(), GroupeInfoDto.class);

        StudentInfoDto studentInfoDto = new StudentInfoDto();
        studentInfoDto.setId(id);
        studentInfoDto.setName(student.getName());
        studentInfoDto.setSurname(student.getSurname());
        studentInfoDto.setGroupeInfoDto(group);

        return studentInfoDto;
    }

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

Для обеспечения работы прокси-сервера nginx в качестве шлюза, необходимо чтобы все управляемые им сервисы находились в одной сети типа "мост":

networks:
  my-network:
    driver: bridge

Настройка сервисов:

Для сервиса БД db-university используется образ postgres. Также указывается порт взаимодействия, переменные окружения - логин, пароль для учетной записи в postgres и имя БД. Сервис добавлятся в созданную сеть. Опция restart: always означает, что docker-compose перезапустит контейнер, если тот вдруг остановится.

db-university:
image: postgres:latest
container_name: db-university
ports:
  - 5432:5432
environment:
  POSTGRES_PASSWORD: admin
  POSTGRES_USER: admin
  POSTGRES_DB: university
restart: always
networks:
  - my-network

Для сервисов groupe-service и student-service используются образы приложений, созданные при помощи Dockerfile. Также указывается порт взаимодействия, зависимость от сервиса БД (контейнер микросервиса запускается только после запуска контейнера БД). Сервис добавлятся в созданную сеть. Опция restart: always означает, что docker-compose перезапустит контейнер, если тот вдруг остановится.

  groupe-service:
    build:
      context: .
      dockerfile: ./groupe-service/Dockerfile
    container_name: groupe-service
    ports:
      - 8080:8080
    restart: always
    depends_on:
      - db-university
    networks:
      - my-network

  student-service:
    build:
      context: .
      dockerfile: ./student-service/Dockerfile
    container_name: student-service
    ports:
      - 8081:8081
    restart: always
    depends_on:
      - db-university
    networks:
      - my-network

Dockerfile сервиса groupe-service:

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

FROM openjdk:17-jdk

WORKDIR /app
COPY ./groupe-service/build/libs/groupe-service-1.0-SNAPSHOT.jar /app/groupe-service-1.0-SNAPSHOT.jar
EXPOSE 8080

CMD ["java", "-jar", "groupe-service-1.0-SNAPSHOT.jar"]

Dockerfile сервиса student-service:

Структура аналогична Dockerfile сервиса groupe-service.

FROM openjdk:17-jdk

WORKDIR /app
COPY ./student-service/build/libs/student-service-1.0-SNAPSHOT.jar /app/student-service-1.0-SNAPSHOT.jar
EXPOSE 8081

CMD ["java", "-jar", "student-service-1.0-SNAPSHOT.jar"]

Реализация шлюза на основе прозрачного прокси-сервера nginx:

Для сервиса nginx используется образ nginx, указывается порт взаимодействия. volumes указывает, что при запуске контейнера, локальный файл конфигураций nginx.conf следует поместить вместо стандартного файла конфигураций nginx, а depends_on указывает, что данный прокси-сервер зависит от обоих сервисов и разворачивается только после их запуска.

  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "80:80"
    networks:
      - my-network
    volumes:
      - ./nginx-conf:/etc/nginx/conf.d
    depends_on:
      - groupe-service
      - student-service

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

Данная конфигурация позволяет перенаправлять запросы, начинающиеся с /groupe-service/ на сервер groupe-service на порту 8080, а запросы, начинающиеся с /student-service/, на сервер student-service на порту 8081. Заголовки запроса также передаются и устанавливаются соответствующие значения для Host и X-Forwarded-Prefix. Заголовок Host будет установлен в значение $host, заголовок X-Forwarded-Prefix - в значение /student-service или /groupe-service.

server {
    listen 80;

    location /groupe-service/ {
        proxy_pass_request_headers on;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Prefix '/groupe-service';
        proxy_pass http://groupe-service:8080/;
    }

    location /student-service/ {
        proxy_pass_request_headers on;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Prefix '/student-service';
        proxy_pass http://student-service:8081/;

    }
}

Запуск сервисов

Результат выполнения команды docker-compose up -d:

Вывод в консоли

Созданные образы:

Созданные образы

Созданные контейнеры:

Созданные контейнеры

Результаты синхронного обмена сообщениями между микросервисами:

При получения списка студентов, сервис student-service обращается к сервису groupe-service, чтобы отобразить данные группы. results

Ссылка на видео: https://youtu.be/BCF0Lxc6veo