Estoy en el proceso de diseñar una aplicación comercial que utilizará una API de Mercados para realizar pedidos en el Mercado. Esta no es una aplicación de algoritmo de alto rendimiento algorítmica de transacción del tipo encontrado en los bancos de inversión. Esto es sólo una pequeña aplicación personal que se comercializará quizás dos o tres veces al día dependiendo de las condiciones del mercado / tendencias La aplicación consistirá (aproximadamente) de los siguientes módulos / paquetes: Estrategias - Los algoritmos reales de comercio Analytics - Las clases para analizar el Precios en vivo órdenes de amplificación en el mercado para producir señales de compra / venta Servicios - Las clases utilizadas para mantener una conexión con el mercado, recuperar información de mercado y realizar pedidos de compra / venta. Hasta ahora, todo lo necesario para la aplicación parece estar disponible en Internet: Apache CXF para generar las clases Java utilizadas para acceder a los servicios web de los mercados. Apache Maths para la realización de la analítica de precios Wikipedia para los patrones de diseño diferentes, es decir, Fábrica, Asunto / Observador, Estado, etc Donde estoy realmente atascado sin embargo es con los algoritmos. He decidido utilizar el patrón de Estado para dividir, en agrupaciones lógicas, las diversas piezas de lógica que deben realizarse cuando se cumplen ciertas condiciones de mercado. El problema es que estoy empezando a ver que es muy probable que cada clase de estado contendrá una explosión de si las declaraciones else: No puedo ayudar pero siento Im falta algo aquí y que debe existir algún marco o patrón de diseño No sé acerca de qué Permite al desarrollador encapsular todas las entradas y salidas de un contexto empresarial dado en un número finito de acciones / entradas de negocio en las que se pueden construir reglas de negocio. Es decir. En lugar de tener que codificar los algoritmos Im con la esperanza de que debería ser posible hacer la aplicación en un procesador de reglas de algún tipo. Lamentablemente no sé por dónde empezar en esto. Espero haber explicado mi dilema con claridad, si quieres que aclare algo, por favor avísame. Gracias, preguntado Oct 8 09 at 22: 48Messaging Patterns 187 Patterns de integración en la práctica 187 Estudio de caso: Bond Trading System (por Jonathan Simon) Es fácil distanciarse de una gran colección de patrones o un lenguaje de patrones. Los patrones son la abstracción de una idea en una forma reutilizable. A menudo, la naturaleza muy genérica de los patrones que los hace tan útiles también los hace difíciles de entender. A veces lo mejor para ayudar a entender los patrones es un ejemplo del mundo real. No es un escenario artificial de lo que podría suceder sino lo que realmente sucede y lo que sucederá. Este capítulo aplica patrones para resolver problemas usando un proceso de descubrimiento. El sistema que vamos a discutir es un sistema de comercio de bonos con el que he trabajado durante dos años, desde el diseño inicial hasta la producción. Exploraremos los escenarios y problemas que se han encontrado y cómo resolverlos con patrones. Esto implica el proceso de decisión de elegir un patrón, así como la forma de combinar y ajustar los patrones para adaptarse a las necesidades del sistema. Y todo esto se hace teniendo en cuenta las fuerzas encontradas en los sistemas reales, incluyendo los requisitos de negocio, las decisiones de los clientes, los requisitos arquitectónicos y técnicos, así como la integración del sistema heredado. La intención de este enfoque es proporcionar una comprensión más clara de los patrones propios a través de la aplicación práctica. Construcción de un sistema Un importante banco de inversión de Wall Street se propone construir un sistema de precios de bonos en un esfuerzo por agilizar el flujo de trabajo de su mesa de negociación de bonos. En la actualidad, los comerciantes de bonos tienen que enviar los precios de un gran número de bonos a diferentes lugares de negociación, cada uno con su propia interfaz de usuario. El objetivo del sistema es minimizar las minucias de fijar precios de todos sus bonos combinados con una funcionalidad analítica avanzada específica para el mercado de bonos en una única interfaz de usuario encapsulada. Esto significa integración y comunicación con varios componentes a través de varios protocolos de comunicación. El flujo de alto nivel del sistema se ve así: En primer lugar, los datos de mercado entran en el sistema. Datos de mercado son datos sobre el precio y otras propiedades del bono que representa lo que la gente está dispuesta a comprar y vender el bono en el mercado libre. Los datos de mercado se envían inmediatamente al motor de análisis que altera los datos. El análisis se refiere a funciones matemáticas para aplicaciones financieras que alteran los precios y otros atributos de los bonos. Estas son funciones genéricas que utilizan variables de entrada para adaptar los resultados de la función a un enlace particular. La aplicación cliente que se ejecutará en cada escritorio de operador configurará el motor de análisis en una base por comerciante, controlando los detalles de la analítica de cada bono que el comerciante está fijando el precio. Una vez que los datos analíticos se aplican a los datos de mercado, los datos modificados se envían a diversos lugares de negociación donde los comerciantes de otras empresas pueden comprar o vender los bonos. Arquitectura con patrones Con esta visión general del flujo de trabajo del sistema, podemos abordar algunos de los problemas arquitectónicos que encontramos durante el proceso de diseño. Echemos un vistazo a lo que sabemos hasta la fecha. Los operadores necesitan una aplicación muy sensible en las estaciones de trabajo de Windows NT y Solaris. Por lo tanto, decidimos implementar la aplicación cliente como un cliente grueso de Java debido a su independencia de plataforma y su capacidad para responder rápidamente a los datos de entrada y de datos del usuario. En el lado del servidor, estamos heredando componentes legados C que nuestro sistema utilizará. Los componentes de datos de mercado se comunican con la infraestructura de mensajería de TIBCO Information Bus (TIB). Estamos heredando los siguientes componentes: Market Data Price Feed Server. Publica los datos de mercado entrantes al TIB. Motor de Analytics. Realiza análisis en los datos de mercado entrantes y transmite los datos de mercado modificados al TIB. Servidor de Contribuciones. Realiza toda la comunicación con los centros de negociación. Los centros de negociación son componentes de terceros no controlados por el banco. Subsistema de datos legacy del mercado Subsistema de contribución heredada Tenemos que decidir cómo se van a comunicar los subsistemas separados (cliente grueso de Java, datos de mercado y contribución). Podríamos tener el cliente grueso comunicarse directamente con los servidores heredados, pero eso requeriría demasiada lógica de negocio en el cliente. En su lugar, construya bien un par de pasarelas Java para comunicarse con los servidores legados. La puerta de enlace de precios para los datos de mercado es una puerta de enlace de contribución para enviar los precios a los lugares de negociación. Esto logrará una buena encapsulación de la lógica de negocio relacionada con estas áreas. A continuación se muestran los componentes actuales del sistema. Las conexiones marcadas como. Indican que aún no estamos seguros de cómo se comunicarán algunos de los componentes. El sistema y sus componentes La primera pregunta de comunicación es cómo integrar el cliente grueso de Java y los dos componentes del servidor Java para intercambiar datos. Veamos los cuatro estilos de integración sugeridos en este libro: Transferencia de archivos. Base de datos compartida. Invocación de procedimiento remoto. Y Mensajería. Podemos descartar la base de datos compartida inmediatamente porque queríamos crear una capa de abstracción entre el cliente y la base de datos y no queremos tener código de acceso a la base de datos en el cliente. La transferencia de archivos también puede descartarse, ya que se requiere una latencia mínima para asegurar que los precios actuales se envíen a los centros de negociación. Esto nos deja con una opción entre la invocación de procedimiento remoto o la mensajería. La plataforma Java proporciona soporte integrado para la invocación de procedimientos remotos y la mensajería. La integración de estilo RPC puede lograrse utilizando Remote Method Invocation (RMI), CORBA o Enterprise Java Beans (EJB). El servicio de mensajería Java (JMS) es la API común para la integración de estilo de mensajería. Así que ambos estilos de integración son fáciles de implementar en Java. Así que funcionará mejor para este proyecto, Invocación a procedimiento remoto o Mensajería. Theres sólo una instancia de la puerta de enlace de precios y una instancia de la puerta de enlace de contribución en el sistema, pero normalmente muchos clientes gruesos se conectan simultáneamente a estos servicios (uno para cada comerciante de bonos que pasa a estar conectado en un momento determinado). Además, el banco desearía que se tratara de un sistema de precios genérico que puede utilizarse en otras aplicaciones. Así que, además de un número desconocido de Think Clients, puede haber un número desconocido de otras aplicaciones que utilizan los datos de precios que salen de los Gateways. Un cliente grueso (u otra aplicación que utiliza los datos de fijación de precios) puede utilizar RPC con bastante facilidad para realizar llamadas a las pasarelas para obtener datos de precios e invocar el procesamiento. Sin embargo, los datos de precios se publicarán constantemente, y algunos clientes sólo están interesados en ciertos datos, por lo que obtener los datos pertinentes a los clientes adecuados de manera oportuna podría ser difícil. Los clientes podrían consultar las pasarelas, pero eso creará una gran cantidad de gastos generales. Sería mejor para los Gateways poner los datos a disposición de los clientes tan pronto como estén disponibles. Esto, sin embargo, requerirá que cada puerta de enlace mantenga un registro de los clientes que están actualmente activos, y que quieren qué datos particulares entonces, cuando una nueva pieza de datos esté disponible (lo cual sucederá varias veces por segundo), la puerta de enlace tendrá que hacer Un RPC a cada cliente interesado para pasar los datos al cliente. Idealmente, todos los clientes deben ser notificados simultáneamente, por lo que cada RPC debe hacerse en su propio hilo concurrente. Esto puede funcionar, pero se está poniendo muy complicado muy rápido. Mensajería simplifica enormemente este problema. Con Mensajería. Podemos definir canales separados para los diferentes tipos de datos de precios. Entonces, cuando una puerta de enlace recibe una nueva pieza de datos, agregará un mensaje que contenga esos datos al canal de publicación de publicación para ese tipo de datos. Mientras tanto, todos los clientes interesados en cierto tipo de datos escucharán en el canal para ese tipo. De esta manera, los Gateways pueden enviar fácilmente nuevos datos a quienquiera que esté interesado, sin necesidad de saber cuántas aplicaciones de escucha hay o cuáles son. Los clientes todavía necesitan ser capaces de invocar el comportamiento en los Gateways también. Puesto que hay solamente dos puertas de enlace, y el cliente puede bloquear probablemente mientras que el método se invoca síncrono, estas invocaciones del cliente-a-Gateway se pueden poner bastante fácilmente usando RPC. Sin embargo, dado que ya estamos utilizando la mensajería para la comunicación de puerta de enlace a cliente, los mensajes son probablemente una forma tan buena de implementar la comunicación de cliente a puerta de enlace también. Por lo tanto, toda la comunicación entre las puertas de enlace y los clientes se realizará a través de mensajes. Debido a que todos los componentes están escritos en Java, JMS presenta una opción fácil como sistema de mensajería. Esto está creando efectivamente un bus de mensajes o una arquitectura que hará posible que sistemas futuros se integren con el sistema actual con pocos o ningún cambio en la infraestructura de mensajería. De esta manera, la funcionalidad empresarial de la aplicación puede ser fácilmente utilizada por otra aplicación que el banco desarrolla. Componentes Java Comunicación con JMS JMS es simplemente una especificación y debemos decidir sobre un sistema de mensajería compatible con JMS. Decidimos usar IBM MQSeries JMS porque el banco es una tienda de IBM, utilizando servidores de aplicaciones WebSphere y muchos otros productos de IBM. Como resultado, utilizaremos MQSeries ya que ya contamos con una infraestructura de soporte y una licencia de sitio del producto. La siguiente pregunta es cómo conectar el sistema de mensajería MQSeries con el servidor C Contribution independiente y los servidores Market Data y Analytics Engine basados en TIBCO. Necesitamos un medio para que los usuarios de MQSeries tengan acceso a los mensajes TIB. Pero, ¿cómo? Podríamos utilizar el patrón de Message Translator para traducir mensajes TIB a mensajes MQSeries. Aunque el cliente C para MQSeries sirve como un traductor de mensajes. Usarlo sacrificaría la independencia del servidor JMS. Y aunque TIBCO tiene una API de Java, el arquitecto y el gerente del cliente lo han rechazado. Como resultado, el enfoque de Message Translator debe ser abandonado. El puente desde el servidor TIB al servidor MQSeries requiere comunicación entre C y Java. Podríamos usar CORBA, pero entonces ¿qué pasa con la mensajería Una mirada más cercana al patrón Message Translator muestra que está relacionada con el adaptador de canal en su uso de protocolos de comunicación. El corazón de un adaptador de canal es conectar sistemas que no son de mensajería a sistemas de mensajería. Un par de adaptadores de canal que conecta dos sistemas de mensajería es Messaging Bridge. El propósito de un puente de mensajería es transferir mensajes de un sistema de mensajería a otro. Esto es exactamente lo que estamos haciendo con la complejidad añadida de la comunicación intra-lenguaje Java a C. Podemos implementar el puente de mensajería de idioma cruzado utilizando una combinación de adaptador de canal y CORBA. Construiremos dos servidores ligeros del adaptador del canal, uno en C que maneja la comunicación con el TIB, y uno en Java que maneja la comunicación con JMS. Estos dos adaptador de canal. Que son Message Endpoint s ellos mismos, se comunicarán entre sí a través de CORBA. Al igual que nuestra elección para MQSeries, vamos a utilizar CORBA en lugar de JNI, ya que es un estándar de la empresa. El puente de mensajería implementa la traducción simulada de mensajes entre sistemas de mensajería aparentemente incompatibles y diferentes lenguajes. Traductor de mensajes utilizando adaptadores de canal El siguiente diagrama muestra el diseño actual del sistema, incluidos los gateways y otros componentes. Este es un buen ejemplo de aplicación de patrón. Combinamos dos adaptadores de canal con un protocolo sin mensajería para implementar el patrón de Message Translator, utilizando de manera efectiva un patrón para implementar otro patrón. Además, cambiamos el contexto del adaptador de canal para vincular dos sistemas de mensajería con un protocolo de traducción de lenguaje cruzado sin mensajería en lugar de conectar un sistema de mensajería a un sistema sin mensajería. El sistema actual con los adaptadores de canal Estructuración de canales Una clave para trabajar con patrones no es sólo saber cuándo usar qué patrón, sino también cómo utilizarlo con mayor eficacia. Cada implementación de patrones debe tener en cuenta aspectos específicos de la plataforma tecnológica, así como otros criterios de diseño. Esta sección aplica el mismo proceso de descubrimiento para encontrar el uso más eficiente del Canal de publicación en el contexto del servidor de datos de mercado que se comunica con el motor de análisis. Los datos de mercado en tiempo real se originan con el feed de datos del mercado, un servidor C que transmite datos de mercado en el TIB. El feed de datos del mercado utiliza un canal de publicación independiente para cada enlace para el que está publicando los precios. Esto puede parecer un poco extremo ya que cada nuevo bono necesita su propio canal nuevo. Pero esto no es tan grave ya que en realidad no es necesario crear canales en TIBCO. Por el contrario, los canales son referenciados por un conjunto jerárquico de nombres de temas llamados sujetos. El servidor TIBCO filtra un solo flujo de mensajes por asunto, enviando cada objeto único a un solo canal virtual. El resultado de lo cual es un canal de mensajes muy ligero. Podríamos crear un sistema que publique en unos pocos canales y los suscriptores podrían escuchar solo los precios que les interesan. Esto requeriría que los suscriptores usen un filtro de mensajes o un consumidor selectivo para filtrar todo el flujo de datos para precios de bonos interesantes, Debe ser procesado a medida que se recibe. Dado que los datos de mercado se publican en canales dedicados a los bonos, los suscriptores pueden registrarse para actualizaciones de una serie de bonos. Esto permite a los suscriptores filtrar mediante la suscripción selectiva a los canales y sólo recibir actualizaciones de interés en lugar de decidir después de recibir el mensaje. Es importante tener en cuenta que el uso de múltiples canales para evitar el filtrado es un uso no estándar de los canales de mensajería. En el contexto de la tecnología TIBCO sin embargo, estamos realmente decidiendo si implementar o poseer filtros o utilizar el filtrado de canales incorporado en TIBCO - en lugar de si usar tantos canales. El siguiente componente que debemos diseñar es el motor de análisis, otro servidor C / TIB que modificará los datos del mercado y lo retransmitirá al TIB. Aunque está fuera del alcance de nuestro desarrollo de Java / JMS, estamos trabajando estrechamente con el equipo de C para diseñarlo ya que somos el cliente principal de los motores de análisis. El problema en cuestión es encontrar la estructura de canal que retransmita de manera más eficiente los datos de mercado recién modificados. Dado que ya tenemos un Canal de mensajes dedicado por enlace heredado del feed de precios de datos de mercado, sería lógico modificar los datos de mercado y retransmitir los datos de mercado modificados en el Canal de mensajes dedicado a bonos. Pero esto no funcionará ya que los analíticos que modifican los precios de los bonos son específicos del comerciante. Si volvemos a retransmitir los datos modificados en el canal de mensajes de enlace. Vamos a destruir la integridad de los datos mediante la sustitución de los datos genéricos de mercado con datos específicos del comerciante. Por otro lado, podríamos tener un tipo de mensaje diferente para los datos de mercado específicos del comerciante que publicamos en el mismo canal, permitiendo a los suscriptores decidir qué mensaje están interesados en evitar destruir la integridad de los datos. Pero entonces los clientes tendrán que implementar sus propios filtros para separar mensajes para otros comerciantes. Además, habrá un aumento sustancial en los mensajes recibidos por los suscriptores, lo que supone una carga innecesaria para ellos. Hay dos opciones: Un canal por operador: Cada operador tiene un canal designado para los datos de mercado modificados. De esta manera, los datos del mercado original permanece intacto y cada aplicación de comerciante puede escuchar a sus comerciantes específicos Canal de mensajes para las actualizaciones de precios modificados. Un canal por comerciante por bono: Crear un canal de mensaje por operador por enlace únicamente para los datos de mercado modificados de ese bono. Por ejemplo, los datos de mercado para el bono ABC se publicarían en el canal Bond ABC, mientras que los datos de mercado modificados para el comerciante A se publicarían en Message Channel Trader A, Bond ABC, datos de mercado modificados para el comerciante B en Trader B, Bond ABC y pronto. Un canal por comerciante Un canal por enlace por comerciante Existen ventajas y desventajas para cada enfoque. El enfoque por enlace, por ejemplo, utiliza mucho más el Canal de mensajes. En el peor de los casos, el número de Message Channel será el número de bonos total multiplicado por el número de comerciantes. Podemos poner límites superiores en el número de canales que se crearán, ya que sabemos que hay sólo alrededor de 20 comerciantes y que nunca el precio de más de un par cientos de bonos. Esto pone el límite superior por debajo de la gama de 10.000, que no es tan extravagante en comparación con el canal de casi 100.000 mensajes que el mercado de datos de precios de alimentación está utilizando. Además, como estamos utilizando el TIB y el Canal de mensajes son bastante baratos, el número de canales de mensajes no es un problema grave. Por otra parte, el gran número de canales de mensajes podría ser un problema desde una perspectiva de gestión. Cada vez que se agrega un bono se debe mantener un canal para cada operador. Esto podría ser grave en un sistema muy dinámico. Nuestro sistema, sin embargo, es esencialmente estático. También cuenta con una infraestructura para gestionar automáticamente los canales de mensajes. Esto combinado con la arquitectura heredada de un componente heredado que utiliza un enfoque similar minimiza el inconveniente. Esto no quiere decir que deberíamos hacer un número innecesariamente excesivo de Canal de Mensajes. Por el contrario, podemos implementar un enfoque arquitectónico que utiliza un gran número de canales de mensajes cuando existe una razón. Y hay una razón en este caso que se reduce a la ubicación de la lógica. Si implementamos el enfoque por comerciante, Analytics Engine necesita lógica para agrupar los canales de entrada y salida. Esto se debe a que los canales de entrada del motor de Analytics son por enlace y el canal de mensajes de salida sería por operador, requiriendo que el motor de Google Analytics enríe todos los datos analíticos de varios enlaces para un comerciante en particular a un canal de mensajes de salida específico del comerciante. Esto convierte eficazmente el motor de análisis en un enrutador basado en contenido para implementar la lógica de enrutamiento personalizada para nuestra aplicación. Siguiendo la estructura del Bus de mensajes, Analytics Engine es un servidor genérico que podría ser utilizado por varios otros sistemas en el. Así que no queremos que la nube con el sistema de funcionalidad específica. Por otro lado, el enfoque por enlace funciona ya que la idea de un comerciante que posee la producción analítica de los precios de los bonos es una práctica aceptada por la compañía. El enfoque por enlace mantiene la separación del canal de mensajes del feed de datos de mercado intacta, al tiempo que añade varios más canales de mensajes. Antes de llegar al cliente, queremos que un enrutador basado en contenido combine estos varios canales en un número manejable de canales. No queremos que la aplicación cliente que se ejecuta en el escritorio de los operadores esté escuchando miles o decenas de miles de canales de mensajes. Ahora la pregunta es dónde colocar el enrutador basado en contenido. Podríamos simplemente tener el Adaptador de Canales C / TIB reenviando todos los mensajes a la Puerta de Precios en un único Canal de Mensajes. Esto es malo por dos razones por las que estaríamos dividiendo la lógica de negocios entre C y Java, y perderíamos el beneficio del canal de mensajes separado en el lado TIB, lo que nos permitiría evitar el filtrado más adelante en el flujo de datos. Mirando nuestros componentes de Java, podríamos situarlo en el Gateway de precios o crear un componente intermediario entre el Gateway de precios y el cliente. En teoría, si persistiera la separación basada en enlaces de Message Channel s hasta el cliente, el Pricing Gateway retransmitiría la información de precios con la misma estructura de canales que la puerta de enlace de precios y el motor de Analytics. Esto significa una duplicación de todos los canales dedicados TIB dedicados en JMS. Incluso si creamos un componente intermediario entre el Gateway de precios y el cliente, el Gateway de precios todavía tendrá que duplicar todos los canales en JMS. Por otro lado, la implementación de la lógica directamente en la puerta de enlace de precios nos permite evitar la duplicación del gran número de canales en JMS permitiéndonos crear un número mucho menor de canales en el orden de uno por comerciante. La puerta de enlace de precios se registra a través del adaptador de canal C / TIB como consumidor para cada enlace de cada comerciante del sistema. A continuación, la puerta de enlace de precios enviará cada cliente específico sólo los mensajes relacionados con ese operador en particular. De esta manera, sólo usamos un pequeño número de canales de mensajes en el extremo de JMS, al tiempo que maximizamos el beneficio de la separación en el extremo de TIB. El flujo de datos de mercado completo para el cliente El debate de diseño de canal de mensajes es un buen ejemplo de cómo es importante integrar patrones. El objetivo aquí era averiguar cómo utilizar eficazmente el Canal de mensajes. Decir que usas un patrón no es suficiente. Necesita averiguar cómo implementarlo mejor e incorporarlo a su sistema para resolver los problemas que tiene a la mano. Además, este ejemplo muestra las fuerzas empresariales en acción. Si pudiéramos implementar la lógica de negocios en cualquiera de nuestros componentes, podríamos haber seguido el enfoque por comerciante e implementado un enfoque general más simple con muchos menos canales. Selección de un canal de mensajes Ahora que conocemos la mecánica de la comunicación entre los componentes de Java / JMS y los componentes de C / TIBCO, y hemos visto alguna estructuración de Message Channel, debemos decidir qué tipo de canal de mensajes de JMS deben ser los componentes de Java Utilizar para comunicarse. Antes de poder elegir entre los diferentes canales de mensajes disponibles en JMS, veamos el flujo de mensajes de alto nivel del sistema. Tenemos dos pasarelas (precio y contribución) que se comunican con el cliente. Los flujos de datos de mercado al cliente desde el Gateway de precios que lo envían al gateway de contribución. La aplicación cliente envía un mensaje a la puerta de enlace de precios para modificar los análisis que se aplican a cada enlace. El gateway de contribución también envía mensajes a la aplicación de cliente que transmite el estado de las actualizaciones de precios a los diferentes lugares de negociación. El flujo de mensajes del sistema La especificación JMS describe dos tipos de Canal de mensajes, Canal de punto a punto (cola JMS) y Canal de publicación de suscripción (tema JMS). Recuerde que el caso de usar publish-subscribe es permitir que todos los consumidores interesados reciban un mensaje mientras que el caso para usar punto a punto es asegurar que solo un consumidor elegible recibe un mensaje en particular. Muchos sistemas simplemente difundirían mensajes a todas las aplicaciones cliente, dejando a cada aplicación cliente individual decidir por si mismo si procesar o no un mensaje en particular. Esto no funcionará para nuestra aplicación, ya que hay un gran número de mensajes de datos de mercado que se envían a cada aplicación cliente. Si transmitimos actualizaciones de datos de mercado a comerciantes desinteresados, estaremos desperdiciando innecesariamente los ciclos de procesamiento de clientes, decidiendo si procesar o no una actualización de datos de mercado. Canal punto a punto inicialmente suena como una buena opción ya que los clientes están enviando mensajes a servidores únicos y viceversa. Pero era un requisito del negocio que los comerciantes pudieron haber entrado a las máquinas múltiples al mismo tiempo. Si tenemos un operador conectado a dos estaciones de trabajo simultáneamente y se envía una actualización de precio punto a punto, sólo una de las dos aplicaciones cliente recibirá el mensaje. Esto se debe a que sólo un consumidor en un canal punto a punto puede recibir un mensaje en particular. Tenga en cuenta que sólo el primero de cada grupo de las aplicaciones cliente de un comerciante recibe el mensaje. Mensajería punto a punto para actualizaciones de precios Podríamos resolver esto utilizando el patrón de lista de destinatarios, que publica los mensajes en una lista de destinatarios previstos, garantizando que sólo los clientes de la lista de destinatarios recibirán mensajes. Utilizando este patrón, el sistema podría crear listas de destinatarios con todas las instancias de aplicación de cliente relacionadas con cada operador. Enviar un mensaje relacionado con un comerciante en particular, a su vez, enviar el mensaje a cada aplicación en la lista de destinatarios. Esto garantiza que todas las instancias de aplicación de cliente relacionadas con un operador en particular reciban el mensaje. La desventaja de este enfoque es que requiere un poco de lógica de implementación para administrar los destinatarios y enviar mensajes. Lista de destinatarios para actualizaciones de precios A pesar de que punto a punto podría ser hecho para trabajar, vamos a ver si hay una mejor manera. Usando el canal Publish-Subscribe, el sistema podría difundir mensajes en canales específicos de comerciantes en lugar de canales específicos de aplicación de cliente. De esta manera, todas las aplicaciones cliente que procesan mensajes para un solo operador recibirían y procesarían el mensaje. Publicar-Suscribir mensajería para actualizaciones de precios La desventaja de utilizar Publish-Subscribe Channel s es que el procesamiento de mensajes único no está garantizado con los componentes del servidor. Sería posible que se instancien múltiples instancias de un componente de servidor y cada proceso de instancia el mismo mensaje, posiblemente enviando precios no válidos. Al recordar el flujo de mensajes del sistema, sólo una dirección de comunicación es satisfactoria con cada canal de mensaje. La comunicación de servidor a cliente con publicar-suscribirse es satisfactoria mientras que la comunicación de cliente a servidor no es y la comunicación de cliente-servidor con punto a punto es satisfactoria mientras que el servidor-cliente no lo es. Puesto que no hay necesidad de usar el mismo Canal de Mensaje en ambas direcciones, podemos usar cada Canal de Mensaje sólo en una dirección. La comunicación de cliente a servidor se implementará con la comunicación punto a punto mientras se implementará la comunicación de servidor a cliente con publish-subscribe. Mediante esta combinación de Message Channel s, el sistema se beneficia de la comunicación directa con los componentes del servidor utilizando la mensajería punto a punto y la naturaleza de multidifusión de publish-subscribe sin ninguno de los inconvenientes. Flujo de mensajes con tipos de canales Solución de problemas con patrones Los patrones son herramientas y las colecciones de patrones son cajas de herramientas. Ayudan a resolver problemas. Algunos piensan que los patrones sólo son útiles durante el diseño. Siguiendo la analogía de la caja de herramientas, esto es como decir que las herramientas sólo son útiles cuando se construye una casa, no cuando se arregla. El hecho es que los patrones son una herramienta útil a lo largo de un proyecto cuando se aplica bien. En las siguientes secciones usaremos el mismo proceso de exploración de patrones que usamos en la sección anterior para resolver problemas en nuestro sistema ahora en funcionamiento. Actualizaciones de datos de mercado que parpadean Los operadores quieren que las celdas de las mesas parpadeen cuando se reciben nuevos datos de mercado para un bono, indicando claramente los cambios. El cliente Java recibe mensajes con nuevos datos que activan una actualización de la caché de datos del cliente y, finalmente, parpadean en la tabla. El problema es que las actualizaciones vienen con bastante frecuencia. La pila de subprocesos de GUI se está sobrecargando y, finalmente, congelar el cliente ya que no puede responder a la interacción del usuario. Asumiremos que el parpadeo se optimiza y se concentra en el flujo de datos de los mensajes a través del proceso de actualización. Un examen de los datos de rendimiento muestra que la aplicación cliente está recibiendo varias actualizaciones de un segundo algunas actualizaciones se produjeron menos de un milisegundo aparte. Dos patrones que parecen que podrían ayudar a ralentizar el flujo de mensajes son agregador y filtro de mensajes. Un primer pensamiento es implementar un filtro de mensajes para controlar la velocidad del flujo de mensajes arrojando actualizaciones recibidas una pequeña cantidad de tiempo después del mensaje de referencia. Como un ejemplo, digamos que vamos a ignorar los mensajes dentro de 5 milisegundos de uno al otro. El filtro de mensajes podría almacenar en caché el tiempo del último mensaje aceptable y tirar cualquier cosa recibida dentro de los próximos 5 milisegundos. Mientras que otras aplicaciones pueden no ser capaces de soportar la pérdida de datos hasta tal punto, esto es perfectamente aceptable en nuestro sistema debido a la frecuencia de actualizaciones de precios. Filtro de mensajes basado en tiempo El problema con este enfoque es que no todos los campos de datos se actualizan al mismo tiempo. Cada enlace tiene aproximadamente 50 campos de datos mostrados al usuario incluyendo el precio. Nos damos cuenta de que no todos los campos se actualizan en cada mensaje. Si el sistema ignora los mensajes consecutivos, puede muy bien estar tirando datos importantes. El otro patrón de interés es el Agregador. El Aggregator se utiliza para administrar la reconciliación de múltiples mensajes relacionados en un solo mensaje, lo que potencialmente reduce el flujo de mensajes. El Agregador podría guardar una copia de los datos de enlace del primer mensaje agregado, y luego actualizar sólo los campos nuevos o modificados sucesivos. Finalmente, los datos de enlace agregado se pasarán en un mensaje al cliente. Por ahora, supongamos que el Aggregator enviará un mensaje cada 5 milisegundos como el Filtro de mensajes. Más tarde, explorar bien otra alternativa. Agregador con actualizaciones parciales sucesivas El Agregador. Como cualquier otro patrón, no es una bala de plata que tiene sus ventajas y desventajas que necesitan ser exploradas. Un inconveniente potencial es que la implementación de un Aggregator reduciría el tráfico de mensajes en gran cantidad en nuestro caso sólo si muchos mensajes llegan dentro de un tiempo relativamente corto con respecto al mismo enlace. On the other hand, we would accomplish nothing if the Java client only receives updates for one field across all of the traders bonds. For example, if we receive 1000 messages in a specified timeframe with 4 bonds of interest, we would reduce the message flow from 1000 to 4 messages over that timeframe. Alternatively, if we receive 1000 messages in the same timeframe with 750 bonds of interest, we will have reduced the message flow from 1000 to 750 messages relatively little gain for the amount of effort. A quick analysis of the message updates proves that the Java client receives many messages updating fields of the same bond, and therefore related messages. So, Aggregator is in fact a good decision. Whats left is to determine how the Aggregator will know when to send a message it has been aggregating. The pattern describes a few algorithms for the Aggregator to know when to send the message. These include algorithms to cause the aggregator to send out its contents after a certain amount of time has elapsed, after all required fields in a data set have been completed, and others. The problem with all of these approaches is that the aggregator is controlling the message flow, not the client. And the client is the major bottleneck in this case, not the message flow. This is because the Aggregator is assuming the consumers of its purged messages (the client application in this case) are Event-Driven Consumer s, or consumers that rely on events from an external source. We need to turn the client into a Polling Consumer . or a consumer that continuously checks for messages, so the client application can control the message flow. We can do this by creating a background thread that continuously cycles through the set of bonds and updates and flashes any changes that have occurred since the last iteration. This way, the client controls when messages are received and as a result, guarantees that it will never become overloaded with messages during high update periods. We can easily implement this by sending a Command Message to the Aggregator initiating an update. The Aggregator will respond with a Document Message containing the set of updated fields that the client will process. The choice of Aggregator over Message Filter is clearly a decision based solely on the business requirements of our system. Each could help us solve our performance problems, but using the Message Filter would solve the problem at cost of the system data integrity. Major Production Crash With the performance of the flashing fixed, we are now in production. One day the entire system goes down. MQSeries crashes, bringing several components down with it. We struggle with the problem for a while and finally trace it back to the MQSeries dead letter queue (an implementation of the Dead Letter Channel ). The queue grows so large that it brings down the entire server. After exploring the messages in the dead letter queue we find they are all expired market data messages. This is caused by slow consumers, or consumers that do not process messages fast enough. While messages are waiting to be processed, they time out (see the Message Expiration pattern) and are sent to the Dead Letter Channel . The excessive number of expired market data messages in the dead letter queue is a clear indication that the message flow is too great messages expire before the target application can consume them. We need to fix the message flow and we turn to patterns for help slowing down the message flow. A reasonable first step is to explore solving this problem with the Aggregator as we recently used this pattern to solve the similar flashing market data control rate problem. The system design relies on the client application to immediately forward market data update messages to the trading venues. This means the system cannot wait to collect messages and aggregate them. So the Aggregator must be abandoned. There are two other patterns that deal with the problem of consuming messages concurrently: Competing Consumers and Message Dispatcher . Starting with Competing Consumers . the benefit of this pattern is the parallel processing of incoming messages. This is accomplished using several consumers on the same channel. Only one consumer processes each incoming message leaving the others to process successive messages. Competing Consumers . however, will not work for us since we are using Publish-Subscribe Channel s in server-to-client communication. Competing Consumers on a Publish-Subscribe Channel channel means that all consumers process the same incoming message. This results in more work without any gain and completely misses the goal of the pattern. This approach also has to be abandoned. On the other hand, the Message Dispatcher describes an approach whereby you add several consumers to a pool. Each consumer can run its own execution thread. One main Message Consumer listens to the Channel and delegates the message on to an unoccupied Message Consumer in the pool and immediately returns to listening on the Message Channel . This achieves the parallel processing benefit of Competing Consumers . but works on Publish-Subscribe Channel s. The Message Dispatcher in context Implementing this in our system is simple. We create a single JMSListener called the Dispatcher, which contains a collection of other JMSListener s called Performers. When the onMessage method of the Dispatcher is called, it in turn picks a Performer out of the collection to actually process the message. The result of which is a Message Listener (the Dispatcher) that always returns immediately. This guarantees a steady flow of message processing regardless of the message flow rate. Additionally, this works equally well on a Publish-Subscribe Channel s as it does on a Point-to-Point Channel s. With this infrastructure, messages can be received by the client application at almost any rate. If the client application is still slow to process the message after receiving them, the client application can deal with the delayed processing and potentially outdated market data rather than the messages expiring in the JMS Message Channel . The crash discussed in this section and the fix using the Message Dispatcher is an excellent example of the limits of applying patterns. We encountered a performance problem based on a design flaw not allowing the client to process messages in parallel. This greatly improved the problem, but did not completely fix it. This is because the real problem was the client becoming a bottleneck. This couldnt be fixed with a thousand patterns. We later addressed this problem by refactoring the message flow architecture to route messages directly from the Pricing Gateway to the Contribution Gateway. So patterns can help design and maintain a system, but dont necessarily make up for poor upfront design. Summary Throughout this chapter, we have applied patterns to several different aspects of a bond trading system including solving initial upfront design problems and fixing a nearly job threatening production crash with patterns. We also saw these patterns as they already exist in third party product, legacy components, and our JMS and TIBCO messaging systems. Most importantly, these are real problems with the same types of architectural, technical and business problems we experience as we design and maintain our own systems. Hopefully reading about applying patterns to this system helps give you a better understanding of the patterns as well as how to apply them to your own systems. Want to track what happened since the book came out Follow My Ramblings . Want to read more in depth Check out My Articles . Want to see me live See where I am speaking next . Find the full description of this pattern in: Enterprise Integration Patterns Gregor Hohpe and Bobby Woolf ISBN 0321200683 650 pages Addison-Wesley Parts of this page are made available under the Creative Commons Attribution license. You can reuse the pattern icon, the pattern name, the problem and solution statements (in bold), and the sketch under this license. Other portions of the text, such as text chapters or the full pattern text, are protected by copyright. Messaging Patterns 187 Integration Patterns in Practice 187 Case Study: Bond Trading SystemAPPLICATION OF. NET DESIGN PATTERN IN GRAIN TRADING MANAGEMENT SYSTEM SUN Yi-gui, YANG Ai-mei(School of Information Science and Engineering, Henan University of Technology, Zhengzhou 450001,China) We designed the grain trading system using design patterns, such as multi-layer architecture pattern, singleton, simple factory pattern, strategy pattern and builder pattern, on the. NET 3.5 platforms. The grain trading system not only met the basic requirements for the grain trading business, but also had greatly improved scalability, easy maintenance, shortened development cycle of the similar software. Accordingly, the paper provided a new idea and method for improving the universality and reusability of the grain trading system. CAJViewer7.0 supports all the CNKI file formats AdobeReader only supports the PDF format.
No comments:
Post a Comment