Trabajo con hebras

Los nodos y los analizadores de proceso de mensajes deben funcionar en un entorno de múltiples instancias y múltiples hebras. Puede haber muchos objetos de nodo u objetos de analizador que tengan, cada uno de ellos, muchos elementos de sintaxis, y puede haber muchas hebras que ejecuten métodos en estos objetos. El diseño de intermediario de mensajes garantiza que un objeto de mensaje y los objetos que pertenecen al mismo los utilice únicamente la hebra que recibe y procesa el mensaje a través del flujo de mensajes.

Una instancia de un nodo de proceso de flujo de mensajes es compartida y utilizada por parte de todas las hebras que dan servicio al flujo de mensajes en el que está definido el nodo. En el caso de los analizadores, una instancia de un analizador es utilizada exclusivamente por una sola hebra de flujo de mensajes.

Una extensión definida por el usuario debe adherirse a este modelo, y debe evitar utilizar datos o recursos globales que requieran semáforos para serializar el acceso a través de las hebras. Dicha serialización puede ocasionar atascos del rendimiento.

Las funciones de implementación de una extensión definida por el usuario deben ser reentrantes, y las funciones que invoquen dichas funciones también deberán ser reentrantes. Todas las funciones de programa de utilidad de una extensión definida por el usuario son completamente reentrantes.

Aunque una extensión definida por el usuario pueda generar hebras adicionales si es necesario, es esencial que la misma hebra devuelva el control al intermediario al completarse una función de implementación. De lo contrario, se pondrá en peligro la integridad del intermediario y se producirán resultados imprevisibles.

Modelo de ejecución

Cuando un grupo de ejecución se inicializa, las lils apropiadas se hacen disponibles para ser ejecutadas. El proceso de ejecución del grupo de ejecución se inicia, y genera una hebra de configuración dedicada. En el entorno de ejecución de flujo de mensajes, el flujo de mensajes es seguro para hebras. Puede ejecutar simultáneamente flujos de mensajes en muchas hebras OS, sin necesidad de tener en cuenta cuestiones de serialización. Los nodos definidos por el usuario que se hayan implementado no deben poner en peligro este modelo de trabajo con hebras. Tenga en cuenta los puntos siguientes:
  • Un mensaje de entrada enviado a un flujo de mensajes lo procesa únicamente la hebra que lo recibe. La conmutación de hebras o de contexto no se lleva a cabo durante el proceso de mensajes.
  • Las estructuras de datos a las que acceden los flujos de mensajes son sólo visibles en una sola hebra, y estas estructuras de datos existen sólo durante el tiempo de vida del mensaje que se va a procesar.
  • Todas las hebras de una agrupación de hebras de un flujo de mensajes comparten una sola instancia de un flujo de mensajes. Este aspecto está relacionado con el comportamiento de un nodo de flujo de mensajes, en cuanto a que ninguno de los dos tiene estado.
  • Los requisitos de memoria de un grupo de ejecución no resultan afectados indebidamente por los flujos de mensajes en ejecución en más hebras OS.

Modelo de trabajo con hebras

El siguiente ejemplo de flujo de mensajes le ayudará a comprender algunas de las consideraciones de trabajo con hebras que debe tener en cuenta al diseñar e implementar sus nodos propios definidos por el usuario. En él se considera el ejemplo de un nodo de entrada definido por el usuario.

Un flujo de mensajes puede configurarse para ejecutarse en un conjunto de hebras. Esto se determina mediante el número de nodos de entrada del flujo de mensajes y el valor de la propiedad additionalInstances del flujo de mensajes. Estos dos elementos determinan la capacidad máxima de la agrupación de hebras que el flujo de mensajes puede utilizar. Por lo tanto, si el flujo de mensajes tiene requisitos de proceso específicos que impongan la utilización de una sola hebra, debe asegurarse de que esto se cumpla.

Para el proceso de nodos de entrada, un orden típico de sucesos tiene el aspecto siguiente:
  1. Se lleva a cabo la creación del nodo de entrada.
  2. Se reclama una hebra desde la agrupación de hebras.
  3. La hebra asignada se inicia en el método run del nodo.
  4. Se confirma la configuración (o reconfiguración).
  5. El proceso de inicialización se realiza en el contexto de la hebra.
  6. La hebra se conecta al gestor de colas del intermediario.
  7. Se crea un grupo de mensajes y un objeto de almacenamiento intermedio.
  8. Una petición de cola abierta para la cola de entrada se envía al gestor de colas. Esta cola se mantiene abierta durante el tiempo de vida de la hebra.
  9. El nodo de entrada entra en un bucle de proceso de mensajes.
  10. Al recibirse un mensaje, el almacenamiento intermedio de datos contiene la cabecera y el cuerpo del mensaje.
  11. Los objetos de mensaje se crean y adjuntan al grupo de hebras.
  12. El envío de hebras se activa si se especifican varias hebras.
  13. Los datos de mensaje se propagan en sentido descendente.
Debe tener en cuenta los puntos siguientes:
  • El nodo de entrada implementará el modelo de trabajo con hebras de flujo de mensajes elegido.
  • El nodo de entrada siempre tendrá, por lo menos, una hebra que lea desde el origen de entrada correspondiente, o que procese de forma activa un mensaje recibido en dicho origen. Si un flujo de mensajes tiene varios nodos de entrada, las instancias de hebra adicionales estarán disponibles para dar servicio a cualquiera de los nodos de entrada, tal como determina la política de envío de dicho nodo de entrada.
Las hebras se pueden reclamar o solicitar. Cuando el flujo de mensajes se difunde, el nodo de entrada reclama una hebra inicial. Aunque el flujo de mensajes está asociado con una agrupación de hebras, el nodo de entrada es el responsable de la política de envío. Esto significa que debe siempre asegurarse de que una instancia de sí mismo se ejecute en una hebra. Puesto que el valor por omisión de la propiedad additionalInstances es cero, las peticiones adicionales para obtener una hebra no recibirán respuesta si el usuario ha definido varios nodos de entrada. Esto significa que un flujo de mensajes puede consumir más hebras de las previstas. Además, esto puede querer decir que, si el usuario ha definido varios nodos de entrada, uno de estos nodos puede no recibir suficientes hebras.

El hecho de permitir al intermediario iniciar copias adicionales del flujo de mensajes en hebras independientes, utilizando la propiedad additionalInstances, es la manera más eficaz de impedir que la cola de entrada se atasque. No obstante, la creación de hebras independientes permite el proceso paralelo de los mensajes de la cola de mensajes; por lo tanto, sólo debe utilizar esta propiedad cuando el orden en que se procesan los mensajes no sea importante.

Las hebras se crean como resultado de la construcción y operación del nodo de entrada. Una hebra permanece activa o desocupada en la agrupación de hebras, y las hebras desocupadas permanecen en la agrupación hasta que un nodo de entrada las envía o hasta que el intermediario se cierra.

La figura siguiente ilustra la asignación de hebras en un flujo de mensajes.

Asignación de hebras en un flujo de mensajes


Consulte el texto adjunto para ver una explicación de los elementos del diagrama

Inicialmente, se reclama la hebra (Thread) 1 (A), la cual espera a recibir mensajes. Cuando llega un mensaje (B), Thread 1 propaga el mensaje y envía Thread 2. Thread 2 recibe un mensaje inmediatamente (C) y los propaga, y luego envía Thread 3, la cual espera a recibir un mensaje (D). Thread 1 se completa (E), y vuelve a la agrupación de hebras. A continuación, Thread 3 recibe un mensaje (F), envía Thread 1 y propaga el mensaje. Thread 1 espera ahora a que llegue un mensaje a la cola (G).

Vale la pena observar el punto marcado con la letra H. En esta instancia del flujo de mensajes, Thread 1 adquiere un mensaje, pero como todas las demás hebras están activas en ese momento, no puede realizar el envío. El mensaje se propaga.

Una vez propagado este mensaje, Thread 2 se completa (I), recibe un nuevo mensaje de la cola y propaga este nuevo mensaje. A continuación, Thread 3 se completa (J), y vuelve a la agrupación. Seguidamente, Thread 2 se completa también (K). Dado que Thread 1 no ha realizado el envío, al completarse (L) no puede regresar a la agrupación de hebras aun cuando no haya ningún mensaje en la cola, así que espera a que llegue un mensaje a la cola.

Tenga en cuenta los puntos siguientes acerca del comportamiento de hebras en WebSphere Business Integration Message Broker:
  • Las hebras sólo se crean si así lo requiere la carga de trabajo. Esto significa que un proceso de grupo de ejecución puede utilizar menos hebras de las que tiene configurado utilizar.
  • A menos que todas las hebras disponibles procesen de forma activa en un flujo de mensajes, siempre habrá una hebra que lea la cola de entrada.
  • Si la carga de trabajo aumenta en un momento dado, otros nodos de entrada del mismo flujo de mensajes podrán adquirir hebras que se hayan devuelto a la agrupación de hebras.
Si una hebra adquiere un mensaje, pero todas las demás hebras están activas en ese momento, dicha hebra no podrá realizar el envío. El mensaje se propaga. Cuando esta hebra se completa, al no haber realizado el envío no puede volver a la agrupación de hebras aun cuando no haya ningún mensaje en la cola.

Conceptos relacionados
Nodos de entrada definidos por el usuario

Tareas relacionadas
Creación de un nodo de entrada en C

Referencia relacionada
cniDispatchThread