2009-10-22 10 views
5

Tengo un script php que necesita ejecutarse por bastante tiempo.php/timeout/connection to server reset?

Lo que hace el script:

  • conecta a MySQL
  • inicia en cualquier lugar de 100 a 100.000 cURL solicita
  • cada solicitud curvatura devuelve datos compactos decodificado de 1 a 2.000 listados de bienes raíces - yo uso preg-match-all para obtener todos los datos y hacer una inserción de mysql por listado. cada consulta nunca excede más de 1mb de datos.

De modo que hay muchos bucles, inserciones de mysql y solicitudes de curl en curso. El modo seguro php está desactivado y puedo instalar con éxito el tiempo máximo de ejecución en algo ridículo para permitir que mi script se ejecute completamente.

Bueno, mi problema es que el script o apache o algo está teniendo un trazo en el medio de la secuencia de comandos y la pantalla va a la pantalla "conexión con el servidor se ha restablecido".

¿Alguna idea?

Respuesta

4

Bueno, sin tener en cuenta el hecho de que intentar 100.000 solicitudes de cURL es una locura, probablemente esté alcanzando el límite de memoria.

Pruebe a establecer el límite de memoria a algo más razonable:

ini_set('memory_limit', '256M'); 

Y como propina lado, no establezca el tiempo de ejecución de algo absurdo, lo más probable es que finalmente va a encontrar una manera de llegar a ese con un script como este. ;]

En cambio, sólo configurarlo para 0, es funcionalmente equivalente a girar el límite de ejecución por completo:

ini_set('max_execution_time', 0); 
+0

sí, ahora veo que necesito aumentar el límite de memoria, pero ¿es esta una mala idea? – Mickey

+0

@John: Sí y no. No lo configure más alto de lo que lo necesita todo el tiempo, ya que evita que los errores de script se ejecuten para siempre. ¡Imagínese si apaga el limitador de tiempo de ejecución de scripts y el límite de memoria y accidentalmente ejecuta un script con un bucle infinito! Moraleja de la historia aquí: utilícela con moderación para situaciones como esta, donde nada más funcionaría si no fuera por escribirla para distribuirla o ejecutarla a lo largo del tiempo. Por cierto, el segundo comentario de Timdev sobre la configuración de un sistema de colas de trabajos, esa es realmente la manera de hacerlo. –

+0

Esta fue una mejor respuesta que la mía - Olvidé que podía anular 'memory_limit' usando' ini_set' – Josh

0

¿Qué hay en el error_log de apache? ¿Estás llegando al límite de la memoria?

EDITAR: Parece que está llegando al límite de memoria. ¿Tiene acceso a PHP.ini? Si es así, usted can raise the memory_limit there. De lo contrario, intente ejecutar binarios rizos o wget utilizando las funciones exec o shell_exec, de esa forma se ejecutan como procesos separados, sin utilizar la memoria de PHP.

+0

Sí. Soy un novato lo siento: Se ha agotado el tamaño de la memoria de 100663296 bytes (intenté asignar 2975389 bytes) – Mickey

+0

Esto podría sonar aún más noobish pero ¿no puedo simplemente ponerme o lavarlo en el script o en ciertas partes del mismo? – Mickey

+1

@John: No, el búfer es solo una parte de la memoria que se está utilizando. Las funciones cURL usan bastante memoria para ellos solos. –

0

100.000 solicitudes cURL ??? Estas loco. ¡Rompe esos datos!

+0

cada vez que el cliente agrega un nuevo MLS que tiene para obtener de 1000 a 10,000 listados, puedo obtener todos los listados en aproximadamente 5 solicitudes de cURL ... pero tengo que hacer 1 solicitud de cURL por listado para obtener las imágenes. – Mickey

+0

@John: ¿Qué tal escribir una clase entonces? que contiene la funcionalidad para recuperar un elemento a la vez. Podría recorrer todos los listados e instanciar la clase una vez para cada uno, asegurando en el proceso que cuando la clase se destruya, la memoria cURL también se libere. –

+0

@John: Básicamente , solo quiere asegurarse de que no está recuperando los mismos datos una y otra vez, desperdiciando ciclos y ancho de banda en el proceso. Configurando una cola de trabajos de alguna descripción, y almacenando cada página recuperada en un dato base, puede evitar esto fácilmente. –

3

Un montón de ideas:

1) No lo haga dentro de una petición HTTP. Escriba un script php de línea de comandos para conducirlo. Puede utilizar un script enlazado a la web para iniciarlo, si es necesario.

2) Debe ser capaz de establecer max_execution_time a cero (o llame set_time_limit (0)) para asegurarse de que no se apague por exceder un límite de tiempo

3) Parece que realmente quiere refactorizar esto en algo más sensato. Piense en configurar un pequeño sistema de cola de trabajos y tener un script php que obligue a varios niños a masticar todo el trabajo.

Como dice Josh, mira tu error_log y comprueba por qué te están cerrando ahora. Intenta calcular cuánta memoria estás usando, eso podría ser un problema. Intente establecer max_execution_time en cero. Quizás eso te lleve a donde necesitas estar rápidamente.

Pero a la larga, parece que tienes mucho trabajo por hacer dentro de una solicitud http. ¡Sacalo de http, divide y conquista!

+0

no sabía acerca de ese truco 0, es bueno saberlo. no estoy seguro de cómo hacer esto fuera de tenerlo en un script php. – Mickey

1

se puede establecer el tiempo de espera para ser indefinate modificando su php.ini y establecer la secuencia de comandos variable de ejecución

Pero es posible que también desee considerar un ligero cambio en la arquitectura. Primero considere un enfoque de "Lanzar y olvidar" para obtener 100.000 solicitudes curl. En segundo lugar, considere usar "wget" en lugar de curl.

Puede emitir un simple "wget URL -o UniqueFileName &" Esto recuperará una página web, la guardará en un nombre de archivo "único" y todo en segundo plano.

Luego puede iterar sobre un directorio de archivos, greping (preg_matching) data y hacer sus llamadas a bases de datos. Mueva los archivos mientras los procesa en un archivo y continúe iterando hasta que no haya más archivos.

Considere el directorio como una "cola" y tenga un solo proceso para procesar los archivos. Haga que un segundo proceso simplemente salga y tome datos de la página web. Podría agregar un tercer proceso que puede ser "monitor" que funciona de manera independiente y simplemente informa las estadísticas instantáneas. Los otros dos solo pueden ser "servicios web" sin interfaz.

Este tipo de multithreading es realmente poderoso y humildemente subutilizado en mi humilde opinión. Para mí, este es el verdadero poder de la web.

1

Tuve el mismo problema al obtener datos de MySQL vía PHP que contenían caracteres especiales como umlauts ä, ö, ü, ampersands etc. La conexión se restableció y no encontré errores en el registro de Apache ni en los registros de php. Primero me aseguré en PHP que accedí correctamente a los caracteres establecidos en el DB con:

mysql_query("SET NAMES 'latin1' COLLATE 'latin1_german2_ci'"); 

mysql_query("SET CHARACTER SET 'latin1'"); 

Then, finally, I resolved the problem with this line in PHP: 

mysql_query("SET character_set_connection='latin1'");