DAS_2023_1/basharin_sevastyan_lab_3/README.md

167 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Лабораторная работа 3. Вариант 5.
### Как запустить
В директории с файлом `docker-compose.yaml` выполнить команду:
```
docker-compose up -d
```
Это запустит `docker-compose`, который создаст контейнер и развернет в нем 3 контейнера.
### Файловая иерархия
```
basharin_sevastyan_lab_3/
|-- user_service/
| |-- Dockerfile
| |-- requirements.txt
| |-- user_service.py
|-- order_service/
| |-- Dockerfile
| |-- requirements.txt
| |-- order_service.py
|-- nginx/
| |-- Dockerfile
| |-- nginx.conf
|-- docker-compose.yml
```
### Описание работы
#### Описание предметной области
Объекты микросервисов буду связаны следующим образом:
```
user (single) <- order (many)
```
#### Синхронный обмен сообщениями
`order_service` будет отправлять http-запрос на `user_service` при определенных crud операциях. Например, при создании
экземпляра `order`, будет отправлен запрос на добавление `order` к определенному `user`:
```python
# CREATE
@app.route('/add_order/<int:user_id>_<string:product>', methods=['POST'])
def create_order(user_id, product):
order = {'id': len(orders) + 1,
'user_id': user_id,
'product': product,
'action': 'create'}
orders.append(order)
# Отправка сообщения о создании заказа
requests.post("http://user-service:5001/event", json=order)
return jsonify(order)
```
В `user_service` этот запрос обрабатывается следующим образом:
```python
@app.route('/event', methods=['POST'])
def event():
print('получено сообщение')
data = request.get_json()
print(data)
user_id = data.get('user_id')
if data['action'] == 'create':
# Создание заказа у пользователя
user = next((user for user in users if user['id'] == user_id), None)
if user:
order_id = len(user.get('orders', [])) + 1
order = {'id': order_id, 'product': data['product']}
user.setdefault('orders', []).append(order)
print(f"Order created for user {user_id}: {order}")
else:
print(f"User not found for order creation: {user_id}")
elif data['action'] == 'update':
# Обновление заказа у пользователя
user = next((user for user in users if user['id'] == user_id), None)
if user:
order_id = data.get('id')
order = next((order for order in user['orders'] if order['id'] == order_id), None)
if order:
order['product'] = data['product']
print(f"Order updated for user {user_id}: {order}")
else:
print(f"Order not found for update: {order_id}")
else:
print(f"User not found for order update: {user_id}")
elif data['action'] == 'delete':
# Удаление заказа у пользователя
user = next((user for user in users if user['id'] == user_id), None)
if user:
order_id = user.get('id')
user['orders'] = [order for order in user.get('orders', []) if order['id'] != order_id]
print(f"Order deleted for user {user_id}: {order_id}")
else:
print(f"User not found for order deletion: {user_id}")
return jsonify({'result': True})
```
### Описание docker-compose
```yaml
version: '3.8'
services:
user-service:
build:
context: ./user_service
ports:
- "5001:5001"
networks:
- my_network
restart: always
order-service:
build:
context: ./order_service
ports:
- "5002:5002"
networks:
- my_network
restart: always
nginx:
image: nginx:latest
ports:
- "80:80"
depends_on:
- user-service
- order-service
networks:
- my_network
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
restart: always
networks:
my_network:
driver: bridge
```
### Dockerfile микросервисов
```dockerfile
# user_service/Dockerfile
FROM python:3.11
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app
CMD ["gunicorn", "--bind", "0.0.0.0:5001", "user_service:app"]
```
```dockerfile
# order_service/Dockerfile
FROM python:3.11
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app
CMD ["gunicorn", "--bind", "0.0.0.0:5002", "order_service:app"]
```
### Dockerfile nginx
```dockerfile
# nginx/Dockerfile
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```
### Видео
https://youtu.be/3-iF9xBHvCU