Infraestructura: Servidores en Datacenter, OS - Debian Squeeze, Webserver - Apache 2.2.16
Situación:
Nuestros clientes usan el servidor en vivo todos los días, lo que hace que sea imposible probar los ajustes y las mejoras. Por lo tanto, nos gustaría duplicar el tráfico HTTP entrante en el servidor en vivo a uno o varios servidores remotos en tiempo real. El tráfico debe pasar al servidor web local (en este caso, Apache) Y al servidor o servidores remotos. De este modo, podemos ajustar las configuraciones y usar un código diferente / actualizado en los servidores remotos para la evaluación comparativa y la comparación con el servidor actual. Actualmente el servidor web está escuchando aprox. 60 puertos adicionales además de 80 y 443, debido a la estructura del cliente.
Pregunta: ¿Cómo se puede implementar esta duplicación en uno o varios servidores remotos?
Ya hemos intentado:
- duplicador agnoster: esto requeriría una sesión abierta por puerto que no es aplicable. ( https://github.com/agnoster/duplicator )
- Proxy kklis: solo reenvía el tráfico al servidor remoto, pero no lo pasa al servidor web lcoal. ( https://github.com/kklis/proxy )
- iptables: DNAT solo reenvía el tráfico, pero no lo pasa al servidor web local
- iptables - TEE solo duplica a los servidores en la red local -> los servidores no están ubicados en la misma red debido a la estructura del centro de datos
- las alternativas sugeridas para la pregunta "duplicar el tráfico de TCP con un proxy" en stackoverflow ( https://stackoverflow.com/questions/7247668/duplicate-tcp-traffic-with-a-proxy ) no tuvieron éxito. Como se mencionó, TEE no funciona con servidores remotos fuera de la red local. teeproxy ya no está disponible ( https://github.com/chrislusf/tee-proxy ) y no pudimos encontrarlo en otro lugar.
- Hemos agregado una segunda dirección IP (que está en la misma red) y la asignamos a eth0: 0 (la dirección IP principal se asigna a eth0). Sin éxito al combinar esta nueva interfaz IP o virtual eth0: 0 con la función o rutas TEE de iptables.
- Las alternativas sugeridas para la pregunta "duplicar el tráfico tcp entrante en Debian Squeeze" ( Duplicar el tráfico TCP entrante en Debian Squeeze ) no tuvieron éxito. Las sesiones cat | nc (cat / tmp / prodpipe | nc 127.0.0.1 12345 y cat / tmp / testpipe | nc 127.0.0.1 23456) se interrumpen después de cada solicitud / conexión por parte de un cliente sin previo aviso o registro. Keepalive no cambió esta situación. Los paquetes TCP no se transportaron al sistema remoto.
- Pruebas adicionales con diferentes opciones de socat (HowTo: http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/ , https://stackoverflow.com/questions/9024227/duplicate-input- unix-stream-to-multiple-tcp-clients-using-socat ) y herramientas similares no tuvieron éxito, porque la función TEE proporcionada solo escribirá en FS.
- Por supuesto, buscar en Google y buscar este "problema" o configuración tampoco tuvo éxito.
Nos estamos quedando sin opciones aquí.
¿Existe algún método para deshabilitar la aplicación del "servidor en la red local" de la función TEE cuando se usan IPTABLES?
¿Se puede lograr nuestro objetivo mediante el uso diferente de IPTABLES o Rutas?
¿Conoces una herramienta diferente para este propósito que haya sido probada y funcione para estas circunstancias específicas?
¿Existe una fuente diferente para tee-proxy (que se ajuste perfectamente a nuestros requisitos, AFAIK)?
Gracias de antemano por tus respuestas.
----------
editar: 05.02.2014
Aquí está el script de Python, que funcionaría de la manera que lo necesitamos:
import socket
import SimpleHTTPServer
import SocketServer
import sys, thread, time
def main(config, errorlog):
sys.stderr = file(errorlog, 'a')
for settings in parse(config):
thread.start_new_thread(server, settings)
while True:
time.sleep(60)
def parse(configline):
settings = list()
for line in file(configline):
parts = line.split()
settings.append((int(parts[0]), int(parts[1]), parts[2], int(parts[3])))
return settings
def server(*settings):
try:
dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dock_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
dock_socket.bind(('', settings[0]))
dock_socket.listen(5)
while True:
client_socket = dock_socket.accept()[0]
client_data = client_socket.recv(1024)
sys.stderr.write("[OK] Data received:\n %s \n" % client_data)
print "Forward data to local port: %s" % (settings[1])
local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
local_socket.connect(('', settings[1]))
local_socket.sendall(client_data)
print "Get response from local socket"
client_response = local_socket.recv(1024)
local_socket.close()
print "Send response to client"
client_socket.sendall(client_response)
print "Close client socket"
client_socket.close()
print "Forward data to remote server: %s:%s" % (settings[2],settings[3])
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((settings[2], settings[3]))
remote_socket.sendall(client_data)
print "Close remote sockets"
remote_socket.close()
except:
print "[ERROR]: ",
print sys.exc_info()
raise
if __name__ == '__main__':
main('multiforwarder.config', 'error.log')
Los comentarios para usar esta secuencia de comandos:
Esta secuencia de comandos reenvía una serie de puertos locales configurados a otro servidor de socket local y remoto.
Configuración:
agregue al archivo de configuración port-forward.config líneas con contenido de la siguiente manera:
Los mensajes de error se almacenan en el archivo 'error.log'.
El script divide los parámetros del archivo de configuración:
Divida cada línea de configuración con espacios
0: puerto local para escuchar
1: puerto local para reenviar a
2: dirección IP remota del servidor de destino
3: puerto remoto del servidor de destino
y devuelva la configuración
Respuestas:
Es imposible. TCP es un protocolo con estado. La computadora del usuario final participa en cada paso de la conexión y nunca responderá a dos servidores separados que intentan comunicarse con ella. Todo lo que puede hacer es recopilar todas las solicitudes http en el servidor web o algún proxy y reproducirlas. Pero eso no dará una concurrencia exacta o condiciones de tráfico de un servidor en vivo.
fuente
Por lo que describe, GOR parece satisfacer sus necesidades. https://github.com/buger/gor/ "Reproducción de tráfico HTTP en tiempo real. Reproduzca el tráfico desde la producción hasta los entornos de preparación y desarrollo". ?
fuente
Teeproxy podría usarse para replicar el tráfico. El uso es realmente simple:
a
servidor de producciónb
servidor de pruebaCuando coloca un HAproxy (con
roundrobin
) antes de su servidor web, puede redirigir fácilmente el 50% de su tráfico al sitio de prueba:fuente
TCP, al ser un protocolo con estado, no es capaz de enviar copias de los paquetes a otro host, como señala @KazimierasAliulis.
Recoger los paquetes en la capa de terminación TCP y retransmitirlos como una nueva secuencia TCP es razonable. La herramienta duplicadora a la que se vinculó parece su mejor apuesta. Funciona como un proxy TCP, lo que permite que la máquina de estado TCP funcione correctamente. Las respuestas de sus máquinas de prueba simplemente se descartarán. Parece que se ajusta a la factura de lo que quieres exactamente.
No me queda claro por qué descartó la herramienta duplicadora como inaceptable. Tendrá que ejecutar varias instancias de la herramienta, ya que solo escucha en un solo puerto pero, presumiblemente, desea retransmitir cada uno de esos diferentes puertos de escucha a diferentes puertos en el sistema de fondo. De lo contrario, podría usar iptables DNAT para dirigir todos los puertos de escucha a una sola copia de escucha de la herramienta duplicadora.
A menos que las aplicaciones que está probando sean muy simples, espero que tenga problemas con esta metodología de prueba relacionada con el tiempo y el estado interno de la aplicación. Lo que quieres hacer suena engañosamente simple: espero que encuentres muchos casos extremos.
fuente
Estoy tratando de hacer algo similar, sin embargo, si simplemente está tratando de simular la carga en un servidor, miraría algo como un marco de prueba de carga. He usado locust.io en el pasado y funcionó muy bien para simular una carga en un servidor. Eso debería permitirle simular una gran cantidad de clientes y permitirle jugar con la configuración del servidor sin tener que pasar por el doloroso proceso de reenviar el tráfico a otro servidor.
fuente
En cuanto a "nos gustaría duplicar el tráfico HTTP entrante en el servidor en vivo a uno o varios servidores remotos en tiempo real", hay una forma no mencionada anteriormente, que es configurar un puerto espejo en el conmutador al que está conectado.
En el caso de los switches Cisco Catalyst, esto se llama SPAN (más información aquí ). En un entorno Cisco, incluso puede tener el puerto duplicado en un conmutador diferente.
Pero el propósito de esto es para el análisis de tráfico, por lo que será unidireccional: palabra clave en el texto citado en el primer párrafo anterior: entrante . No creo que ese puerto permita ningún tráfico de retorno, y si lo hiciera, ¿cómo lidiaría con el tráfico de retorno duplicado? Eso probablemente causará estragos en su red.
Entonces ... solo quería agregar una posibilidad a su lista, pero con la advertencia de que realmente será para el tráfico unidireccional. Tal vez pueda poner un concentrador en ese puerto espejo y tener respuestas duplicadas del servidor entregadas por algún simulador de cliente local que recogería las sesiones iniciadas y respondería, pero luego estaría duplicando el tráfico entrante a su servidor duplicado ... probablemente no lo que usted querer.
fuente
También he escrito un proxy inverso / equilibrador de carga para un propósito similar con Node.js (es solo por diversión, no está listo para la producción en este momento).
https://github.com/losnir/ampel
Es muy obstinado y actualmente admite:
GET
Uso de la selección round-robin (1: 1)POST
Uso de división de solicitudes. No existe un concepto de "maestro" y "sombra": el primer backend que responde es el que atenderá la solicitud del cliente, y luego se descartarán todas las demás respuestas.Si alguien lo encuentra útil, entonces puedo mejorarlo para que sea más flexible.
fuente
mi empresa tenía un requisito similar: clonar un paquete y enviarlo a otro host (ejecutamos simuladores de datos de mercado y necesitábamos una solución temporal que escuchara una alimentación TCP de datos de mercado, ingiriera cada paquete pero también enviara un clon de cada paquete a otro simulador servidor)
este binario funciona muy bien, es una versión de TCP Duplicator pero está escrito en golang en lugar de jscript, por lo que es más rápido y funciona como se anuncia,
https://github.com/mkevac/goduplicator
fuente
hay una herramienta creada por un chico de una empresa china, y tal vez sea lo que necesitas: https://github.com/session-replay-tools/tcpcopy
fuente