2009-07-07 9 views
8

Actualmente trato de implementar un servidor HTTP simple para algún tipo de comet -technique (solicitudes XHR de sondeo largo). Como JavaScript es muy estricto en cuanto a las solicitudes crossdomain Tengo algunas preguntas:Comprender mod_proxy y Apache 2 para escribir un comet-server

  1. Según entendí cualquier trabajador Apache se bloquea mientras cumplía una petición, por lo que escribir el "guión" como un sitio web habitual bloquearía el Apache, cuando todo trabajadores que tienen una solicitud para servir. -> No funciona!
  2. Se me ocurrió la idea de escribir un servidor HTTP simple y propio solo para servir a este largo pedido de sondeo. Este servidor no debería estar bloqueando, por lo que cada trabajador podría manejar muchas solicitudes al mismo tiempo. Como mi sitio también contiene contenido/imágenes, etc. y mi servidor no necesita contenido del servidor, lo inicié en un puerto diferente, entonces 80. El problema ahora es que no puedo interactuar entre mi JavaScript entregado por mi apache y mi servidor de cometa ejecutándose en un puerto diferente, debido a algunas restricciones de dominios cruzados. -> No funciona!
  3. Luego se me ocurrió la idea de usar mod_proxy para asignar mi servidor en un nuevo subdominio. Realmente no pude entender cómo funciona el mod_proxy pero podría imaginar que sé que tiene el mismo efecto que en mi primer acercamiento.

¿Cuál sería la mejor manera de crear este tipo de combinación de este tipo de sitio web clásico y estas solicitudes XHR de larga duración? ¿Debo implementar la entrega de contenido en mi servidor por mi cuenta?

Respuesta

3

Estoy bastante seguro de que usar mod_proxy bloqueará a un trabajador mientras se procesa la solicitud.

Si puede utilizar 2 direcciones IP, hay una solución bastante fácil. Digamos que IP A es 1.1.1.1 e IP B es 2.2.2.2, y digamos que su dominio es example.com.

Esta es la forma en que va a funcionar:

-Configure Apache para que escuche en el puerto 80, pero sólo en IP A.

-Start su otro servidor en el puerto 80, pero sólo en IP B.

-Configure las solicitudes XHR para estar en un subdominio de su dominio, pero con el mismo puerto. Entonces, las restricciones entre dominios no los previenen. Por lo tanto, su sitio es example.com y las solicitudes XHR van a xhr.example.com, por ejemplo.

-Configure su DNS para que example.com resuelve IP A y xhr.example.com resuelve IP B.

-Estás hecho.

Esta solución funcionará si tiene 2 servidores y cada uno tiene su IP, y funcionará si tiene un servidor con 2 direcciones IP.

Si no puede usar 2 direcciones IP, puedo tener otra solución, estoy comprobando si es aplicable a su caso.

+0

Estoy interesado en la idea de que sólo el uso de una dirección IP. – TheHippo

+1

No creo que el modelo de seguridad del navegador permita que el código cargado desde example.com envíe XHR a xhr.example.com. Tienes que jugar con document.domain y IFrames, y luego no es portátil. - http: //www.fettig.net/weblog/2005/11/28/how-to-make-xmlhttprequest-connections-to-another-server-in-your-domain / –

3

Este es un problema difícil. Incluso si supera los problemas de seguridad con los que se está encontrando, terminará teniendo que mantener abierta una conexión TCP para cada cliente que actualmente esté mirando una página web. No podrá crear un hilo para manejar cada conexión, y no podrá "seleccionar" en todas las conexiones desde un único hilo. Habiendo hecho esto antes, puedo decirte que no es fácil. Es posible que desee examinar libevent, que memcached utiliza para un fin similar.

Hasta cierto punto, probablemente pueda salirse con la suya estableciendo largos tiempos de espera y permitiendo que Apache tenga una gran cantidad de trabajadores, la mayoría de los cuales estarán inactivos la mayor parte del tiempo. La elección cuidadosa y la configuración del módulo de trabajo de Apache extenderán esto a miles de usuarios simultáneos, creo. En algún momento, sin embargo, ya no se escalará más.

No sé cómo es su infraestructura, pero tenemos cajas de equilibrio de carga en los bastidores de red llamados F5. Presentan un solo dominio externo, pero redirigen el tráfico a múltiples servidores internos en función de sus tiempos de respuesta, las cookies en los encabezados de las solicitudes, etc. Se pueden configurar para enviar solicitudes de una determinada ruta dentro del dominio virtual a un servidor específico. Por lo tanto, podría tener solicitudes example.com/xhr/foo asignadas a un servidor específico para manejar estas solicitudes de cometas. Desafortunadamente, esto no es una solución de software, sino una solución de hardware bastante costosa.

De todos modos, es posible que necesite algún tipo de sistema de equilibrio de carga (o tal vez ya tenga uno), y tal vez se puede configurar para manejar esta situación mejor que Apache.

Tuve un problema hace años cuando quería que los clientes que usaban un sistema cliente-servidor con un protocolo binario patentado pudieran acceder a nuestros servidores en el puerto 80 porque continuamente tenían problemas con los firewalls en el puerto personalizado que el sistema usado. Lo que necesitaba era un proxy que viviera en el puerto 80 y dirigiera el tráfico a Apache o al servidor de la aplicación, dependiendo de los primeros bytes de lo que venía del cliente. Busqué una solución y no encontré nada que se ajustara. Consideré escribir un módulo de Apache, un complemento para DeleGate, etc., pero finalmente lo hice mediante un servicio de proxy de detección de contenido personalizado. Ese, creo, es el peor escenario posible para lo que estás tratando de hacer.

0

Para responder a la pregunta específica sobre mod-proxy: , se puede configurar mod_proxy para servir contenido que es generado por un servidor (o servicio) que no está orientada al público (es decir, que sólo está disponible a través de una dirección interna o localhost).

He hecho esto en un entorno de producción y funciona muy, muy bien. Apache reenvía algunas solicitudes a Tomcat a través de los trabajadores de AJP, y otras a un servidor de aplicaciones GIS a través de proxy mod. Como otros han señalado, la seguridad entre sitios puede dejar que te trabajando en un sub-dominio, pero no hay ninguna razón por qué no puede pasar peticiones a mydomain.com/application


Para hablar de su específica Problema: creo que realmente te empantanas al ver el problema como "solicitudes de larga duración", es decir, asumiendo que cuando realizas una de estas solicitudes, todo el proceso debe detenerse. Parece que estás tratando de resolver un problema con la arquitectura de la aplicación a través de cambios en la arquitectura del sistema. De hecho, lo que debe hacer es tratar estas solicitudes de antecedentes exactamente como tales; y multi-hilo a:

  • cliente hace la solicitud al servicio remoto "realizar tarea X con los datos A, B y C"
  • Su servicio recibe la solicitud: lo pasa a un planificador que emite un ticket/token único para la solicitud.El servicio devuelve este token al cliente "gracias, su tarea está en una cola que se ejecuta bajo el token Z"
  • El cliente se cuelga en este token, muestra un cuadro de "carga/espere por favor" y configura un temporizador que dicen los incendios, los argumentos, cada segundo
  • Cuando se activa el temporizador, el cliente realiza otra petición al servidor remoto "usted ha conseguido el resultado para mi tarea, que es Z símbolo"
  • usted servicio en segundo plano puede luego verifique con su planificador, y probablemente devuelva un documento vacío "no, aún no se ha hecho" o los resultados
  • Cuando el cliente obtiene los resultados, simplemente puede borrar el temporizador y mostrarlos.

Siempre que esté razonablemente cómodo con el enhebrado (que debe ser si ha indicado que está buscando escribir su propio servidor HTTP, esto no debería ser demasiado complejo, además del http parte oyente:

  • objeto Programador - objeto único, de verdad que solo se ajusta un "primero en entrar, primero en salir" pila nuevas tareas van en el extremo de la pila, los trabajos se puede sacar desde el principio: acaba de hacer. Asegúrese de que el código para emitir un trabajo es seguro para subprocesos (menos se obtienen dos trabajos que extraen el mismo trabajo de la pila).
  • Los subprocesos de trabajo pueden ser bastante simples: obtenga acceso a el programador, pregunte por el próximo trabajo: si hay uno, haga el trabajo envíe los resultados; de lo contrario, simplemente duerma durante un período, comience nuevamente.

De esta manera, nunca vas a estar bloqueando Apache por más tiempo del necesario, ya que todo lo que estás haciendo son solicitudes de problemas para "do x" o "dame resultados para x". Probablemente desee construir algunas características de seguridad en algunos puntos, como el manejo de tareas que fallan y asegurarse de que haya un tiempo de espera en el lado del cliente para que no espere indefinidamente.

0

Para el número 2: puede evitar las restricciones de dominio cruzado mediante el uso de JSONP.

0

Dostres alternativas:

  1. Use nginx. Esto significa que ejecuta 3 servidores: nginx, Apache y su propio servidor.
  2. Ejecute su servidor en su propio puerto.
  3. Utilice Apache mod_proxy_http (como su propia sugerencia).

mod_proxy_http He confirmado (Apache 2.2.16) funciona una aplicación proxy Comet (alimentado por Ambiente 0.7.1) que se ejecutan en GlassFish 3.1.1.

Mi aplicación de prueba con código fuente completo está aquí: https://github.com/ceefour/jsfajaxpush

Cuestiones relacionadas