2010-02-24 8 views
10

Mi aplicación realiza solicitudes de servicios web; hay una tasa máxima de solicitudes que el proveedor manejará, así que necesito reducirlas.¿Puedo acelerar las solicitudes realizadas por una aplicación distribuida?

Cuando la aplicación se ejecutó en un único servidor, solía hacerlo a nivel de aplicación: un objeto que realiza un seguimiento de cuántas solicitudes se han realizado hasta ahora y espera si la solicitud actual supera el máximo permitido carga.

Ahora, estamos migrando de un único servidor a un clúster, por lo que hay dos copias de la aplicación ejecutándose.

  • No puedo seguir buscando la carga máxima en el código de la aplicación, porque los dos nodos combinados pueden exceder la carga permitida.
  • No puedo simplemente reducir la carga en cada servidor, porque si el otro nodo está inactivo, el primer nodo puede enviar más solicitudes.

Este es un entorno JavaEE 5. ¿Cuál es la mejor manera de reducir las solicitudes que envía la aplicación?

+2

simplemente curioso, ¿estás usando un marco especial como Terracota? –

+0

@Pablo: No. Estamos migrando de un único servidor JBoss en un servidor dedicado a un WebLogic 10.3 alojado configurado con dos nodos. – Leonel

Respuesta

5

Dado que ya se encuentra en un entorno Java EE, puede crear un MDB que maneje todas las solicitudes al servicio web basado en una cola JMS. Las instancias de la aplicación pueden simplemente publicar sus solicitudes en la cola y el MDB las recibirá y llamará al servicio web.

La cola realmente se puede configurar con el número apropiado de sesiones que limitarán el acceso simultáneo a su servicio web, por lo que su aceleración se maneja a través de la configuración de la cola.

Los resultados se pueden devolver a través de otra cola (o incluso una cola por instancia de la aplicación).

+0

Sí, dado que ya estaba en un entorno JavaEE, la cola JavaEE era la solución más directa, y no tuve que agregar ninguna otra dependencia. – Leonel

1

Muchas formas de hacer esto: es posible que tenga un "Agente de coordinación" que es responsable de entregar "tokens" a los servidores. Cada "token" representa un permiso para realizar una tarea, etc. Cada aplicación necesita solicitar "tokens" para realizar llamadas.

Una vez que una aplicación agota sus tokens, debe solicitar más antes de volver a acceder al servicio web.

Por supuesto, todo esto se complica cuando hay requisitos con respecto a la sincronización de cada llamada que realiza cada aplicación debido a la concurrencia hacia el servicio web.

Puede confiar en RabbitMQ como estructura de mensajería: los enlaces de Java están disponibles.

+0

+1 porque no tenía conocimiento de RabbitMQ que también tiene enlaces .net. – tobsen

1

Los N nodos deben comunicarse. Hay varias estrategias:

  • difusión: cada nodo transmitirá a todos los demás que está macking una llamada, y todos los otros nodos tendrán eso en cuenta. Los nodos son iguales y mantienen un recuento global individual (cada nodo conoce las llamadas de cada nodo).
  • nodo maestro: un nodo es especial, es el maestro y todos los demás nodos solicitan permiso del maestro antes de realizar una llamada. El maestro es el único que conoce el recuento global.
  • maestro dedicado: igual que el maestro, pero el 'maestro' no hace llamadas en itslef, es solo un servicio que realiza un seguimiento de las llamadas.

Dependiendo de qué tan alto espere escalar más adelante, una u otra estrategia puede ser la mejor. Para 2 nodos, el más simple se transmite, pero a medida que aumenta el número de nodos, los problemas comienzan a aumentar (usted pasará más tiempo transmitiendo y respondiendo a los broadcats que haciendo solicitudes de WS).

Cómo se comunican los nodos, depende de usted. Puede abrir un canal TCP, puede broadcats UDP, puede hacer un WS completo para este propósito, puede usar un protocolo de intercambio de archivos. Hagas lo que hagas, ya no estás dentro de un proceso, por lo que se aplican todos los fallacies of distributed computing.

1

Este es un problema interesante, y la dificultad de la solución depende, en cierta medida, de lo estricto que sea el estrangulamiento.

Mi solución usual para esto es JBossCache, en parte porque viene empaquetada con JBoss AppServer, pero también porque maneja la tarea bastante bien. Puede usarlo como un tipo de hashmap distribuido, registrando las estadísticas de uso en varios grados de granularidad. Las actualizaciones se pueden realizar de forma asincrónica, por lo que no desacelera.

JBossCache se utiliza generalmente para el almacenamiento en caché distribuido de alta resistencia, pero me gusta también para estos trabajos más livianos. Es puro java, y no requiere de mugre con la JVM (a diferencia de Terracota).

2

Recomiendo usar beanstalkd para bombear periódicamente un conjunto de solicitudes (trabajos) en un tubo (cola), cada uno con un retraso apropiado. Cualquier número de subprocesos o procesos de "trabajador" esperará a que la siguiente solicitud esté disponible, y si un trabajador termina temprano, puede recoger la siguiente solicitud. El inconveniente es que no hay ningún equilibrio de carga explícito entre los trabajadores, pero he encontrado que la distribución de las solicitudes fuera de la cola ha sido bien equilibrada.

0

Hystrix fue diseñado para casi el escenario exacto que está describiendo. Puede definir un tamaño de grupo de subprocesos para cada servicio para que tenga un número máximo de solicitudes simultáneas y pone en cola las solicitudes cuando el grupo está lleno. También puede definir un tiempo de espera para cada servicio y cuando un servicio comienza a exceder su tiempo de espera, Hystrix rechazará más solicitudes a ese servicio por un corto período de tiempo para que el servicio tenga la oportunidad de volver a ponerse en pie. También hay monitoreo en tiempo real de todo el clúster a través del Turbine.

Cuestiones relacionadas