Skip to main content

Runbook: Utilizzo CPU Elevato

Severita: Warning Alert Prometheus: HighCPUUsage

Descrizione

Questo alert si attiva quando un container nel namespace pos-enterprise utilizza piu dell'80% del limite CPU configurato per un periodo prolungato (>10 minuti). A differenza della memoria, superare il limite CPU non causa la terminazione del pod ma provoca throttling: il kernel limita il tempo CPU del container, causando rallentamenti significativi.

Regola Prometheus:

(rate(container_cpu_usage_seconds_total{namespace="pos-enterprise", container!=""}[5m])
/ on(pod, container) kube_pod_container_resource_limits{namespace="pos-enterprise", resource="cpu"})
> 0.8

Impatto

  • CPU throttling: le richieste vengono elaborate piu lentamente, aumentando la latenza (p99).
  • Timeout Moleculer: le action call possono superare il requestTimeout (default 10s), generando RequestTimeoutError.
  • Health check falliti: le liveness/readiness probe possono non rispondere in tempo, causando restart.
  • Effetto domino: la coda di richieste si accumula, saturando ulteriormente la CPU.
  • Esperienza utente: l'app cassa/waiter diventa lenta, gli operatori segnalano rallentamenti.

Diagnosi

1. Identificare i pod con CPU alta

# Top pod per CPU
kubectl top pods -n pos-enterprise --sort-by=cpu

# Dettaglio per container
kubectl top pod <POD_NAME> -n pos-enterprise --containers

2. Verificare il throttling

# Secondi di throttling al secondo (Grafana)
rate(container_cpu_cfs_throttled_seconds_total{namespace="pos-enterprise", container="moleculer"}[5m])

# Percentuale di periodi con throttling
rate(container_cpu_cfs_throttled_periods_total{namespace="pos-enterprise"}[5m])
/ rate(container_cpu_cfs_periods_total{namespace="pos-enterprise"}[5m])

3. Analizzare il carico di richieste

# Verificare le metriche Moleculer del servizio
curl -s https://platform.sellogic.cloud/api/\$node/actions | jq '
.[] | select(.count > 0) | {name, count, "avgTime": (.time.mean | round)}
' | head -40
# Request rate per azione (Grafana)
rate(moleculer_request_total{namespace="pos-enterprise"}[5m])

# Azioni piu lente (correlazione CPU)
histogram_quantile(0.99, rate(moleculer_request_duration_seconds_bucket{namespace="pos-enterprise"}[5m]))

4. Verificare lo stato HPA (se configurato)

kubectl get hpa -n pos-enterprise
kubectl describe hpa <HPA_NAME> -n pos-enterprise

5. Profiling CPU del processo Node.js

# Generare un CPU profile (30 secondi)
kubectl exec <POD_NAME> -n pos-enterprise -- \
node --cpu-prof --cpu-prof-dir=/tmp --cpu-prof-interval=100 -e "
setTimeout(() => process.exit(0), 30000);
"

# In alternativa, usare il profiler built-in di V8
kubectl port-forward <POD_NAME> -n pos-enterprise 9229:9229
# Connettere Chrome DevTools e registrare un CPU profile

6. Identificare hot path comuni

I servizi Moleculer con maggior consumo CPU tipicamente sono:

ServizioCausa comuneSoglia normale
api-gatewaySerializzazione JSON di risposte grandi< 200m
orders-nodeCalcolo totali, validazione ordini< 300m
products-nodeRicerca full-text, filtri complessi< 200m
knowledge-nodeElaborazione embedding< 400m
printer-nodeGenerazione comandi ESC/POS< 150m
cash-nodeAggregazione report, calcoli< 250m
scheduler-nodeJob batch concorrenti< 300m (picco)

Risoluzione

Azione immediata: scaling orizzontale

# Aumentare le repliche del deployment sovraccarico
kubectl scale deployment <DEPLOY_NAME> -n pos-enterprise --replicas=3

# Verificare che le nuove repliche siano pronte
kubectl rollout status deployment/<DEPLOY_NAME> -n pos-enterprise

Configurare HPA (Horizontal Pod Autoscaler)

kubectl apply -f - <<EOF
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: <DEPLOY_NAME>-hpa
namespace: pos-enterprise
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: <DEPLOY_NAME>
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 2
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
EOF

Aumentare i limiti CPU

kubectl patch deployment <DEPLOY_NAME> -n pos-enterprise --type='json' -p='[
{"op": "replace", "path": "/spec/template/spec/containers/0/resources/limits/cpu", "value": "1000m"},
{"op": "replace", "path": "/spec/template/spec/containers/0/resources/requests/cpu", "value": "250m"}
]'

Ridurre la concorrenza Moleculer

Se il carico CPU e dovuto a troppe richieste concorrenti:

# Ridurre il bulkhead concurrency
kubectl set env deployment/<DEPLOY_NAME> -n pos-enterprise \
MOL_BULKHEAD_CONCURRENCY=5 \
MOL_BULKHEAD_MAXQUEUESIZE=50

Ottimizzazione lato codice

Per servizi specifici che mostrano hotspot:

  1. Serializzazione JSON pesante: abilitare la compressione o il pagination per risposte grandi.
  2. Query MongoDB non indicizzate: verificare con explain() le query piu frequenti.
  3. Calcoli sincroni bloccanti: spostare in worker thread con worker_threads.
  4. Cache miss elevati: verificare che il cacher Redis sia configurato e le chiavi siano corrette.
# Verificare gli indici MongoDB per una collection
kubectl run mongo-check --rm -it --image=mongo:7 -n pos-enterprise -- \
mongosh "mongodb+srv://admin:xxx@cluster0.xxx.mongodb.net/t_demo" \
--eval "db.orders.getIndexes()"

Prevenzione

  • HPA su tutti i deployment stateless: configurare autoscaling basato su CPU per tutti i nodi Moleculer.
  • Load testing pre-deploy: validare il consumo CPU con carico simulato prima di ogni release.
  • Profiling in CI: eseguire benchmark automatici per individuare regressioni di performance.
  • Limiti CPU realistici: basare i limiti su dati storici, non su stime.
  • Circuit breaker tuning: configurare circuitBreaker.threshold appropriato per evitare cascate.
// moleculer.config.js - esempio di tuning
bulkhead: {
enabled: true,
concurrency: 10,
maxQueueSize: 100,
},
circuitBreaker: {
enabled: true,
threshold: 0.5,
windowTime: 60,
minRequestCount: 20,
halfOpenTime: 10000,
}

Escalation

LivelloCondizioneContatto
L1 - OpsSingolo pod > 80%, HPA funzionaMonitorare
L1 - OpsHPA al max replicas, CPU ancora altaValutare aumento limiti
L2 - DevCPU alta persistente, possibile bugTeam Dev - profiling
L3 - InfraCluster sotto-dimensionatoDevOps Lead - aggiungere nodi

Tempo massimo di risposta: 30 minuti. Se accompagnato da latenza > 5s, trattare come Critical.

Questa pagina ti è stata utile?