206 lines
8.9 KiB
Markdown
206 lines
8.9 KiB
Markdown
|
# Лабораторная работа №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`:
|
|||
|
![Вывод в консоли](build_images.png)
|
|||
|
|
|||
|
### Созданные образы:
|
|||
|
![Созданные образы](images.png)
|
|||
|
|
|||
|
### Созданные контейнеры:
|
|||
|
![Созданные контейнеры](containers.png)
|
|||
|
|
|||
|
### Результаты синхронного обмена сообщениями между микросервисами:
|
|||
|
При получения списка студентов, сервис `student-service` обращается к сервису `groupe-service`,
|
|||
|
чтобы отобразить данные группы.
|
|||
|
![results](results.png)
|
|||
|
|
|||
|
Ссылка на видео:
|
|||
|
https://youtu.be/BCF0Lxc6veo
|