variable una session_destroy sesion recuperar inicializar ini_set destruir delete php performance zend-framework session profiling

una - session id() php



session_start() lleva MUCHO TIEMPO (8)

Acabo de tener este problema. session_start tardaba aproximadamente 5 segundos.

Mi problema era que había declarado algunas variables por encima.

Moví session_start a la parte superior y ahora toma unos pocos milisegundos.

Mi sitio funciona muy lentamente (y no tenía idea de por qué). Se basa en la aplicación Zend, solía hacer decenas de esos sitios, por lo que estoy seguro de que mi código es correcto.

Instalé xdebugger en el servidor, intenté perfilarlo y ¿adivinen qué? php :: session_start () tomó 48.675 segundos. Cuarenta y ocho segundos y medio! ¡Es increíble! ¿Cuál podría ser el motivo de esto? Es una operación común, ¿por qué podría ejecutarse TAN largo? Cómo solucionar ese comportamiento, ¿qué configuraciones editar? Busqué en Google, pero no encontré una buena respuesta (casi en todas partes hay una pregunta, pero no hay respuesta). Gracias antes!


En mi caso, era una configuración incorrecta del servidor de /etc/php.d/memcached.ini en /etc/php.d/memcached.ini Here hay información sobre las propiedades de Memcache y here se explica cómo configurar el almacenamiento en Memcache.


He tenido este problema y estoy sorprendido de que nadie haya publicado esta respuesta específica. Puede que no sea así, pero vale la pena verificarlo.

PHP bloquea el archivo de sesión mientras se está procesando una página, por lo que esa página puede tener acceso exclusivo a ella. Piénselo, el archivo sess_184c9aciqoc no es una base de datos, por lo que dos llamadas en la misma sesión no pueden acceder a él simultáneamente. Entonces, si tienes muchas llamadas ajax, puedes obtener un "atasco de tráfico". Una vez que comienzas a hacer secuencias de comandos avanzadas, tienes que tener cuidado con esto. por cierto, aquí hay una función para almacenar una matriz de marcas de tiempo. Lo usé para descubrir que el inicio de la sesión era el culpable:

//time function for benchmarking if( function_exists(''gmicrotime'')){ function gmicrotime($n=''''){ #version 1.1, 2007-05-09 //store array of all calls global $mT; list($usec, $sec) = explode('' '',microtime()); if(!isset($mT[''_base_'']))$mT[''_base_'']=$sec; $t=round((float)$usec + (float)(substr($sec,-4)),6); $mT[''all''][]=$t; if($n){ if(isset($mT[''indexed''][$n])){ //store repeated calls with same index. If in a loop, add a $i if needed if(is_array($mT[''indexed''][$n])){ $mT[''indexed''][$n][]=$t; }else{ $mT[''indexed''][$n]=array($mT[''indexed''][$n],$t); } }else $mT[''indexed''][$n]=$t; } //return elapsed since last call (in the local array) $u=$mT[''all'']; if(count($u)>1){ $mT[''_total_'']=$u[count($u)-1] - $u[0]; return round(1000*($u[count($u)-1]-$u[count($u)-2]),6); } } gmicrotime(''pageStart''); }

entonces llamo de la siguiente manera:

gmicrotime(''beforeSessionStart''); session_start(); gmicrotime(''afterSessionStart''); do_something_slow(); gmicrotime(''afterSlowProcess''); //etc.. echo ''<pre>''; print_r($mT);

Espero que esto sea útil!


Mi suposición sería la rutina de recolección de basura, que se ejecuta dentro de la función native session_start() . ¿Tal vez has hecho algo que mantiene muchos archivos de sesión antiguos, como cambiar el tiempo de vida máximo? ¿O tal vez ha decidido que sería una buena idea almacenarlos en una base de datos, pero olvidó crear un índice adecuado? El archivo nativo stat () de cada rutina de sesión de GC comprueba la caducidad. Esto lleva mucho tiempo si se crean muchos archivos.

editar : para ayudarlo solo con la depuración , deshabilite la recolección de elementos no utilizados estableciendo session.gc-probability :

session.gc-probability = 0

Asegúrate de que las configuraciones se mantengan, no sé lo que el framework zend podría estar haciendo aquí.

PD: es difícil sugerir una solución sin saber la causa. Mi respuesta está destinada a guiarlo hacia la identificación de la causa.


Otro enfoque podría ser que haya establecido un memory_limit grande en PHP.ini.

Lo hice para cargar enormes volcados de mysql en PHPMyAdmin y cargar el tiempo de carga, tal vez (como se dijo anteriormente) muchos archivos de sesión se acumularon ahora que PHP tenía espacio de sobra. El valor predeterminado es 128M , creo. Me había cuadruplicado eso.


Si tiene varias llamadas ajax concurrentes en la misma página, esta situación puede causar su problema.


Una forma de evitar este problema es pedirle a PHP que almacene sesiones en una tabla de base de datos en lugar de archivos.

En primer lugar, le daré algunos enlaces como créditos reales para esta solución:

http://www.tonymarston.net/php-mysql/session-handler.html

http://shiflett.org/articles/storing-sessions-in-a-database

http://culttt.com/2013/02/04/how-to-save-php-sessions-to-a-database/

Luego, una implementación de código que obtuve de estas lecturas:

<?php class TLB_Sessions_in_Database { private $debug; private $dbc; function __construct() { $this->debug = false; session_set_save_handler( array($this, ''_open''), array($this, ''_close''), array($this, ''_read''), array($this, ''_write''), array($this, ''_destroy''), array($this, ''_clean'') ); } function _open() { if( $this->debug ) echo ''_open:''.PHP_EOL; if( ($this->dbc = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD)) !== false ) { $select_db = mysql_select_db(DB_NAME, $this->dbc); $set_charset = mysql_set_charset(DB_CHARSET, $this->dbc); if( $this->debug ) echo ''- return: ''.(( $select_db && $set_charset ) ? ''true'' : ''false'').PHP_EOL; return( $select_db && $set_charset ); } else { if( $this->debug ) echo ''- error: ''.mysql_error($this->dbc).PHP_EOL; } return( false ); } function _close() { if( $this->debug ) echo ''_close:''.PHP_EOL; return( mysql_close($this->dbc) ); } function _read($session_id) { if( $this->debug ) echo ''_read:''.PHP_EOL; $session_id = mysql_real_escape_string($session_id); $sql = "SELECT `session_data` FROM `".DB_NAME."`.`php_sessions` WHERE `session_id` = ''".$session_id."''"; if( $this->debug ) echo ''- query: ''.$sql.PHP_EOL; if( ($result = mysql_query($sql, $this->dbc)) !== false ) { if( !in_array(mysql_num_rows($result), array(0, false), true) ) { $record = mysql_fetch_assoc($result); return( $record[''session_data''] ); } } else { if( $this->debug ) echo ''- error: ''.mysql_error($this->dbc).PHP_EOL; } return( '''' ); } function _write($session_id, $session_data) { if( $this->debug ) echo ''_write:''.PHP_EOL; $session_id = mysql_real_escape_string($session_id); $session_data = mysql_real_escape_string($session_data); //$sql = "REPLACE INTO `php_sessions` (`session_id`, `last_updated`, `session_data`) VALUES (''".$session_id."'', ''".time()."'', ''".$session_data."'')"; $sql = "INSERT INTO `".DB_NAME."`.`php_sessions` (`session_id`, `date_created`, `session_data`) VALUES (''".$session_id."'', NOW(), ''".$session_data."'') ON DUPLICATE KEY UPDATE `last_updated` = NOW(), `session_data` = ''".$session_data."''"; if( ($result = mysql_query($sql, $this->dbc)) === false ) { if( $this->debug ) echo ''- error: ''.mysql_error($this->dbc).PHP_EOL; } return( $result ); } function _destroy($session_id) { if( $this->debug ) echo ''_destroy:''.PHP_EOL; $session_id = mysql_real_escape_string($session_id); $sql = "DELETE FROM `".DB_NAME."`.`php_sessions` WHERE `session_id` = ''".$session_id."''"; if( ($result = mysql_query($sql, $this->dbc)) === false ) { if( $this->debug ) echo ''- error: ''.mysql_error($this->dbc).PHP_EOL; } return( $result ); } function _clean($max) { if( $this->debug ) echo ''_clean:''.PHP_EOL; $sql = ''DELETE FROM `''.DB_NAME.''`.`php_sessions` WHERE `last_updated` < DATE_SUB(NOW(), INTERVAL ''.$max.'' SECOND)''; if( ($result = mysql_query($sql, $this->dbc)) === false ) { if( $this->debug ) echo ''- error: ''.mysql_error($this->dbc).PHP_EOL; } return( $result ); } } new TLB_Sessions_in_Database();

FIN.


session_start (con sesiones almacenadas en archivos) está bloqueando en PHP, por lo que este problema aparecerá si intentas iniciar varias sesiones de servidor para la misma sesión del navegador (AJAX o varias pestañas / ventanas del navegador). Cada session_start esperará hasta que se cierren las otras sesiones.

Vea aquí: http://konrness.com/php5/how-to-prevent-blocking-php-requests/

Intente cambiar de archivos a almacenamiento de base de datos de sesiones.