2012-01-28 20 views
8

Mantengo un sitio con un montón de archivos descargables. Actualmente está alojado en un servidor en los EE. UU., Pero recientemente adquirí un nuevo servidor en Alemania. Me gustaría reflejar las descargas al servidor en Alemania, y tener un script PHP en el primer servidor (que aloja el sitio web) detectar qué archivo espejo usar en función de la ubicación del usuario. Por ejemplo, si el usuario está en Canadá, debería descargar el archivo de mi servidor actual en los EE. UU. Si están en Francia, deberían obtener el archivo de Alemania, en lugar de descargarlo a través del Atlántico. ¿Cómo, entonces, puedo determinar a qué país están más cerca?Determinar el espejo más cercano PHP

Conozco MaxMind GeoIP, y lo tengo instalado, pero eso solo me da un país, y AFAIK, no hay manera de determinar automáticamente a cuál de mis dos países espejo es el país más cercano. Supongo que lo que podría hacer es ir por continente: haga que los usuarios de Asia, Europa, África y Australia obtengan el contenido de Alemania y que los visitantes de Norte y Sudamérica obtengan el archivo de los EE. UU. Si alguien puede pensar en una solución mejor , Estoy abierto a sugerencias.


Bueno, supongo que me voy a ir con mi idea original de verificar por continentes. Para otros que buscan hacer este tipo de cosas, ese será un buen lugar para comenzar. El problema vendrá cuando tenga múltiples espejos en Europa, pero la idea del continente tendrá que funcionar por el momento.

+0

se podría llamar los mapas de Google a través de la API de Google y calcule la distancia entre el país en el que vive el usuario de IP y sus dos destinos de servidor, en función de cuál de ellos es el más cercano, establezca el espejo de descarga. Entonces solo tienes dos variables estáticas. Uno para cada ubicación del servidor. –

+0

Estoy fuera de mi área con esto, pero creo * que hay una forma de usar DNS para manejar esto ...? Una pequeña búsqueda produce esto: http://stackoverflow.com/questions/1040545/how-to-dispatch-network-requests-to-the-geographically-closest-server – Aerik

+0

@Jonasm: no es una mala idea, pero te creo no se puede simplemente usar la API de Maps para calcular la distancia, en realidad tiene que mostrar un mapa, que definitivamente es insatisfactorio en este caso. –

Respuesta

2

Parece que hay una gran cantidad de gastos generales del desarrollador en las soluciones propuestas hasta el momento. Si esto era un problema que tenía que resolver en mis propias aplicaciones, podría ahorrarme algunas horas de trabajo al seleccionar y no para reinventar la rueda en este caso.

La determinación de la réplica más próxima (Usando códigos postales)

  1. mantener una lista de códigos postales en una matriz para esos servidores espejo disponibles.
  2. determinar el código postal de la agente de usuario (por ejemplo, la entrada del usuario o biblioteca PHP)
  3. calcular la distancia entre los dos códigos postales (por ejemplo, biblioteca de PHP)
  4. Proceder con la selección de espejo basada en la distancia de regresar

Tenga en cuenta que una distancia más cercana no constituye necesariamente un tiempo de respuesta más rápido. En el contexto de su escenario, sin embargo, un espejo en un país obviamente será más rápido que un espejo en otro, suponiendo que ambos espejos estén activos. Continúe leyendo para lo que considero una solución más "robusta".

Recursos & enlaces

El "Maverick" Enfoque

En mi opinión, Mavericks también son conocidos como los innovadores, capaces de resolver problemas, y los inventores de estos grandes bibliotecas y los marcos que todos usamos hoy en día. A veces erróneamente asociados con ideas "hacker", pero aceptamos el complemento :)

  1. Crear su propio servicio API a cada uno de los servidores espejo que aceptará una solicitud ya sea $ _GET o $ _POST.

  2. Este servicio API tomará una dirección IP y lo hará ping(), calculando los tiempos de respuesta y luego tomando el promedio, devolviéndolo a la interfaz solicitante (por ejemplo, su portal frontend a través del cual se conectan los clientes y/o el servidor tratando de determinar el espejo más cercano).El servidor que responde con el promedio más bajo debería ser el servidor de respuesta más rápida, aunque no necesariamente el más cercano. ¿Qué es más importante para ti? Ver Ping site and return result in PHP para una función ping() que funciona y que no depende de ejecutar comandos de shell localmente (por ejemplo, plataforma independiente).

  3. En el último paso, obtenga la dirección IP del cliente solicitante y páselo a su servicio API ejecutándose en cualquier servidor reflejado en segundo plano. Y todos sabemos cómo derivar el IP, pero no tan bien como crees que podríamos. Si está equilibrado de carga o detrás de un proxy, es posible que desee comprobar primero si alguno de estos encabezados apareció (HTTP_FORWARDED, HTTP_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP). Si es así, probablemente sea real dirección IP del agente de usuario.

Es en este punto (paso 3) donde desea comparar las medias de los tiempos de respuesta que cada espejo respondió con cuando fueron a hacer ping al agente de usuario. Luego proceda con la selección de desde qué espejo debe descargar el agente de usuario. El flujo de servicio se han creado a continuación, se asemeja a algo como esto: agente visitas

  1. usuario del portal
  2. Portal reenvía la dirección IP del agente de usuario de servicio API ejecuta por separado en ambos espejos usando un fondo petición AJAX/jQuery (o tradicional POST y redirigir).
  3. El servicio de API que se ejecuta en las réplicas indica la dirección IP que recibe y devuelve un promedio del número total de respuestas que está configurado para recuperar.
  4. Portal lee los promedios devueltos y los compara.

Espero que ayude y feliz codificación!

+1

Esa es la primera realmente buena y fácil de implementar idea que he visto hasta ahora. Me gusta mucho. Una pregunta: ¿cuánto overhead esto causará? ¿El montón de pequeñas solicitudes terminará siendo difícil para el servidor, calculando alrededor de 500 visitantes por día? –

+0

PHP es ciertamente capaz de hacer más allá de esto, por lo que le corresponde al programador realizar pruebas de referencia y crear unidades de prueba para su código para evaluar su rendimiento. Una posibilidad que viene a la mente en torno a su preocupación es llegar a una solución de almacenamiento en caché donde la selección del servidor ha sido predeterminada. Determine la porción de red de la dirección IP de su agente de usuario y asigne el servidor a esa red (por ejemplo, 192.168.0.0). Luego, si una dirección IP entrante coincide con una porción de red en su base de datos, su portal puede omitir la realización de la llamada API y dirigirse directamente al aprovisionamiento del servidor. – rdev5

+0

Además, hay otra cosa que señalar: algunas personas configuran sus enrutadores para que no respondan a los pings ICMP, mientras que otros todavía no tienen puertos disponibles para conectarse a la prueba (según la referencia ping() en mi publicación). Es completamente posible que obtenga una solicitud expirada. En tales casos, actualizaría su servicio de API para recurrir a una función de cálculo de distancia de IP a código postal que, en lugar de devolver la respuesta de ping promedio como una cifra numérica, devuelve la distancia como una cifra numérica. De nuevo, con la comprensión de que la distancia no necesariamente significa una conexión más rápida. – rdev5

0

No recuerdo ninguna biblioteca que pueda hacer esto. Pero en lugar de construir un sistema, si tengo una idea, podría ayudarte.

Calcule la distancia entre dos direcciones IP usando este distance calculator. O descubra la latitud y la longitud de las dos direcciones IP (un servidor) y (un invitado) y calcule la distancia. Aquí es un pseudocódigo para hacer eso

distance = (3956 *2 * ASIN(SQRT(POWER(SIN((34.1012181 - ABS(latitude)) * PI() /180 /2) , 2) + COS(34.1012181 * PI() /180) * COS(ABS(latitude) * PI() /180) * POWER(SIN((ABS(- 118.325739) - ABS(longitude)) * PI() /180 /2) , 2)))) 
0

hacer un traceroute (configurar el cliente no traceroute para resolver nombres de host y con un pequeño tiempo de espera).

Según el número de saltos y la ubicación del cliente traceroute (supongo que es el mismo que el script PHP), seleccione entre EE. UU. Y Alemania.

La distancia geográfica no tiene nada que ver con la distancia de red y la velocidad de red, o los costos de ancho de banda.

Como alternativa a la traceroute (ya que es una solución de código hacker, pequeño), recomiendo que utilice el $ _SERVER [ "REMOTE_ADDR"] y mirar hacia arriba en un geo ip database para obtener el código de país. Si el código de país no es uno de los países en los continentes americanos, para evitar cruzar una red troncal repleta de gente, retroceda a Alemania (además, podría condicionar el código de país para que sea de Europa).

Una vez que haya configurado la base de datos geo ip, le recomiendo que convierta las direcciones IP en los rangos de formato de puntos a formato entero para mayor velocidad y facilidad de consulta.

Según mi experiencia con la base de datos geo ip anterior, falla tan poco que no importa.

1

Si solo tiene dos espejos, inicie las solicitudes AJAX en su navegador que descargan un archivo de 50K de cada servidor. Esto es lo suficientemente pequeño como para no representar un gran retraso para el usuario, pero lo suficientemente grande como para hacer que las diferencias de medición del cronómetro sean significativas, aunque, por supuesto, debería jugar con esa cifra un poco.

Luego, una vez que tenga un "mejor momento", configure una cookie JS y redirija al espejo preferido cada vez que se requiera una descarga.La medición se puede iniciar desde una página de descarga en segundo plano, por lo que el usuario probablemente no notará el retraso (mientras están seleccionando el archivo que desean).

Incluso podría responder con una 'carga del servidor' en cada AJAX op y seleccionar el mejor servidor no solo en el tiempo de respuesta sino también en la carga actual. Entonces, un usuario del Reino Unido usaría el servidor de EE. UU., Aunque el servidor más cercano esté en Alemania, si la carga en este último es significativamente más alta que la primera.

+0

Me gusta esta idea – Sam

0

no es más fácil usar alguna biblioteca como geoip como dijiste y usar la latitud y longitud para comparar la distancia entre los espejos y el usuario?

Creo que es menos complicado y su mucho más fácil de implemen, trabaja para N espejos y U no necesita solicitar un Zip u otro tipo de datos para tomar las referencias