diff --git a/basharin_sevastyan_lab_3/README.md b/basharin_sevastyan_lab_3/README.md index e4c6c46..f8c71ba 100644 --- a/basharin_sevastyan_lab_3/README.md +++ b/basharin_sevastyan_lab_3/README.md @@ -1,3 +1,13 @@ +# Лабораторная работа 3. Вариант 5. + +### Как запустить +В директории с файлом `docker-compose.yaml` выполнить команду: +``` +docker-compose up -d +``` +Это запустит `docker-compose`, который создаст контейнер и развернет в нем 3 контейнера. + +### Файловая иерархия ``` basharin_sevastyan_lab_3/ |-- user_service/ @@ -14,8 +24,78 @@ basharin_sevastyan_lab_3/ |-- docker-compose.yml ``` +### Описание работы +#### Описание предметной области +Объекты микросервисов буду связаны следующим образом: +``` +user (single) <- order (many) +``` +#### Синхронный обмен сообщениями +`order_service` будет отправлять http-запрос на `user_service` при определенных crud операциях. Например, при создании +экземпляра `order`, будет отправлен запрос на добавление `order` к определенному `user`: +```python +# CREATE +@app.route('/add_order/_', 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' +version: '3.8' services: user-service: @@ -23,49 +103,65 @@ services: context: ./user_service ports: - "5001:5001" - depends_on: - - rabbitmq + networks: + - my_network + restart: always order-service: build: context: ./order_service ports: - "5002:5002" - depends_on: - - rabbitmq - - rabbitmq: - image: "rabbitmq:management" - ports: - - "5672:5672" - - "15672:15672" + networks: + - my_network + restart: always nginx: - build: - context: ./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 . . -CMD ["python", "user_service.py"] +COPY . /app +CMD ["gunicorn", "--bind", "0.0.0.0:5001", "user_service:app"] ``` - ```dockerfile -# user_service/Dockerfile +# order_service/Dockerfile FROM python:3.11 WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -COPY . . -CMD ["python", "order_service.py"] -``` \ No newline at end of file +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 \ No newline at end of file diff --git a/basharin_sevastyan_lab_3/user_service/user_service.py b/basharin_sevastyan_lab_3/user_service/user_service.py index 7249978..245f2ee 100644 --- a/basharin_sevastyan_lab_3/user_service/user_service.py +++ b/basharin_sevastyan_lab_3/user_service/user_service.py @@ -71,8 +71,7 @@ users = [] # while True: # connection.process_data_events(time_limit=1) -# CRUD операции для пользователей -# READ ALL + @app.route('/event', methods=['POST']) def event(): print('получено сообщение') @@ -116,6 +115,9 @@ def event(): print(f"User not found for order deletion: {user_id}") return jsonify({'result': True}) + +# CRUD операции для пользователей +# READ ALL @app.route('/users', methods=['GET']) def show_users(): return users