.. | ||
groupe-service | ||
nginx-conf | ||
student-service | ||
build_images.png | ||
containers.png | ||
docker-compose.yml | ||
images.png | ||
README.md | ||
results.png |
Лабораторная работа №3
ПИбд-42 Машкова Маргарита
Задание
- Создать 2 микросервиса, реализующих CRUD на связанных сущностях.
- Реализовать механизм синхронного обмена сообщениями между микросервисами.
- Реализовать шлюз на основе прозрачного прокси-сервера 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
,
чтобы отобразить данные группы.
Ссылка на видео: https://youtu.be/BCF0Lxc6veo