Tool Open Source · Apache 2.0 ~15 min lectura

Gatling MQTT Demo Scala / Maven

Demo funcional de load testing para brokers MQTT usando Gatling con Scala DSL. Conecta a HiveMQ vía TLS, simula flujos de pub/sub con validación de mensajes mediante JMESPath y genera reportes HTML detallados. Listo para clonar y ejecutar.

Gatling 3.14.9Scala 2.13Maven 3.8+Java 11+MQTTTLSHiveMQJMESPathIoT Testing

rcampos09/gatling-mqtt-demo-scala-rc

Repositorio público · Apache 2.0 · Scala DSL · HiveMQ public broker

¿Por qué hacer load testing sobre MQTT?

MQTT (Message Queuing Telemetry Transport) es el protocolo ligero de mensajería más usado en IoT, telemetría industrial, vehículos conectados y sistemas de notificaciones en tiempo real. A diferencia de REST, MQTT opera sobre un modelo de publicación/suscripción donde los clientes se conectan a un broker que enruta mensajes por tópicos.

Testear un broker MQTT bajo carga es diferente a testear una API REST: los usuarios virtuales mantienen conexiones persistentes, se suscriben a tópicos, publican mensajes y esperan respuestas correlacionadas — todo de forma concurrente. Sin una herramienta específica, este patrón es difícil de simular con fidelidad. Gatling tiene una extensión oficial para MQTT que este proyecto demuestra de forma completa y ejecutable.

🔗

Conexiones persistentes

Cada VU mantiene una sesión TCP activa, no una request-response por ciclo

📨

Pub/Sub asíncrono

Suscripción + publicación + validación del mensaje recibido en el mismo flujo

🔒

TLS incluido

Conecta sobre puerto 8883 con TLS — el modo de producción real en IoT

Stack técnico

Componente Versión Rol en el proyecto
Scala 2.13.17 Lenguaje principal de la simulación — DSL nativo de Gatling
Gatling 3.14.9 Motor de load testing — genera reportes HTML con métricas de percentiles
Gatling MQTT 3.14.9 Extensión oficial de Gatling para el protocolo MQTT — connect, subscribe, publish, check
Maven 3.8+ (wrapper incluido) Build tool — incluye mvnw para Unix y mvnw.cmd para Windows
Java JDK 11+ Runtime de la JVM requerido por Scala y Gatling
HiveMQ Public Broker Broker MQTT gratuito en broker.hivemq.com:8883 — sin registro, TLS habilitado

Estructura del proyecto

gatling-mqtt-demo-scala-rc/

├── pom.xml — Configuración Maven: dependencias Gatling + plugin

├── mvnw — Maven Wrapper Unix/macOS

├── mvnw.cmd — Maven Wrapper Windows

└── src/test/

    ├── scala/io/gatling/mqtt/demo/

        └── MqttDemoSimulation.scala — Simulación principal ⬅

    └── resources/

        ├── gatling.conf — Configuración de Gatling

        └── logback-test.xml — Configuración de logging

Instalación y setup

Tres pasos. No requiere instalar Gatling manualmente — Maven lo descarga como dependencia.

1 — Clonar el repositorio

$ git clone https://github.com/rcampos09/gatling-mqtt-demo-scala-rc.git $ cd gatling-mqtt-demo-scala-rc

2 — Compilar (descarga dependencias automáticamente)

$ ./mvnw clean test-compile [INFO] Downloading: gatling-mqtt 3.14.9 ... [INFO] BUILD SUCCESS

3 — Verificar versiones

$ java -version && ./mvnw -version java version "17.0.x" ... | Apache Maven 3.9.x

En Windows usa mvnw.cmd en lugar de ./mvnw

La simulación explicada

El archivo principal MqttDemoSimulation.scala en menos de 30 líneas cubre el flujo completo de un cliente MQTT real.

MqttDemoSimulation.scala
Scala
package io.gatling.mqtt.demo

import java.util.UUID
import scala.concurrent.duration._
import io.gatling.core.Predef._
import io.gatling.mqtt.Predef._

class MqttDemoSimulation extends Simulation {

  // 1. Protocolo: broker HiveMQ público con TLS
  val baseMqttProtocol = mqtt
    .broker("broker.hivemq.com", 8883)
    .useTls(true)
    .correlateBy(jmesPath("id"))   // correlación por campo "id"

  // 2. Tópico único por ejecución (evita colisiones entre tests)
  val topic = s"gatling-mqtt-demo/${UUID.randomUUID()}"

  // 3. Escenario: cada VU hace connect → subscribe → publish → check
  val scn = scenario("Publisher")
    .exec(session => session.set("id", UUID.randomUUID()))
    .exec(mqtt("Connecting").connect)
    .exec(mqtt("Subscribing").subscribe(topic))
    .exec(
      mqtt("Publishing")
        .publish(topic)
        .message(StringBody("""{"id":"#{id}","message":"Hello from #{id}"}"""))
        .await(1.second)
        .check(jmesPath("message").is("Hello from #{id}"))
    )

  // 4. Inyección: 5 usuarios simultáneos
  setUp(
    scn.inject(atOnceUsers(5))
  ).protocols(baseMqttProtocol)
}

Las 4 fases del flujo por usuario virtual

01

Connect

Establece conexión TCP/TLS con el broker en broker.hivemq.com:8883. Cada VU tiene su propia sesión de red persistente durante el test.

02

Subscribe

Se suscribe a un tópico único generado con UUID al inicio del test. El UUID garantiza que múltiples ejecuciones no interfieren entre sí.

03

Publish

Publica un mensaje JSON con un ID único por VU. El campo "id" es el identificador que Gatling usará para correlacionar la respuesta recibida en el paso siguiente.

04

Check (await)

Espera hasta 1 segundo el mensaje de vuelta (el broker lo re-entrega porque el VU está suscrito al mismo tópico), y valida que el campo "message" del JSON contenga el ID correcto.

¿Qué es JMESPath y por qué importa aquí?

JMESPath es un lenguaje de consulta para JSON (similar a JSONPath). En este proyecto, .correlateBy(jmesPath("id")) le dice a Gatling que cada respuesta recibida en el tópico debe ser emparejada con la publicación que tiene el mismo valor en el campo "id". Sin correlación, en un test con múltiples VUs concurrentes, sería imposible saber qué respuesta pertenece a qué usuario virtual.

Ejecutar el test

Dos formas equivalentes. Se recomienda el Maven Wrapper para garantizar la versión correcta sin instalación adicional.

Con Maven Wrapper (recomendado)

$ ./mvnw gatling:test -Dgatling.simulationClass=io.gatling.mqtt.demo.MqttDemoSimulation

Con Maven instalado globalmente

$ mvn gatling:test -Dgatling.simulationClass=io.gatling.mqtt.demo.MqttDemoSimulation

⚠️ Entender el conteo de requests

Cada usuario virtual ejecuta 3 acciones MQTT: Connect + Subscribe + Publish. El total de requests en el reporte será siempre usuarios × 3.

5 VUs

= 15 requests

50 VUs

= 150 requests

100 VUs

= 300 requests

Personalizar la carga

Modifica el bloque setUp en la simulación para ajustar el perfil de carga a tu escenario.

Smoke test — verificación básica 5 VUs simultáneos
setUp(scn.inject(atOnceUsers(5))).protocols(baseMqttProtocol)
Load test — rampa gradual 100 VUs en 60 segundos
setUp(scn.inject(rampUsers(100).during(60.seconds))).protocols(baseMqttProtocol)
Stress test — carga sostenida constante 10 VUs/segundo durante 5 minutos
setUp(scn.inject(constantUsersPerSec(10).during(5.minutes))).protocols(baseMqttProtocol)

Reportes HTML

Al finalizar cada ejecución, Gatling genera un reporte HTML completo automáticamente en target/gatling/.

[INFO] Reports generated in 1s. [INFO] Please open the following file: target/gatling/mqttdemosimulation-20260308120000/index.html
⏱️

Response time metrics

Mínimo, máximo, promedio y percentiles p50, p75, p95, p99 por request

📈

Requests per second

Throughput real medido durante toda la ejecución del test

👥

Active users timeline

Curva de usuarios activos por segundo — muestra el perfil de inyección real

📊

Response distribution

Histograma de distribución de tiempos de respuesta por acción MQTT

Adaptar a tu propio broker

El proyecto usa HiveMQ público por defecto — ideal para demos y aprendizaje. Para usar tu propio broker, modifica el bloque de protocolo:

MqttDemoSimulation.scala — modificar broker
val baseMqttProtocol = mqtt
  .broker("tu-broker.example.com", 1883)   // puerto 1883 sin TLS
  .useTls(false)                            // o true + puerto 8883
  .credentials("user", "password")       // si requiere auth
  .correlateBy(jmesPath("id"))

🚀

Listo para clonar y ejecutar

Repositorio público, Apache 2.0. Si quieres proponer mejoras o agregar nuevos escenarios MQTT, abre un issue o pull request en GitHub.