# Примеры тестирования микросервисов через 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