Trabajo con Apache Kafka en Node.js: biblioteca KafkaJS

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Trabajo con Apache Kafka en Node.js usando la biblioteca KafkaJS

\n\n

Apache Kafka es una plataforma distribuida para transmisión de eventos en flujo, que se ha convertido en el estándar de facto para construir sistemas de mensajería de alta carga. En el ecosistema de Node.js, una de las bibliotecas más populares y estables para interactuar con Kafka es KafkaJS. Es un cliente moderno, completamente asíncrono, escrito en JavaScript puro, que soporta todas las capacidades clave de Kafka: productores, consumidores, grupos de consumidores, gestión de offsets y transacciones.

\n\n

En este artículo, analizaremos en detalle cómo instalar KafkaJS, configurar la conexión a un clúster de Kafka, enviar y leer mensajes, y también veremos las mejores prácticas para trabajar con esta biblioteca en un entorno de producción.

\n\n

Instalación y configuración de KafkaJS

\n\n

La instalación de la biblioteca se realiza con el gestor de paquetes estándar npm:

\n\n
npm install kafkajs
\n\n

Después de la instalación, es necesario crear un cliente especificando las direcciones de los brokers y un identificador de cliente. Ejemplo de configuración mínima:

\n\n
const { Kafka } = require('kafkajs');\n\nconst kafka = new Kafka({\n  clientId: 'my-app',\n  brokers: ['localhost:9092']\n});
\n\n

Para entornos de producción, se recomienda especificar varios brokers separados por comas para garantizar la tolerancia a fallos, así como configurar SSL y autenticación SASL:

\n\n
const kafka = new Kafka({\n  clientId: 'my-production-app',\n  brokers: ['broker1:9092', 'broker2:9092', 'broker3:9092'],\n  ssl: true,\n  sasl: {\n    mechanism: 'scram-sha-256',\n    username: 'myuser',\n    password: 'mypassword'\n  }\n});
\n\n

Productor: envío de mensajes a un tópico

\n\n

El productor se encarga de publicar mensajes en un tópico de Kafka especificado. KafkaJS ofrece dos modos de funcionamiento del productor: simple (send) y transaccional (para entrega exacta). Veamos un ejemplo básico de envío de un mensaje:

\n\n
const producer = kafka.producer();\n\nasync function sendMessage() {\n  await producer.connect();\n\n  await producer.send({\n    topic: 'test-topic',\n    messages: [\n      { key: 'user1', value: '¡Hola Kafka desde Node.js!' },\n      { key: 'user2', value: JSON.stringify({ orderId: 123, amount: 2500 }) }\n    ]\n  });\n\n  await producer.disconnect();\n}\n\nsendMessage().catch(console.error);
\n\n

Puntos clave:

\n
    \n
  • topic — nombre del tópico al que se envía el mensaje.
  • \n
  • messages — arreglo de objetos, cada uno puede contener key (opcional) y value (cadena o Buffer).
  • \n
  • Se recomienda llamar a producer.connect() una sola vez al iniciar la aplicación y reutilizar la conexión.
  • \n
\n\n

Para mejorar el rendimiento en producción, use un pool de conexiones y la configuración de acks:

\n\n
const producer = kafka.producer({\n  allowAutoTopicCreation: false,\n  transactionTimeout: 30000\n});\n\nawait producer.send({\n  topic: 'orders',\n  messages: [{ value: 'Nuevo pedido' }],\n  acks: -1  // Esperar confirmación de todas las réplicas\n});
\n\n

Consumidor: lectura de mensajes de un tópico

\n\n

El consumidor permite leer mensajes de uno o varios tópicos. El concepto más importante son los grupos de consumidores (consumer groups), que proporcionan balanceo de carga y garantizan que cada mensaje sea procesado solo por un consumidor del grupo.

\n\n
const consumer = kafka.consumer({ groupId: 'my-group' });\n\nasync function consumeMessages() {\n  await consumer.connect();\n  await consumer.subscribe({ topic: 'test-topic', fromBeginning: true });\n\n  await consumer.run({\n    eachMessage: async ({ topic, partition, message }) => {\n      console.log({\n        partition,\n        offset: message.offset,\n        key: message.key.toString(),\n        value: message.valu                    

Recommendations