antonov_dmitry_lab3_ready

This commit is contained in:
DmitriyAntonov 2023-12-04 18:24:11 +04:00
parent b166d347a9
commit fe7928f10c
10 changed files with 177 additions and 103 deletions

View File

@ -1,67 +1,54 @@
# Лабораторная работа №3 - Знакомство с docker и docker-compose # Лабораторная работа №3 - REST API, Gateway и синхронный обмен между микросервисами
Разверните 3 сервиса на выбор в контейнерах docker с помощью docker-compose. Изучение шаблона проектирования gateway, построения синхронного обмена между микросервисами и архитектурного стиля RESTful API.
Требования и docker-compose:
Несколько контейнеров. Создать два микросервиса.
Хотя бы один volume.
Хотя бы один порт, проброшенный на хост.
При этом разворачивание системы должно пройти до конца. Например, должен быть создан
администратор и система должна корректно функционировать. Это необходимо будет предоставить
в отчёте, поэтому не забывайте делать скриншоты.
# Выбранные сервисы Каждый сервис реализует CRUD-операции: список записей, подробности конкретной записи, создание, удаление и изменение записи.
В качестве хранилища данных может выступать оперативная память приложения или база данных.
Сущности необходимо подобрать по следующим критериям:
* mediawiki - движок вики Они должны быть связаны с предполагаемой темой диплома.
* drupal - популярная система управления контентом Они должны быть связаны как "1-ко-многим".
* wordpress - популярная система управления контентом.
# Задачи
* Создать 2 микросервиса, реализующих CRUD на связанных сущностях.
* Реализовать механизм синхронного обмена сообщениями между микросервисами.
* Реализовать шлюз на основе прозрачного прокси-сервера nginx.
# Запуск # Запуск
Командой в консоли проекта "docker-compose up -d" Командой в консоли проекта "docker-compose up -d"
# Описание работы: # Описание работы:
Развернули три сервиса плюс базу данных к ним. Развернули два приложения
Подробное описание для docker-compose дано в комментариях.
1. mediawiki: 1. Сервис с врачами:
- доступ на http://localhost:8080/ - доступ на http://localhost:5000/
2. drupal: 2. Сервис с пациентами:
- доступ на http://localhost:8081/ - доступ на http://localhost:5001/
3. wordpress: Сервисы связываются друг с другом через ссылку и библиотеку requests
- доступ на http://localhost:8082/
<p> <p>
<div>Старт сервисов</div> <div>Старт сервисов</div>
<img src="screens/img.png" width="650" title="Старт сервисов"> <img src="screens/img1.png" width="650" title="Сервисы">
</p> </p>
<p> <p>
<div>Сервисы</div> <div>Сервис врачей</div>
<img src="screens/img_1.png" width="650" title="Сервисы"> <img src="screens/img2.png" width="650" title="Сервис врачей">
</p> </p>
<p> <p>
<div>Images</div> <div>Сервис пациентов</div>
<img src="screens/img_2.png" width="650" title="Сервисы"> <img src="screens/img3.png" width="650" title="Сервис пациентов">
</p> </p>
<p> <p>
<div>Volumes</div> <div>Связь сервисов через библиотеку requests</div>
<img src="screens/img_3.png" width="650" title="Сервисы"> <img src="screens/img4.png" width="650" title="Связь сервисов">
</p>
<p>
<div>Сервис 1</div>
<img src="screens/img_4.png" width="650" title="Сервис 1">
</p>
<p>
<div>Сервис 2</div>
<img src="screens/img_5.png" width="650" title="Сервис 2">
</p>
<p>
<div>Сервис 3</div>
<img src="screens/img_6.png" width="650" title="Сервис 3">
</p> </p>
# Ссылка на видео # Ссылка на видео
https://disk.yandex.ru/i/nG5KrHy_DsQxuw https://disk.yandex.ru/i/3o4aLuqp1EpbJg

View File

@ -14,9 +14,9 @@ services:
nginx: nginx:
image: nginx image: nginx
ports: ports:
- "8085:8085" - "80:80"
volumes: volumes:
- ./nginx.conf:/etc/nginx/conf.d/nginx.conf - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on: depends_on:
- service_a - service_a
- service_b - service_b

View File

@ -1,13 +0,0 @@
server {
listen 8085;
listen [::]:8085;
server_name localhost;
location /service_a/ {
proxy_pass http://127.0.0.1:5000;
}
location /service_b/ {
proxy_pass http://127.0.0.1:5001;
}
}

View File

@ -0,0 +1,17 @@
server {
listen 80;
location /app1/ {
proxy_pass http://localhost:5000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /app2/ {
proxy_pass http://localhost:5001/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -1,42 +1,98 @@
from flask import Flask, jsonify, request from flask import Flask, jsonify, request
import requests
app = Flask(__name__) app = Flask(__name__)
# "customers" # набор данных докторов с их пациентами
customers_data = [] doctors_data = [
{
'id': 1,
'name': 'Doctor A',
'email': 'doctor.a@example.com',
'patients': [
{'id': 1, 'name': 'Patient A1', 'email': 'patient.a1@example.com'},
{'id': 2, 'name': 'Patient A2', 'email': 'patient.a2@example.com'},
],
},
{
'id': 2,
'name': 'Doctor B',
'email': 'doctor.b@example.com',
'patients': [
{'id': 3, 'name': 'Patient B1', 'email': 'patient.b1@example.com'},
{'id': 4, 'name': 'Patient B2', 'email': 'patient.b2@example.com'},
],
},
{
'id': 3,
'name': 'Doctor C',
'email': 'doctor.c@example.com',
'patients': [
{'id': 5, 'name': 'Patient C1', 'email': 'patient.c1@example.com'},
],
},
]
# URL для сервиса пациентов
patients_service_url = "http://localhost/app2/patients"
@app.route('/service_a/', methods=['GET']) @app.route('/', methods=['GET'])
def get_index(): def get_index():
return "Hello from service_a" return "это первый сервис"
@app.route('/service_a/customers', methods=['GET']) @app.route('/doctors', methods=['GET'])
def get_customers(): def get_doctors():
return jsonify(customers_data) return jsonify(doctors_data)
@app.route('/service_a/customers', methods=['POST']) @app.route('/doctors', methods=['POST'])
def create_customer(): def create_doctor():
new_customer = request.json new_doctor = request.json
customers_data.append(new_customer) # уникальный id для нового доктора
return jsonify(new_customer), 201 new_doctor['id'] = len(doctors_data) + 1
new_doctor['patients'] = []
doctors_data.append(new_doctor)
return jsonify(new_doctor), 201
@app.route('/service_a/customers/<int:id>', methods=['PUT']) @app.route('/doctors/<int:id>', methods=['PUT'])
def update_customer(id): def update_doctor(id):
for customer in customers_data: for doctor in doctors_data:
if customer['id'] == id: if doctor['id'] == id:
customer.update(request.json) doctor.update(request.json)
return jsonify(customer), 200 return jsonify(doctor), 200
return jsonify({'error': 'Customer not found'}), 404 return jsonify({'error': 'Доктор не найден'}), 404
@app.route('/service_a/customers/<int:id>', methods=['DELETE']) @app.route('/doctors/<int:id>', methods=['DELETE'])
def delete_customer(id): def delete_doctor(id):
global customers_data global doctors_data
customers_data = [customer for customer in customers_data if customer['id'] != id] doctors_data = [doctor for doctor in doctors_data if doctor['id'] != id]
return jsonify({'message': 'Customer deleted'}), 200 return jsonify({'message': 'Доктор удален'}), 200
@app.route('/doctors/<int:id>/patients', methods=['GET'])
def get_doctor_patients(id):
for doctor in doctors_data:
if doctor['id'] == id:
return jsonify(doctor['patients'])
return jsonify({'error': 'Доктор не найден'}), 404
@app.route('/doctors/<int:id>/patients', methods=['POST'])
def create_doctor_patient(id):
for doctor in doctors_data:
if doctor['id'] == id:
new_patient = request.json
# назначить уникальный id новому пациенту
new_patient['id'] = len(doctor['patients']) + 1
doctor['patients'].append(new_patient)
requests.post(patients_service_url, json=new_patient)
return jsonify(new_patient), 201
return jsonify({'error': 'Доктор не найден'}), 404
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,42 +1,69 @@
from flask import Flask, jsonify, request from flask import Flask, jsonify, request
import requests
app = Flask(__name__) app = Flask(__name__)
# "clients" # набор данных пациентов и их врачей
clients_data = [] patients_data = [
{'id': 1, 'name': 'Patient A', 'email': 'patient.a@example.com', 'doctor_id': 1},
{'id': 2, 'name': 'Patient B', 'email': 'patient.b@example.com', 'doctor_id': 2},
{'id': 3, 'name': 'Patient C', 'email': 'patient.c@example.com', 'doctor_id': 1},
]
# URL сервиса докторов
doctor_service_url = "http://localhost:5000"
@app.route('/', methods=['GET']) @app.route('/', methods=['GET'])
def get_index(): def get_index():
return "Hello from service_b" return "это второй сервис"
@app.route('/clients', methods=['GET']) @app.route('/patients', methods=['GET'])
def get_clients(): def get_patients():
return jsonify(clients_data) return jsonify(patients_data)
@app.route('/clients', methods=['POST']) @app.route('/patients/<int:id>', methods=['GET'])
def create_client(): def get_patient(id):
new_client = request.json for patient in patients_data:
clients_data.append(new_client) if patient['id'] == id:
return jsonify(new_client), 201 return jsonify(patient)
return jsonify({'error': 'Пациент не найден'}), 404
@app.route('/clients/<int:id>', methods=['PUT']) @app.route('/patients', methods=['POST'])
def update_client(id): def create_patient():
for client in clients_data: new_patient = request.json
if client['id'] == id: # назначить уникальный id новому пациенту
client.update(request.json) new_patient['id'] = len(patients_data) + 1
return jsonify(client), 200 patients_data.append(new_patient)
return jsonify({'error': 'Client not found'}), 404
# отправляем запрос другому сервису
requests.post(f"{doctor_service_url}/doctors/1/patients", json=new_patient)
return jsonify(new_patient), 201
@app.route('/clients/<int:id>', methods=['DELETE']) @app.route('/patients/<int:id>', methods=['PUT'])
def delete_client(id): def update_patient(id):
global clients_data for patient in patients_data:
clients_data = [client for client in clients_data if client['id'] != id] if patient['id'] == id:
return jsonify({'message': 'Client deleted'}), 200 patient.update(request.json)
# отправляем запрос другому сервису
response = requests.put(f"{doctor_service_url}/doctors/1/patients/{id}", json=request.json)
return jsonify(patient), 200
return jsonify({'error': 'Пациент не найден'}), 404
@app.route('/patients/<int:id>', methods=['DELETE'])
def delete_patient(id):
# отправляем запрос другому сервису
response = requests.delete(f"{doctor_service_url}/doctors/1/patients/{id}")
global patients_data
patients_data = [patient for patient in patients_data if patient['id'] != id]
return jsonify({'message': 'Пациент удален'}), 200
if __name__ == '__main__': if __name__ == '__main__':