Use when building cloud-native apps. Keywords: kubernetes, k8s, docker, container, grpc, tonic, microservice, service mesh, observability, tracing, metrics, health check, cloud, deployment, 云原生, 微服务, 容器
false
Cloud-Native Domain
Layer 3: Domain Constraints
Domain Constraints → Design Implications
Domain Rule
Design Constraint
Rust Implication
12-Factor
Config from env
Environment-based config
Observability
Metrics + traces
tracing + opentelemetry
Health checks
Liveness/readiness
Dedicated endpoints
Graceful shutdown
Clean termination
Signal handling
Horizontal scale
Stateless design
No local state
Container-friendly
Small binaries
Release optimization
Critical Constraints
Stateless Design
RULE: No local persistent state
WHY: Pods can be killed/rescheduled anytime
RUST: External state (Redis, DB), no static mut
RULE: Every request must be traceable
WHY: Debugging distributed systems
RUST: tracing spans, opentelemetry export
Trace Down ↓
From constraints to design (Layer 2):
"Need distributed tracing"
↓ m12-lifecycle: Span lifecycle
↓ tracing + opentelemetry
"Need graceful shutdown"
↓ m07-concurrency: Signal handling
↓ m12-lifecycle: Connection draining
"Need health checks"
↓ domain-web: HTTP endpoints
↓ m06-error-handling: Health status
Key Crates
Purpose
Crate
gRPC
tonic
Kubernetes
kube, kube-runtime
Docker
bollard
Tracing
tracing, opentelemetry
Metrics
prometheus, metrics
Config
config, figment
Health
HTTP endpoints
Design Patterns
Pattern
Purpose
Implementation
gRPC services
Service mesh
tonic + tower
K8s operators
Custom resources
kube-runtime Controller
Observability
Debugging
tracing + OTEL
Health checks
Orchestration
/health, /ready
Config
12-factor
Env vars + secrets
Code Pattern: Graceful Shutdown
usetokio::signal;asyncfnrun_server()-> anyhow::Result<()>{letapp=Router::new().route("/health",get(health)).route("/ready",get(ready));letaddr=SocketAddr::from(([0,0,0,0],8080));axum::Server::bind(&addr).serve(app.into_make_service()).with_graceful_shutdown(shutdown_signal()).await?;Ok(())}asyncfnshutdown_signal(){signal::ctrl_c().await.expect("failed to listen for ctrl+c");tracing::info!("shutdown signal received");}