2010-07-21 17 views
6

Tengo que implementar un cliente HTTP en Java y, para mis necesidades, parece que la forma más eficiente de hacerlo es implementando una canalización HTTP (según RFC2616).HTTP 1.1 Pipelining

Como un aparte, quiero canalizar POST. (Tampoco me refiero a la multiplexación. Me refiero a la canalización, es decir, a muchas solicitudes sobre una conexión antes de recibir respuesta a lotes de solicitudes HTTP)

No pude encontrar una biblioteca de terceros que indique explícitamente que admite pipelining. Pero podría usar, por ejemplo, Apache HTTPCore para construir dicho cliente, o si tengo que hacerlo, compilarlo yo mismo.

El problema que tengo es si es una buena idea. No he encontrado ninguna referencia autorizada de que la canalización HTTP sea algo más que un modelo teórico y que los servidores HTTP la implementen correctamente. Además, todos los navegadores compatibles con la canalización tienen esta característica desactivada por defecto.

Por lo tanto, debería intentar implementar un cliente así o tendré muchos problemas debido a las implementaciones (o proxies) del servidor. ¿Hay alguna referencia que dé pautas sobre esto?

Si es una mala idea, ¿cuál sería el modelo de programación alternativo para la eficiencia? Separar las conexiones TCP?

+0

No es exactamente lo que necesita, pero serf es una biblioteca de C que implementa HTTP pipelining http://code.google.com/p/serf/ Sin embargo, no estoy 100% seguro si admite publicaciones segmentadas. – Rup

+0

Gracias, tengo que hacerlo en java – Cratylus

+0

@ user384706 Nunca he probado serf, pero si de hecho hace lo que quiere y todo lo demás falla, entonces siempre puede probar JNI/JNA. – luiscubal

Respuesta

8

he implementado un cliente HTTP pipeline. El concepto básico parece fácil pero el manejo de errores es muy difícil.La ganancia de rendimiento es tan insignificante que nos dimos por vencidos con los conceptos hace mucho tiempo.

En mi opinión, no tiene sentido para el caso de uso normal. Solo tiene algunos beneficios cuando las solicitudes tienen conexiones lógicas. Por ejemplo, tiene una transacción de 3 solicitudes y puede enviarlas todas en un lote. Pero normalmente puede combinarlos en una sola solicitud si se pueden canalizar.

siguientes son sólo algunos obstáculos que puedo recordar,

  1. de mantenimiento de conexión de TCP no está garantizada conexión persistente. Si tiene 3 solicitudes conectadas en la conexión, el servidor desconecta la conexión después de la primera respuesta. Se supone que debes volver a intentar las siguientes dos solicitudes.

  2. Cuando tiene conexiones múltiples, el equilibrio de carga también es complicado. Si no hay una conexión inactiva, puede usar una conexión ocupada o crear una nueva.

  3. Tiempo de espera también es complicado. Cuando se agota el tiempo de una solicitud, debe descartar todo después, ya que deben volver a estar en orden.

+0

@ZZ Coder ¡Gracias! ¿En tu cliente canalizaste POST también? Mi caso no es normal. Quiero canalizar los POST en tiempo real que desencadenan acciones en un centro de llamadas. ¡Se agradece cualquier información que recuerde, especialmente sobre el comportamiento de los servidores/proxies! – Cratylus

+0

Sí. Maneja POST. No hay diferencia, excepto que debe recordar el cuerpo si implementa la lógica de reintento. –

+0

@ZZ Coder - Con respecto a 1: en el caso de HTTP, debe implementar la lógica de reintento de todos modos, y la lógica de reintento para las conexiones en línea no es muy diferente (lo único que ocurre es que en caso de reintento después de que se interrumpe esperar la primera respuesta para ver si se trata de una conexión interconectada o no).Y la mayoría de los servidores en estos días tienen pipelining habilitado por defecto, así que a excepción de conexiones de red muy malas, las caídas de la tubería no deberían ocurrir a menudo, supongo –

9

post no debe pipeline

8.1.2.2 tuberias de

Un cliente que sea compatible persistentes conexiones pueden "pipeline" sus solicitudes (es decir, enviar varias solicitudes sin esperar a que cada respuesta) . Un servidor DEBE enviar sus respuestas a esas solicitudes en el mismo orden en que se recibieron las solicitudes .

Clientes que asumen persistentes conexiones y tuberías de inmediato después del establecimiento de conexión debe estar preparados para volver a intentar su conexión si falla el primer intento pipeline. Si un cliente lo intenta de este modo, DEBE NO interconectarse antes de saber que la conexión es persistente. Los clientes DEBEN también estar preparados para volver a enviar sus solicitudes si el servidor cierra la conexión antes de enviar todas las respuestas correspondientes a .

Clientes NO solicitudes de tuberías DEBEN usando métodos no idempotentes o secuencias no idempotentes de métodos (ver sección 9.1.2). De lo contrario, una terminación prematura de la conexión de transporte podría dar lugar a resultados indeterminados. Un cliente que desee enviar una solicitud no ideopotente DEBE esperar a enviar esa solicitud hasta que haya recibido el estado de respuesta para la solicitud previa .

http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html

+4

Gracias por la respuesta. Pero NO DEBERÍA significar: "puede haber razones válidas en circunstancias particulares cuando el comportamiento particular es aceptable o incluso útil" según el rfc 2119. Este es uno de estos casos. A menos que exista una implicación en la definición NO DEBERÍA no entender – Cratylus

+0

@ user384706 Si su solicitud es realmente idempotente, ¿tal vez realmente está haciendo una PUT? –

+0

@ user384706, Significa que un servidor pésimo podría tener problemas cuando se publique. Pero es cierto, eso no es tu culpa, pero cuando las cosas no funcionan, las cosas no funcionan. Quien sea la culpa es que no importa. – Pacerier

-1

pipelining casi no hace diferencia a los servidores http; generalmente procesan las solicitudes en una conexión en serie de todos modos: lee una solicitud, escribe una respuesta y luego lee la siguiente solicitud ...

pero el cliente probablemente mejoraría el rendimiento multiplexando. los sitios web generalmente tienen varias máquinas con varias CPU, ¿por qué quiere limitar voluntariamente sus solicitudes en una sola línea? hoy se trata más de la escalabilidad horizontal (solicitudes simultáneas). por supuesto, es mejor compararlo.

+1

En la canalización, al menos por definición, la interacción no es serial, ya que las solicitudes vienen en lotes. Además, ¿qué ocurre si existe una limitación en el número de conexiones abiertas al mismo servidor? – Cratylus

+2

Hace toda la diferencia cuando se usa una conexión de alta latencia (acceso telefónico); aún más cuando se trata de una "tubería larga y gruesa" (satélite). Evita la sobrecarga de múltiples conexiones TCP, pero mantiene la mayoría de las ventajas. – lxgr

Cuestiones relacionadas