Files
ApiGatewayTest/README-krakend.md
T

12 KiB
Raw Blame History

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

# Построить образы и запустить с 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

curl http://localhost:8000/health

Статус всех сервисов

curl http://localhost:8000/gateway/status

User Service Endpoints через Gateway

Получить список пользователей

curl http://localhost:8000/users

Получить пользователя по ID

curl http://localhost:8000/users/1

Создать нового пользователя

curl -X POST http://localhost:8000/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Петр Иванов",
    "email": "petr@example.com",
    "age": 30
  }'

Обновить пользователя

curl -X PUT http://localhost:8000/users/1 \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Иван Петров (обновлено)",
    "email": "ivan.updated@example.com",
    "age": 29
  }'

Удалить пользователя

curl -X DELETE http://localhost:8000/users/1

Получить статистику пользователей

curl http://localhost:8000/users/stats

Order Service Endpoints через Gateway

Получить список продуктов

curl http://localhost:8000/products

Получить продукт по ID

curl http://localhost:8000/products/1

Создать новый продукт

curl -X POST http://localhost:8000/products \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Мышка беспроводная",
    "price": 1500.00,
    "quantity": 20
  }'

Обновить продукт

curl -X PUT http://localhost:8000/products/1 \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ноутбук (обновлено)",
    "price": 55000.00,
    "quantity": 3
  }'

Удалить продукт

curl -X DELETE http://localhost:8000/products/1

Получить список заказов

curl http://localhost:8000/orders

Получить заказ по ID

curl http://localhost:8000/orders/1

Создать новый заказ

curl -X POST http://localhost:8000/orders \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": 2,
    "product_id": 2,
    "quantity": 2
  }'

Получить статистику заказов

curl http://localhost:8000/orders/stats

Тестирование через Python requests

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 конфигурации

{
  "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

Мониторинг и отладка

# Проверить статус контейнеров
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