CodeGym /Cursos /Módulo 5. Spring /Lección 114: Métricas de rendimiento y monitorización de ...

Lección 114: Métricas de rendimiento y monitorización de memoria

Módulo 5. Spring
Nivel 19 , Lección 3
Disponible

Las métricas son esos indicadores con los que valoras el estado de tu aplicación, su rendimiento y su salud. Si hacemos una analogía, las métricas son como los signos vitales de una persona: temperatura, presión, pulso. Por ejemplo, si tu servidor de repente empieza a "ahogarse", Actuator puede decirte cuál es el problema: demasiadas peticiones, falta de memoria o, tal vez, tu servidor decidió tomarse unas vacaciones.


Métricas de Actuator

Spring Boot Actuator trae muchas métricas por defecto. Aquí tienes algunas de las más interesantes:

Métrica Descripción
jvm.memory.used Uso de memoria de la JVM
http.server.requests Métricas de las peticiones HTTP: número de peticiones, tiempo medio de respuesta, etc.
cpu.usage Carga del procesador
logback.events Número de eventos de logging
jvm.threads.live Número de threads activos en la JVM
jvm.gc.pause Tiempo de las pausas del garbage collector

No está mal, ¿eh? Y eso es solo el conjunto básico. Si quieres más, por decirlo de forma coloquial, más "especias" en la sopa, puedes añadir tus propias métricas (sobre métricas custom hablaremos más adelante en el curso).

Las métricas están disponibles en el endpoint /actuator/metrics. Para ver todas las métricas, basta con entrar en ese endpoint desde el navegador o Postman, y obtendrás la lista completa de indicadores disponibles.

Por ejemplo:

{
  "names": [
    "jvm.memory.used",
    "http.server.requests",
    "logback.events",
    "jvm.threads.live",
    "system.cpu.usage"
  ]
}

Si quieres obtener datos concretos de una métrica en particular (por ejemplo, el uso de memoria de la JVM), usa el endpoint /actuator/metrics/{nombre_metrica}.

Ejemplo:

curl http://localhost:8080/actuator/metrics/jvm.memory.used

El resultado puede verse así:

{
  "name": "jvm.memory.used",
  "measurements": [
    {
      "statistic": "VALUE",
      "value": 12345678
    }
  ],
  "availableTags": [
    {
      "tag": "area",
      "values": ["heap", "nonheap"]
    }
  ]
}

Aquí value es el volumen actual de memoria usada, y tags como area indican si la memoria pertenece al heap o al non-heap (no intentes memorizar todos los términos ahora, luego lo veremos con calma).


Monitorización de rendimiento: las peticiones HTTP como papel tornasol

Una de las métricas clave para monitorizar el rendimiento es http.server.requests. Rastrea todas las peticiones HTTP que llegan a tu aplicación. Estos datos pueden ser una mina de oro para entender el comportamiento de los usuarios y detectar problemas.

¿Qué información puedes obtener de http.server.requests?

  • Número de peticiones. ¿Cuántas peticiones ha procesado tu aplicación en un periodo dado?
  • Tiempo medio de respuesta. ¿Qué tan rápido responde tu aplicación a las peticiones?
  • Errores. ¿Cuántas peticiones devolvieron status 4xx o 5xx?

Usa el mismo endpoint /actuator/metrics/http.server.requests para más detalles. Aquí tienes un ejemplo de respuesta:

{
  "name": "http.server.requests",
  "measurements": [
    {
      "statistic": "COUNT",
      "value": 438
    },
    {
      "statistic": "TOTAL_TIME",
      "value": 125.8
    },
    {
      "statistic": "MAX",
      "value": 2.5
    }
  ],
  "availableTags": [
    {
      "tag": "status",
      "values": ["200", "404", "500"]
    },
    {
      "tag": "uri",
      "values": ["/api/users", "/api/orders"]
    }
  ]
}

¿Cómo leer esta respuesta?

  • COUNT — el número total de peticiones (en este caso 438 peticiones).
  • TOTAL_TIME — el tiempo total empleado en procesar todas las peticiones (125,8 segundos).
  • MAX — el tiempo máximo empleado en procesar una sola petición (2,5 segundos).

Los tags permiten filtrar las peticiones, por ejemplo por status de respuesta (200, 404) o por URI (/api/users, /api/orders). Muy útil para análisis detallados.

Situación práctica

Si ves que el tiempo de respuesta para un URI concreto es demasiado alto, puede deberse a una consulta lenta a la base de datos o a carga en la CPU. Empieza a investigar desde ahí para solucionar el problema.


Memoria: monitorizamos la JVM para que no se nos "cueza"

La Java Virtual Machine (JVM) es como el motor de tu aplicación. Si algo va mal con ella, todo se viene abajo. Actuator ofrece métricas útiles para monitorizar la memoria:

  • jvm.memory.used — uso actual de memoria.
  • jvm.memory.max — cantidad máxima de memoria disponible.
  • jvm.gc.pause — tiempo de las pausas del garbage collector.

Entendiendo heap y non-heap

La memoria de la JVM se divide en dos tipos principales:

  • Heap memory (montón) — se usa para almacenar objetos creados con new.
  • Non-heap memory — se usa para almacenar metadata de clases, variables estáticas y otras cosas.

Ejemplo de análisis de la métrica jvm.memory.used:

{
  "name": "jvm.memory.used",
  "measurements": [
    {
      "statistic": "VALUE",
      "value": 98765432
    }
  ],
  "availableTags": [
    {
      "tag": "area",
      "values": ["heap", "nonheap"]
    }
  ]
}

Si la memoria del heap está ocupada al 90% (o más), puede ser señal de memory leaks o de que necesitas aumentar el parámetro -Xmx de la JVM.


Casos prácticos: cuando las métricas salvan el día

Caso 1: Alta carga de CPU

La métrica system.cpu.usage muestra la carga total de la CPU. Si está constantemente por encima del 80%, es una señal clara de sobrecarga del servidor. La causa puede ser código poco optimizado o una carga excesiva.

Caso 2: GC frecuente

La métrica jvm.gc.pause rastrea las pausas del garbage collector. Si las pausas son muy frecuentes o muy largas (decenas de milisegundos), puede ralentizar todo el sistema. Revisa si estás asignando demasiados objetos en periodos cortos de tiempo.


Ejercicio práctico

  1. Integración de Actuator en el proyecto. Si aún no lo has hecho, añade la dependencia spring-boot-starter-actuator en tu pom.xml o build.gradle.
  2. Configuración de métricas. Investiga los endpoints /actuator/metrics y /actuator/metrics/{nombre_metrica}. Intenta obtener datos de las métricas http.server.requests y jvm.memory.used.
  3. Análisis de datos. En base a los datos obtenidos, intenta sacar conclusiones sobre el estado de tu aplicación. Por ejemplo, ¿cuánto tiempo tarda en procesar las peticiones HTTP? ¿Cuál es el uso actual de memoria de la JVM?
// Comprobamos la carga actual de la CPU mediante Actuator
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Map> response = restTemplate.getForEntity("http://localhost:8080/actuator/metrics/system.cpu.usage", Map.class);
System.out.println("Carga de CPU: " + response.getBody());

Analiza, saca conclusiones, optimiza — y tu servidor te lo agradecerá.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION