2012-07-03 16 views
12

Estoy pidiendo esto aquí porque creo que se aplica a algo más que a EasyPHP.PHP a EasyPHP servidor MySQL 1 segundo retraso de conexión

Actualmente uso EasyPHP como servidor de desarrollo WAMP para poder crear aplicaciones web. El problema es que cuando obtengo el objeto mysqli para conectarme a la base de datos, demora 1 segundo. Ejecutar la misma consulta en el alojamiento compartido da como resultado velocidades 200 veces más rápidas. ¿Debería ser algo de lo que debería estar preocupado? En términos de escalabilidad o mover mi aplicación a otro servidor, ¿sería inteligente pasar un rato viendo cuál es el problema? Solo asumí que quizás EasyPHP era lento. No es un comandante, solo algo que me pareció interesante.

Respuesta

45

Si tiene este problema y utiliza una versión de Windows anterior a Windows 7, probablemente esta no sea la solución a su problema.

¿Por qué sucede esto?

La causa de este problema es IPv4 vs IPv6.

Cuando utiliza un nombre de host en lugar de una dirección IP, el cliente MySQL ejecuta primero una búsqueda de host AAAA (IPv6) para el nombre e intenta primero esta dirección si resuelve satisfactoriamente el nombre a una dirección IPv6. Si cualquiera de los pasos falla (resolución de nombre o conexión), volverá a utilizar IPv4, ejecutará una búsqueda A y probará este host.

Lo que esto significa en la práctica es que si la búsqueda de IPv6 localhost es exitosa pero MySQL no está vinculado al bucle invertido de IPv6, tendrá que esperar un ciclo de tiempo de espera de conexión (evidentemente en la máquina del OP es 1 segundo) antes el respaldo de IPv4 ocurre y la conexión tiene éxito.

Esto no era un problema antes de Windows 7, ya que localhost resolución se realiza mediante el archivo hosts, y llegó preconfigurado con solamente 127.0.0.1 - no vino con su contraparte IPv6 ::1.

Desde Windows 7, sin embargo, la resolución localhost está integrada en el sistema de resolución de DNS, por los motivos descritos here. Esto significa que la búsqueda de IPv6 ahora tendrá éxito, pero MySQL no está vinculado a esa dirección IPv6, por lo que la conexión fallará, y verá el retraso descrito en esta pregunta.

Eso es bueno. ¡Solo dime cómo arreglarlo ya!

Tiene algunas opciones.Buscando en Internet, la "solución" general parece ser usar la dirección IP explícitamente en lugar del nombre, pero hay un par de razones para no hacerlo, ambas relacionadas con la portabilidad, ambas posiblemente no son importantes:

  • Si mueve la secuencia de comandos a otra máquina que solo es compatible con IPv6, la secuencia de comandos ya no funcionará.

  • Si se mueve el guión para un entorno de alojamiento basados ​​en * nix, la cadena mágica localhost significaría el cliente MySQL preferiría utilizar un socket de Unix que se haya configurado, esto es más eficiente que la conectividad

    con base IP de bucle invertido

Aunque suenan bastante importantes?

No lo son. Debe diseñar su aplicación para que este tipo de cosas se defina en un archivo de configuración. Si mueve su script a otro entorno, es probable que haya otras cosas que también necesiten configuración.

En resumen, usar la dirección IP no es la mejor solución , pero es muy probable que sea aceptable.

¿Cuál es la mejor solución?

La mejor manera sería cambiar la dirección de vinculación que utiliza el servidor MySQL. Sin embargo, esto no es tan simple como a uno le gustaría. A diferencia de Apache, Nginx y casi todas las otras aplicaciones de servicios de red, alguna vez, MySQL solo admite una sola dirección de vinculación, por lo que no se trata solo de agregar otra. Afortunadamente, los sistemas operativos admiten un poco de magia aquí, por lo que podemos permitir que MySQL use tanto IPv4 como IPv6 simultáneamente.

Debe ejecutar MySQL 5.5.3 o posterior, y debe iniciar MySQL con el argumento de la línea de comando --bind-address= (o configurar la opción correspondiente en my.ini). Usted tiene 4 opciones docs, dependiendo de lo que quieres hacer:

  • el que usted probablemente está familiarizado con, y el que lo más probable es (efectivamente) usando, 0.0.0.0. Esto se une a todas las direcciones IPv4 disponibles en la máquina. En realidad, esto probablemente no sea lo mejor que puede hacer, incluso si no le importa IPv6, ya que sufre los mismos riesgos de seguridad que ::.

  • Una dirección IPv4 o IPv6 explícita (por ejemplo 127.0.0.1 o ::1 para loopback). Esto vincula el servidor a esa dirección y solo esa dirección.

  • La cadena mágica ::. Esto vinculará a MySQL con todas las direcciones de la máquina, tanto las direcciones de interfaz física como de bucle, en los modos IPv4 e IPv6. Esto es potencialmente un riesgo de seguridad, solo hazlo si necesitas que MySQL acepte conexiones de hosts remotos.

  • Utilice IPv4-mapped IPv6 address. Este es un mecanismo especial integrado en IPv6 para compatibilidad con versiones anteriores durante la transición 4 -> 6, y le permite vincularse a una dirección IPv4 específica y es equivalente a IPv6. Es poco probable que esto sea útil para cualquier otra cosa que no sea la dirección de "doble bucle de retorno" ::ffff:127.0.0.1.Es muy probable que esta sea la mejor solución para la mayoría de las personas, solo vinculando al bucle invertido pero permitiendo conexiones tanto IPv4 como IPv6.

¿Debo modificar el archivo de hosts?

NO. No modifique el archivo de hosts. El solucionador de DNS sabe qué hacer con localhost, redefinirlo en el mejor de los casos no tendrá ningún efecto y, en el peor de los casos, confundirá al solucionador.

¿Qué hay de --skip-name-resolve?

Esto también puede solucionar el problema/se requiere para solucionar el problema, por una razón relacionada pero ligeramente diferente.

Sin esta opción de configuración, MySQL intentará resolver todas las direcciones IP de conexión del cliente a un nombre de host a través de una consulta DNS PTR. Si su servidor MySQL ya está habilitado para usar IPv6 pero las conexiones aún tardan mucho tiempo, puede ser porque el registro DNS inverso (PTR) no está configurado correctamente.

La desactivación de la resolución del nombre solucionará este problema, pero tiene otras ramificaciones, especialmente que los permisos de acceso configurados para usar un nombre DNS en la condición Host ahora fallarán.

Si va a hacer esto, deberá configurar todas sus concesiones para usar direcciones IP en lugar de nombres.

+12

-1 ¡sin jquery en absoluto! – PeeHaa

+0

TL; DR! Lol, en realidad, esta respuesta es perfecta. ¿Sabes si MySQL 5.6 resuelve el problema? Podría actualizar en su lugar. (Pero, en serio, ¿no jQuery?) – MaxArt

+0

Este parece ser un problema muy común para las máquinas con Windows 8 con consultas mysql muy lentas (comentario para SEO). – Josiah

0

Independientemente del servidor, sería bueno utilizar conexiones persistentes siempre que sea posible. Después de todo, no es aconsejable abrir nuevas conexiones todo el tiempo cuando las antiguas también pueden llevar a cabo el trabajo. Eche un vistazo a manual para mysqli.

+0

Tuve problemas con las conexiones persistentes: PHP a veces intentaba crear conexiones nuevas aunque había conexiones existentes "libres", lo que producía un error de "demasiadas conexiones". Sin embargo, fue hace años, por lo que podría ser arreglado ya (o podría ser un problema local). – binaryLV

+0

Debe haber sido arreglado. Las conexiones persistentes para mysqli se introdujeron en PHP 5.3, por lo que no son tan antiguas. – linepogl

+0

Creo que tuve problemas con las funciones anteriores de PDO o de MySQL. Nunca he usado realmente mysqli. – binaryLV

23

Tuve cierta demora al usar localhost como dirección del servidor MySQL. Cambiarlo a 127.0.0.1 ayudó.

+0

Bien, eres increíble. Muchas gracias. Cambié el host a 127.0.0.1 y mis páginas se ejecutan en 0.0074560547 segundos. No puedo agradecerle lo suficiente. – Sam

Cuestiones relacionadas