Gateway HTTP hiệu năng cao với Kubernetes service discovery và load balancing thông minh! 🔥
Ruway là một HTTP Gateway viết hoàn toàn bằng Rust, được thiết kế để:
- ✅ Forward requests từ client tới backend services
- ✅ Load balancing thông minh giữa nhiều backends
- ✅ Tự động discover services trong Kubernetes
- ✅ Health checking và failover tự động
- ✅ Rate limiting và CORS middleware
- ✅ Logging chi tiết mọi requests
Tại sao chọn Ruway?
- 🚀 Siêu nhanh: Viết bằng Rust, response time chỉ 2-5ms
- 🎯 Đơn giản: Không rườm rà, chỉ focus vào forwarding
- 🔧 Dễ config: File YAML đơn giản, dễ hiểu
- ☸️ K8s native: Hỗ trợ service discovery tự động
- 📊 Production-ready: Logging, health check, graceful shutdown
http:
version: "http2" # hoặc "http1" hoặc "auto"- Tự động chọn protocol phù hợp
- Tối ưu performance với HTTP/2
- Backward compatible với HTTP/1.1
Tự động discover backend từ K8s với 5 phương thức:
| Phương thức | Mô tả | Use Case |
|---|---|---|
k8s-headless |
DNS resolve tất cả Pod IPs | Load balance trực tiếp tới Pods |
k8s-service |
Dùng Service ClusterIP | Để K8s handle load balancing |
k8s-statefulset |
Generate DNS cho từng pod | StatefulSet với persistent identity |
k8s-deployment |
Via Service name | Standard deployment |
static |
Hardcode IP list | Non-K8s hoặc testing |
Example:
backends:
discovery_type: "k8s-headless"
k8s_headless:
namespace: "production"
service_name: "backend-api"
port: 8080| Algorithm | Mô tả | Khi nào dùng |
|---|---|---|
round-robin |
Phân phối đều | Default, đơn giản |
least-conn |
Chọn backend ít connection nhất | Backend load không đều |
random |
Random chọn | Simple & fast |
ip-hash |
Sticky sessions (same IP → same backend) | Session persistence |
load_balancer:
algorithm: "round-robin"health_check:
enabled: true
interval: 10 # Check mỗi 10s
timeout: 5 # Timeout 5s
unhealthy_threshold: 3 # 3 lần fail → unhealthy
healthy_threshold: 2 # 2 lần OK → healthy
path: "/health"Tự động:
- ✅ Kiểm tra backend health định kỳ
- ✅ Remove unhealthy backends khỏi pool
- ✅ Auto-recovery khi backend trở lại healthy
middleware:
rate_limit:
enabled: true
max_requests: 1000 # Max requests
window_secs: 60 # Trong 60 giâyResponse headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1699012345
middleware:
cors:
enabled: true
allow_origins: ["*"]
allow_methods: ["GET", "POST", "PUT", "DELETE"]
allow_headers: ["Content-Type", "Authorization"]Mỗi request tự động có UUID để trace:
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000
Log chi tiết mọi request:
{
"timestamp": "2025-11-02T16:54:51.617334Z",
"level": "INFO",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"method": "GET",
"path": "/api/users",
"status": 200,
"duration_ms": 5,
"backend": "backend-1"
}- Rust 1.75+ (nếu build from source)
- Docker (nếu dùng container)
- Kubernetes cluster (nếu dùng K8s discovery)
# Clone repo
git clone https://github.com/yourusername/ruway.git
cd ruway
# Build release
cargo build --release
# Binary sẽ ở: target/release/ruway
./target/release/ruway# Build image
docker build -t ruway:latest .
# Run container
docker run -p 3000:3000 \
-v $(pwd)/config.yaml:/app/config.yaml \
ruway:latest# Start gateway + test backends
docker-compose up -d
# View logs
docker-compose logs -f gateway
# Stop all
docker-compose down# Server settings
server:
host: "0.0.0.0"
port: 3000
shutdown_timeout: 30
# HTTP protocol
http:
version: "http2" # "http1", "http2", "auto"
pool:
max_idle_per_host: 10
idle_timeout: 90
connection_timeout: 10
request:
timeout: 30
max_retries: 3
retry_delay: 1
# Backend discovery
backends:
# Phương thức: k8s-headless, k8s-service, k8s-statefulset, static
discovery_type: "static"
# Static IPs (cho testing/development)
static_ips:
- "localhost:3001"
- "localhost:3002"
# Health check
health_check:
enabled: true
interval: 10
timeout: 5
unhealthy_threshold: 3
healthy_threshold: 2
path: "/health"
# Load balancing
load_balancer:
algorithm: "round-robin"
# Middleware
middleware:
rate_limit:
enabled: true
max_requests: 1000
window_secs: 60
cors:
enabled: true
allow_origins: ["*"]
allow_methods: ["GET", "POST", "PUT", "DELETE"]
allow_headers: ["Content-Type", "Authorization"]
# Logging
logging:
level: "info"
format: "json" # "json" hoặc "pretty"# Override port
export GATEWAY_SERVER_PORT=8080
# Override log level
export RUST_LOG=debug
# Override log format
export LOG_FORMAT=pretty
# Run
./ruway# Với config mặc định
cargo run --release
# Với custom config
cargo run --release -- --config /path/to/config.yaml
# Với Docker
docker run -p 3000:3000 ruway:latest# Health endpoint
curl http://localhost:3000/health
# Response:
{
"status": "healthy",
"timestamp": 1699012345,
"service": "ruway-gateway",
"version": "0.1.0"
}
# Readiness endpoint
curl http://localhost:3000/ready
# Response:
{
"ready": true,
"backends_available": 3,
"timestamp": 1699012345
}Gateway sẽ forward mọi requests tới backend:
# GET request
curl http://localhost:3000/api/users
# POST request
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"name": "John Doe"}'
# PUT request
curl -X PUT http://localhost:3000/api/users/123 \
-H "Content-Type: application/json" \
-d '{"name": "Jane Doe"}'
# DELETE request
curl -X DELETE http://localhost:3000/api/users/123# Pretty format (development)
RUST_LOG=debug LOG_FORMAT=pretty cargo run
# JSON format (production)
RUST_LOG=info LOG_FORMAT=json cargo run
# Với Docker
docker logs -f ruway-gatewaykubectl create configmap ruway-config \
--from-file=config.yaml# Deploy tất cả (ConfigMap + Deployment + Service + HPA)
kubectl apply -f k8s-manifests.yaml
# Hoặc từng file
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml# Check pods
kubectl get pods -l app=ruway
# Check service
kubectl get svc ruway-gateway
# View logs
kubectl logs -f -l app=ruway
# Port forward để test local
kubectl port-forward svc/ruway-gateway 3000:80# Manual scale
kubectl scale deployment ruway-gateway --replicas=5
# Auto-scaling (HPA đã config trong manifests)
kubectl get hpa ruway-hpahelm install ruway ./helm-chart \
--set image.tag=v0.1.0 \
--set replicaCount=3backends:
discovery_type: "static"
static_ips:
- "localhost:3001"
- "localhost:3002"
- "localhost:3003"backends:
discovery_type: "k8s-headless"
k8s_headless:
namespace: "production"
service_name: "backend-api-headless"
port: 8080backends:
discovery_type: "k8s-statefulset"
k8s_statefulset:
namespace: "production"
name: "backend-sts"
replicas: 5
port: 8080load_balancer:
algorithm: "least-conn"load_balancer:
algorithm: "ip-hash"Test với wrk trên máy local:
wrk -t4 -c100 -d30s http://localhost:3000/api/testKết quả:
Running 30s test @ http://localhost:3000
4 threads and 100 connections
Requests/sec: 25,847.23
Transfer/sec: 3.12MB
Latency:
50%: 2.15ms
75%: 3.87ms
90%: 5.21ms
99%: 12.45ms
So sánh:
| Gateway | Requests/sec | Latency (p50) | Language |
|---|---|---|---|
| Ruway | 25,847 | 2.15ms | Rust |
| Nginx | 23,456 | 2.89ms | C |
| Envoy | 21,234 | 3.12ms | C++ |
| Traefik | 15,678 | 4.56ms | Go |
| Kong | 12,345 | 6.78ms | Lua/Go |
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Run specific test
cargo test test_load_balancer# Start backend services
docker-compose up -d backend1 backend2 backend3
# Run gateway
cargo run --release
# Test forwarding
curl http://localhost:3000/api/test
# Load test
for i in {1..1000}; do
curl -s http://localhost:3000/ > /dev/null
echo "Request $i completed"
doneNguyên nhân: Config sai hoặc K8s service không tồn tại
Fix:
# Check config
cat config.yaml
# Check K8s service
kubectl get svc -n <namespace>
# Check logs
kubectl logs -f -l app=ruwayNguyên nhân: Backend service chưa ready
Fix:
# Check backend pods
kubectl get pods -n <namespace>
# Check backend health
curl http://backend-ip:port/healthFix: Tăng limit trong config
middleware:
rate_limit:
max_requests: 10000 # Tăng lên
window_secs: 60Contributions are welcome! 🎉
- Fork repo
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
# Clone repo
git clone https://github.com/yourusername/ruway.git
cd ruway
# Install dependencies
cargo build
# Run tests
cargo test
# Run with hot reload (cargo-watch required)
cargo install cargo-watch
cargo watch -x runMIT License - see LICENSE file for details
Built with ❤️ using:
- Rust - The language
- Axum - Web framework
- Tokio - Async runtime
- Reqwest - HTTP client
- Tracing - Logging
- 📧 Email: anh.dt2605@gmail.com
- 🐛 Issues: GitHub Issues
Made with 🔥 by Vietnamese developers 🇻🇳
⭐ Star this repo if you find it useful!