docker-compose.yml — Single-node + vmagent + vmalert
Listo para producción NutriFlow
# docker-compose.ymlservices:
victoriametrics:
image: victoriametrics/victoria-metrics:v1.96.0
command:
- '-storageDataPath=/victoria-metrics-data'
- '-retentionPeriod=90d' # 90 días para NutriFlow
- '-httpListenAddr=:8428'
- '-search.maxUniqueTimeseries=2000000' # 2M series para escala actual
- '-dedup.minScrapeInterval=15s'
ports: ["8428:8428"]
volumes: [vm_data:/victoria-metrics-data]
restart: always
vmagent:
image: victoriametrics/vmagent:v1.96.0
command:
- '-promscrape.config=/etc/vmagent/scrape.yml'
- '-remoteWrite.url=http://victoriametrics:8428/api/v1/write'
- '-remoteWrite.tmpDataPath=/vmagent-remotewrite-data'
- '-promscrape.maxScrapeSize=64MB'
volumes:
- ./vmagent-scrape.yml:/etc/vmagent/scrape.yml:ro
- vmagent_data:/vmagent-remotewrite-data
vmalert:
image: victoriametrics/vmalert:v1.96.0
command:
- '-datasource.url=http://victoriametrics:8428'
- '-notifier.url=http://alertmanager:9093'
- '-rule=/etc/vmalert/rules/*.yml'
- '-evaluationInterval=30s'
volumes: [./alert-rules:/etc/vmalert/rules:ro]
alertmanager:
image: prom/alertmanager:v0.26.0
volumes: [./alertmanager.yml:/etc/alertmanager/config.yml:ro]
ports: ["9093:9093"]
volumes: { vm_data: {}, vmagent_data: {} }
vmagent-scrape.yml
Kubernetes + servicios estáticos
global:
scrape_interval: 15s
external_labels:
cluster: nutriflow-prod
env: production
scrape_configs:
- job_name: nutriflow-services
static_configs:
- targets:
- api-gateway:8080
- plan-service:8080
- billing-service:8080
labels:
team: backend
product: nutriflow
metrics_path: /metrics
relabel_configs:
- source_labels: [__address__]
regex: '([^:]+):.*'
target_label: service
- job_name: node-exporter
static_configs:
- targets: ['node-exporter:9100']
labels:
environment: production
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels:
[__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels:
[__meta_kubernetes_namespace]
target_label: namespace
alert-rules/service-alerts.yml
Umbrales NutriFlow
HighErrorRate
error_rate > 0.03 (umbral: 3% — más estricto que default)
P99LatencySpike — plan-service
quantile_over_time(0.99, duration[5m]) > 2.5
HighMemoryUsage
mem_used / mem_total > 0.85
BillingServiceDown
up{service="billing-service"} == 0
Queries MetricsQL — Dashboards Grafana NutriFlow
MetricsQL extiende PromQL con funciones avanzadas
Request Rate por servicio (panel principal)
PromQL compatible
sum(rate(http_requests_total{product="nutriflow"}[5m])) by (service)
Muestra RPS de api-gateway, plan-service y billing-service en tiempo real
Latencia P99 por servicio
PromQL compatible
quantile_over_time(0.99, http_request_duration_seconds{product="nutriflow"}[5m]) by (service)
Percentil 99 de latencia — detecta cuellos de botella en plan-service (llamadas IA)
Top 3 endpoints con mayor error rate
MetricsQL exclusivo
topk_avg(3,
sum(rate(http_requests_total{status=~"5..",product="nutriflow"}[5m])) by (endpoint)
/ sum(rate(http_requests_total{product="nutriflow"}[5m])) by (endpoint)
)
topk_avg (MetricsQL) evita spikes temporales que engañan a topk() estándar
Total acumulado de planes generados (últimas 24h)
MetricsQL exclusivo
running_sum(increase(plans_generated_total{service="plan-service"}[1h]))
running_sum no existe en PromQL — muestra curva acumulativa de planes IA del día
CPU median suavizado (todos los nodos)
MetricsQL exclusivo
range_median(cpu_usage_percent{cluster="nutriflow-prod",instance=~"gke-node-.*"})
range_median elimina outliers transitorios — mejor que avg() para capacity planning
VictoriaMetrics vs Prometheus
Benchmark para escala NutriFlow
| Métrica | Prometheus | VictoriaMetrics |
|---|---|---|
| RAM para 800k series | ~6.4 GB | ~1.8 GB |
| Disk (90d · 2M pts/min) | ~420 GB | ~95 GB |
| Velocidad de ingesta | ||
| Tiempo query 90d range | ~8.2s | ~0.9s |
| HA / Dedup nativo | ❌ Requiere Thanos | ✅ -dedup flag |
| Retención configurable | ⚠️ Limitado | ✅ -retentionPeriod=90d |
Recording rules — Optimización Grafana
Pre-compute para dashboards rápidos
# alert-rules/recording-rules.ymlgroups:
- name: nutriflow-precomputed
interval: 30s
rules:
# RPS por servicio — panel principal Grafana
- record: service:request_rate:5m
expr: |
sum(rate(http_requests_total[5m]))
by (service)
# Error rate — usado en alertas y SLO panel
- record: service:error_rate:5m
expr: |
sum(rate(http_requests_total
{status=~"5.."}[5m])) by (service)
/
sum(rate(http_requests_total[5m])) by (service)
# P95 latencia billing-service (crítico)
- record: billing:p95_latency:5m
expr: |
quantile_over_time(0.95,
http_request_duration_seconds
{service="billing-service"}[5m])