DAS_2023_1/basharin_sevastyan_lab_3/README.md

5.0 KiB
Raw Blame History

Лабораторная работа 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:

# 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 этот запрос обрабатывается следующим образом:

@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

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 микросервисов

# 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"]
# 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

# nginx/Dockerfile
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Видео

https://youtu.be/3-iF9xBHvCU