This commit is contained in:
2026-01-10 23:37:18 +03:00
parent 9ecf873877
commit c1c8bdfeaa
6 changed files with 24 additions and 653 deletions
+1 -1
View File
@@ -2,6 +2,6 @@ FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY service-1-main.py main.py
COPY service_1_main.py main.py
EXPOSE 8001
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8001"]
+1 -1
View File
@@ -2,6 +2,6 @@ FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY service-2-main.py main.py
COPY service_2_main.py main.py
EXPOSE 8002
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8002"]
-381
View File
@@ -1,381 +0,0 @@
# Примеры тестирования микросервисов через API Gateway KrakenD
## Структура проекта
```
.
├── service-1-main.py # User Service
├── service-2-main.py # Order Service
├── requirements.txt # Зависимости
├── Dockerfile.service1 # Docker образ для Service 1
├── Dockerfile.service2 # Docker образ для Service 2
├── docker-compose.yaml # Docker Compose без Gateway
├── docker-compose-krakend.yaml # Docker Compose с KrakenD Gateway
├── krakend-config.json # Конфигурация KrakenD
└── README.md # Документация
```
## Запуск контейнеров с KrakenD
```bash
# Построить образы и запустить с KrakenD Gateway
docker-compose -f docker-compose-krakend.yaml up --build
# Запустить в фоновом режиме
docker-compose -f docker-compose-krakend.yaml up -d --build
# Просмотреть логи всех сервисов
docker-compose -f docker-compose-krakend.yaml logs -f
# Просмотреть логи только KrakenD
docker-compose -f docker-compose-krakend.yaml logs -f api-gateway
# Остановить контейнеры
docker-compose -f docker-compose-krakend.yaml down
```
## API Gateway KrakenD
### Что такое KrakenD?
KrakenD - это высокопроизводительный API Gateway с открытым исходным кодом, написанный на Go. Он обеспечивает:
- **Маршрутизацию запросов** к микросервисам
- **Кэширование** ответов
- **Rate limiting** (ограничение частоты запросов)
- **CORS** (Cross-Origin Resource Sharing)
- **Трансформацию данных** перед отправкой клиенту
- **Логирование** запросов
- **Мониторинг** производительности
### Порты сервисов
- **KrakenD Gateway**: `http://localhost:8000` (главный точка входа)
- **Service 1**: `http://localhost:8001` (доступен также через Gateway)
- **Service 2**: `http://localhost:8002` (доступен также через Gateway)
## Тестирование через KrakenD Gateway
### Health Check Gateway
```bash
curl http://localhost:8000/health
```
### Статус всех сервисов
```bash
curl http://localhost:8000/gateway/status
```
## User Service Endpoints через Gateway
### Получить список пользователей
```bash
curl http://localhost:8000/users
```
### Получить пользователя по ID
```bash
curl http://localhost:8000/users/1
```
### Создать нового пользователя
```bash
curl -X POST http://localhost:8000/users \
-H "Content-Type: application/json" \
-d '{
"name": "Петр Иванов",
"email": "petr@example.com",
"age": 30
}'
```
### Обновить пользователя
```bash
curl -X PUT http://localhost:8000/users/1 \
-H "Content-Type: application/json" \
-d '{
"name": "Иван Петров (обновлено)",
"email": "ivan.updated@example.com",
"age": 29
}'
```
### Удалить пользователя
```bash
curl -X DELETE http://localhost:8000/users/1
```
### Получить статистику пользователей
```bash
curl http://localhost:8000/users/stats
```
## Order Service Endpoints через Gateway
### Получить список продуктов
```bash
curl http://localhost:8000/products
```
### Получить продукт по ID
```bash
curl http://localhost:8000/products/1
```
### Создать новый продукт
```bash
curl -X POST http://localhost:8000/products \
-H "Content-Type: application/json" \
-d '{
"name": "Мышка беспроводная",
"price": 1500.00,
"quantity": 20
}'
```
### Обновить продукт
```bash
curl -X PUT http://localhost:8000/products/1 \
-H "Content-Type: application/json" \
-d '{
"name": "Ноутбук (обновлено)",
"price": 55000.00,
"quantity": 3
}'
```
### Удалить продукт
```bash
curl -X DELETE http://localhost:8000/products/1
```
### Получить список заказов
```bash
curl http://localhost:8000/orders
```
### Получить заказ по ID
```bash
curl http://localhost:8000/orders/1
```
### Создать новый заказ
```bash
curl -X POST http://localhost:8000/orders \
-H "Content-Type: application/json" \
-d '{
"user_id": 2,
"product_id": 2,
"quantity": 2
}'
```
### Получить статистику заказов
```bash
curl http://localhost:8000/orders/stats
```
## Тестирование через Python requests
```python
import requests
import json
import time
# URL Gateway
GATEWAY_URL = "http://localhost:8000"
def test_users():
"""Тестирование User Service через Gateway"""
print("=== Testing User Service ===")
# Получение списка пользователей
response = requests.get(f"{GATEWAY_URL}/users")
print(f"GET /users: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
# Получение конкретного пользователя
response = requests.get(f"{GATEWAY_URL}/users/1")
print(f"GET /users/1: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
# Создание пользователя
user_data = {
"name": "Тест Пользователь",
"email": "test@example.com",
"age": 25
}
response = requests.post(f"{GATEWAY_URL}/users", json=user_data)
print(f"POST /users: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
# Получение статистики
response = requests.get(f"{GATEWAY_URL}/users/stats")
print(f"GET /users/stats: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
def test_products():
"""Тестирование Order Service (Products) через Gateway"""
print("=== Testing Product Service ===")
# Получение списка продуктов
response = requests.get(f"{GATEWAY_URL}/products")
print(f"GET /products: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
# Получение конкретного продукта
response = requests.get(f"{GATEWAY_URL}/products/1")
print(f"GET /products/1: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
# Создание продукта
product_data = {
"name": "Новый продукт",
"price": 5000.00,
"quantity": 10
}
response = requests.post(f"{GATEWAY_URL}/products", json=product_data)
print(f"POST /products: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
def test_orders():
"""Тестирование Order Service (Orders) через Gateway"""
print("=== Testing Order Service ===")
# Получение списка заказов
response = requests.get(f"{GATEWAY_URL}/orders")
print(f"GET /orders: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
# Получение конкретного заказа
response = requests.get(f"{GATEWAY_URL}/orders/1")
print(f"GET /orders/1: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
# Создание заказа
order_data = {
"user_id": 1,
"product_id": 2,
"quantity": 2
}
response = requests.post(f"{GATEWAY_URL}/orders", json=order_data)
print(f"POST /orders: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
# Получение статистики
response = requests.get(f"{GATEWAY_URL}/orders/stats")
print(f"GET /orders/stats: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
def test_gateway_status():
"""Проверка статуса Gateway и всех сервисов"""
print("=== Gateway Status ===")
# Health check Gateway
response = requests.get(f"{GATEWAY_URL}/health")
print(f"Gateway Health: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
# Статус всех сервисов
response = requests.get(f"{GATEWAY_URL}/gateway/status")
print(f"All Services Status: {response.status_code}")
print(f"Response: {json.dumps(response.json(), indent=2)}\n")
if __name__ == "__main__":
try:
test_gateway_status()
test_users()
test_products()
test_orders()
print("✓ Все тесты завершены успешно!")
except requests.exceptions.ConnectionError:
print("✗ Ошибка подключения. Убедитесь, что контейнеры запущены:")
print(" docker-compose -f docker-compose-krakend.yaml up -d --build")
except Exception as e:
print(f"✗ Ошибка: {e}")
```
## Конфигурация KrakenD (krakend-config.json)
### Основные параметры
- **version**: версия конфигурации (3)
- **timeout**: глобальный таймаут для запросов (3s)
- **cache_ttl**: время кэширования по умолчанию (300s)
- **output_encoding**: формат ответа (json)
### Endpoints
Для каждого endpoint определяются:
- **endpoint**: путь доступа через Gateway
- **method**: HTTP метод (GET, POST, PUT, DELETE)
- **backend**: список бэкенд сервисов для маршрутизации
- **cache_ttl**: время кэширования для этого endpoint
### Пример endpoint конфигурации
```json
{
"endpoint": "/users/{id}",
"method": "GET",
"backend": [
{
"url_pattern": "/users/{id}",
"method": "GET",
"host": ["service-1:8001"],
"disable_host_sanitize": false
}
],
"output_encoding": "json",
"cache_ttl": "60s"
}
```
### Extra Config (дополнительная конфигурация)
1. **Логирование** - INFO уровень с форматированием
2. **Rate Limiting** - максимум 100 запросов в минуту
3. **CORS** - разрешены все источники и методы
## Преимущества использования KrakenD
✅ **Высокая производительность** - написан на Go, обрабатывает тысячи RPS
✅ **Простая конфигурация** - JSON файл, легко редактировать
✅ **Встроенное кэширование** - улучшает скорость ответов
✅ **Rate limiting** - защита от перегрузки
✅ **CORS поддержка** - работа с веб-приложениями
✅ **Логирование** - отслеживание запросов
✅ **Health checks** - мониторинг состояния сервисов
✅ **Гибкая маршрутизация** - поддержка параметров в URL
## Мониторинг и отладка
```bash
# Проверить статус контейнеров
docker-compose -f docker-compose-krakend.yaml ps
# Просмотреть логи Gateway
docker-compose -f docker-compose-krakend.yaml logs api-gateway
# Подключиться к контейнеру Gateway
docker-compose -f docker-compose-krakend.yaml exec api-gateway /bin/sh
# Проверить подключение Gateway к Service 1
docker-compose -f docker-compose-krakend.yaml exec api-gateway curl http://service-1:8001/health
# Проверить подключение Gateway к Service 2
docker-compose -f docker-compose-krakend.yaml exec api-gateway curl http://service-2:8002/health
```
## Требования
- Docker 20.10+
- Docker Compose 2.0+
- Python 3.11+ (для локального запуска тестов)
- curl или PostMan для тестирования API
## Лицензия
MIT
+18 -258
View File
@@ -4,247 +4,40 @@
```
.
├── service-1-main.py # User Service
├── service-2-main.py # Order Service
├── postman # Готовые ручки для Postman
├── service_1_main.py # User Service
├── service_2_main.py # Order Service
├── requirements.txt # Зависимости
├── Dockerfile.service1 # Docker образ для Service 1
├── Dockerfile.service2 # Docker образ для Service 2
├── kakend-config.json # Конфигурация Krakend API Gateway
└── docker-compose.yaml # Конфигурация Docker Compose
```
## Запуск контейнеров
## Запуск
```bash
# Построить образы и запустить контейнеры
docker-compose up --build
# Запустить в фоновом режиме
docker-compose up -d --build
# Просмотреть логи
docker-compose logs -f
# или так, если ссыкло
docker-compose up --build
# Остановить контейнеры
docker-compose down
```
## Service 1 - User Service (порт 8001)
## Тест
Бля, скачай Postman и не еби мозги. Должен подхватить ручки из репы - если нет, тогда лох, пиши запросы сам.
### Health Check
```bash
curl http://localhost:8001/
curl http://localhost:8001/health
```
## Ручки
### Получить список пользователей
```bash
curl http://localhost:8001/users
```
### Получить пользователя по ID
```bash
curl http://localhost:8001/users/1
```
### Создать нового пользователя
```bash
curl -X POST http://localhost:8001/users \
-H "Content-Type: application/json" \
-d '{
"name": "Петр Иванов",
"email": "petr@example.com",
"age": 30
}'
```
### Обновить пользователя
```bash
curl -X PUT http://localhost:8001/users/1 \
-H "Content-Type: application/json" \
-d '{
"name": "Иван Петров (обновлено)",
"email": "ivan.updated@example.com",
"age": 29
}'
```
### Удалить пользователя
```bash
curl -X DELETE http://localhost:8001/users/1
```
### Получить статистику
```bash
curl http://localhost:8001/stats
```
## Service 2 - Order Service (порт 8002)
### Health Check
```bash
curl http://localhost:8002/
curl http://localhost:8002/health
```
### Получить список продуктов
```bash
curl http://localhost:8002/products
```
### Получить продукт по ID
```bash
curl http://localhost:8002/products/1
```
### Создать новый продукт
```bash
curl -X POST http://localhost:8002/products \
-H "Content-Type: application/json" \
-d '{
"name": "Мышка беспроводная",
"price": 1500.00,
"quantity": 20
}'
```
### Обновить продукт
```bash
curl -X PUT http://localhost:8002/products/1 \
-H "Content-Type: application/json" \
-d '{
"name": "Ноутбук (обновлено)",
"price": 55000.00,
"quantity": 3
}'
```
### Удалить продукт
```bash
curl -X DELETE http://localhost:8002/products/1
```
### Получить список заказов
```bash
curl http://localhost:8002/orders
```
### Получить заказ по ID
```bash
curl http://localhost:8002/orders/1
```
### Создать новый заказ
```bash
curl -X POST http://localhost:8002/orders \
-H "Content-Type: application/json" \
-d '{
"user_id": 2,
"product_id": 2,
"quantity": 2
}'
```
### Получить статистику
```bash
curl http://localhost:8002/stats
```
## Тестирование через Python requests
```python
import requests
import json
BASE_URL_SERVICE1 = "http://localhost:8001"
BASE_URL_SERVICE2 = "http://localhost:8002"
# Проверка здоровья Service 1
response = requests.get(f"{BASE_URL_SERVICE1}/health")
print(f"Service 1 Health: {response.json()}")
# Получение всех пользователей
response = requests.get(f"{BASE_URL_SERVICE1}/users")
print(f"Users: {response.json()}")
# Создание пользователя
user_data = {
"name": "Тест Пользователь",
"email": "test@example.com",
"age": 25
}
response = requests.post(f"{BASE_URL_SERVICE1}/users", json=user_data)
print(f"Created User: {response.json()}")
# Проверка здоровья Service 2
response = requests.get(f"{BASE_URL_SERVICE2}/health")
print(f"Service 2 Health: {response.json()}")
# Получение всех продуктов
response = requests.get(f"{BASE_URL_SERVICE2}/products")
print(f"Products: {response.json()}")
# Создание заказа
order_data = {
"user_id": 1,
"product_id": 3,
"quantity": 5
}
response = requests.post(f"{BASE_URL_SERVICE2}/orders", json=order_data)
print(f"Created Order: {response.json()}")
```
## Конфигурация API Gateway
Для проверки работы API Gateway, вы можете использовать:
1. **Kong** - популярный API Gateway
2. **NGINX** - простой и быстрый
3. **Traefik** - автоматическое обнаружение сервисов
4. **AWS API Gateway** - облачное решение
### Пример конфигурации NGINX
```nginx
upstream service1 {
server service-1:8001;
}
upstream service2 {
server service-2:8002;
}
server {
listen 8000;
server_name localhost;
location /api/users {
proxy_pass http://service1;
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 /api/products {
proxy_pass http://service2;
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 /api/orders {
proxy_pass http://service2;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
```
## Основные характеристики микросервисов
### API Gateway - Угадай
- **Порт**: 8000
- **Функционал**: Проксирование запросов, единая точка входа
- **Endpoints**:
- `GET /health` - Health check (Мне в падлу что-то еще прикручивать)
### Service 1 - User Service
- **Порт**: 8001
- **Функционал**: Управление пользователями (CRUD)
- **Функционал**: Управление пользователями (Крудошлепство)
- **Endpoints**:
- `GET /` - Проверка статуса
- `GET /health` - Health check
@@ -257,7 +50,7 @@ server {
### Service 2 - Order Service
- **Порт**: 8002
- **Функционал**: Управление продуктами и заказами (CRUD)
- **Функционал**: Управление продуктами и заказами (Крудошлепство 2)
- **Endpoints**:
- `GET /` - Проверка статуса
- `GET /health` - Health check
@@ -277,37 +70,4 @@ server {
- Встроенное логирование (INFO уровень)
- Health check endpoints
- Метрики статистики
- Документацию Swagger (автоматическая генерация)
### Доступ к Swagger документации
- Service 1: `http://localhost:8001/docs`
- Service 2: `http://localhost:8002/docs`
## Отладка
```bash
# Проверить статус контейнеров
docker-compose ps
# Просмотреть логи конкретного сервиса
docker-compose logs service-1
docker-compose logs service-2
# Подключиться к контейнеру
docker-compose exec service-1 /bin/bash
# Проверить сетевое подключение между сервисами
docker-compose exec service-1 curl http://service-2:8002/health
```
## Требования
- Docker 20.10+
- Docker Compose 2.0+
- Python 3.11+ (для локального запуска без Docker)
- curl или PostMan для тестирования API
## Лицензия
MIT
- Документацию Swagger на ручках /docs
+3 -6
View File
@@ -1,12 +1,9 @@
"""
Первый микросервис - Service 1
Предоставляет API для управления пользователями
"""
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
import logging
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI(
title="Service 1 - User Service",
description="Микросервис для управления пользователями",
+1 -6
View File
@@ -1,9 +1,4 @@
"""
Второй микросервис - Service 2
Предоставляет API для управления заказами и продуктами
"""
from typing import List, Optional
from typing import List
from datetime import datetime
import logging