Files
ApiGatewayTest/README-krakend.md
T

382 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Примеры тестирования микросервисов через 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