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