Resumen
Empezamos a usar Azure Service Bus (ASB) como solución de mensajería empresarial hace tres años. La hemos usado para publicar y consumir datos entre muchas aplicaciones de la organización. Como el flujo de datos es complejo, y normalmente se necesitan los datos de una aplicación en muchas otras aplicaciones, el modelo publicador -> múltiples subscriptores resultó muy adecuado. El uso de ASB en la organización es de docenas de millones de mensajes por día, mientras que la plataforma IRIS tiene unos 2-3 millones de mensajes/día.
El problema con ASB
Cuando empezamos con la integración de ASB, encontramos que el protocolo AMQP no tiene la configuración predeterminada para la implementación de IRIS, por lo que estuvimos buscando una solución alternativa para poder comunicar con ASB.
La solución
Desarrollamos un servicio local en Windows (.NET y Swagger) que se encargaba de la comunicación con ASB. Se instaló en la misma máquina que IRIS. Enviamos los mensajes a ASB dirigidos a este servicio local en Windows (usando: localhost y haciendo una API REST) y el propio servicio hacía el resto. Esta solución funcionó bien durante años, pero era muy difícil monitorizar el tráfico, depurar los mensajes "perdidos" y medir el rendimiento general. El hecho de tener este servicio local en Windows como un agente intermedio no resultaba la mejor arquitectura.
Programa de Acceso Preferente a Python Embebido (EAP)
Me pidieron (o me presenté voluntario, no lo recuerdo bien) participar en el Programa de Acceso Preferente a Python Embebido. Fue muy interesante para mí, porque pude poder probar nuevas funcionalidades y dar feedback al equipo de desarrollo. También me gustó mucho participar de forma activa e influir en el desarrollo de este producto. En esa fase, empezamos a probar Python Embebido para el ERP y decidimos comprobar si podíamos utilizar Python Embebido para resolver problemas “reales”. Nos plantearnos entonces intentar resolver la conectividad directa de IRIS a ASB.
El POC (prueba de concepto)
Empezamos a programar la solución y vimos que usar la librería ASB de Microsoft para Python nos haría nuestra vida (y nuestro trabajo) mucho más fácil. El primer paso fue desarrollar una función que pueda conectar con un topic específico en ASB y recibir mensajes. Esto se hizo bastante rápido (1 día de desarrollo) y avanzamos a la fase publicar (enviar mensajes a ASB).
Nos llevó varios días desarrollar toda la cubierta para esas funciones enviar y recibir. Preparamos lo siguiente:
- Un “área de preparación” entrante y saliente adecuada, para controlar el flujo de mensajes entrantes/salientes.
- Un mecanismo central para almacenar el tráfico ASB entrante y saliente para poder tener estadísticas adecuadas y medidas del rendimiento.
- Una página de monitorización CSP para activar/desactivar servicios, mostrar estadísticas y dar alertas sobre cualquier incidencia.
La implementación
Configuración Preliminar
Antes de usar las librerías ASB de Microsoft para Python, hay que instalarlas en un directorio ..\python dedicado.
Nosotros elegimos usar ../mge/python/ pero se puede usar cualquier carpeta que se quiera (inicialmente era una carpeta vacía)
Los siguientes comandos hay que ejecutarlos bien con una sesión CMD con privilegios (Windows) o con un usuario con los privilegios suficientes (Linux):
..\bin\irispip install --target ..\mgr\python azure.servicebus
Recibir mensajes desde ASB (consumo)
Tenemos una ClassMethod con varios parámetros:
- The topiId - El ASB se divide en topics de los cuales se consumen los mensajes
- subscriptionName - Nombre de la subscripción Azure
- connectionString - Para poder conectar con el topic al que estás suscrito
Ten en cuenta que se está usando [ Language = python ]
para indicar que este ClassMethod está escrito en Python (!)
Para usar la librería ASB, primero necesitamos importar las librerías ServiceBusClient
y ServiceBusSubQueue
:
para poder interactuar con IRIS (por ejemplo, ejecutar código) también necesitamos:
En este punto, podemos usar las librerías ASB:
with client.get_subscription_receiver(topicName, subscriptionName, max_wait_time=1, sub_queue=subQueue) as receiver:
for msg in receiver:
En este punto, tenemos un objeto Python "msg" (stream) donde podemos pasarlo (como un stream, por supuesto) a IRIS y almacenarlo directamente en la base de datos:
Enviar mensajes a ASB (publicación)
Tenemos un ClassMethod con varios parámetros:
- topicName - El Topic en el que queremos publicar (aquí tenemos que pasar el nombre, no el id)
- connectionString - Para poder conectar con el topic al que se está suscrito
- JSONmessage - el mensaje que queremos enviar (publicar)
Ten en cuenta que se está usando [ Language = python ]
para indicar que este ClassMethod está escrito en Python (!)
Para usar la librería ASB, primero necesitamos importar las librerías ServiceBusClient
y ServiceBusMessage
:
Usar las librerías ASB es muy sencillo:
result=1
with ServiceBusClient.from_connection_string(connectionString) as client:
with client.get_queue_sender(topicName) as sender:
single_message = ServiceBusMessage(JSONmessage)
sender.send_messages(single_message)
except Exception as e:
print(e)
result=0
return result
Beneficios de usar la conectividad ASB directa
- Mucho más rápida que usar la antigua alternativa del servicio local en Windows
- Fácil de monitorizar, recoger estadísticas, resolver incidencias
- Retirar el agente intermedio (servicio local en Windows) reduce un potencial punto de fallo
- Posibilidad de gestionar mensajes perdidos para cualquier topic automáticamente y hacer que ASB re-envíe esos mensajes a los subscriptores del topic
Agradecimientos
Me gustaría dar las gracias a @David.Satorres6134 (Senior Developer para IRIS) por su enorme contribución en el diseño, programación y pruebas. Sin su ayuda este proyecto no hubiera sido posible.