2011-03-13 15 views
5

Hola chicos, estoy configurando un clúster EC2 con un equilibrador de carga. Tengo un servidor de bases de datos separado que tiene mysql ejecutándose en él. Tengo 3 servidores web en ejecución, en su mayoría para alta disponibilidad, y por supuesto su equilibrio de carga round-robin parece, por lo que cada página que vaya a usted obtendrá un servidor diferente que perderá su sesión.PHP - Almacenamiento de sesión en una base de datos

Estoy tratando de configurar PHP para almacenarlo en la base de datos. Configuré una tabla y configuré todas las funciones (abrir, cerrar, etc.). y yo he puesto:

session_set_save_handler('_open', 
         '_close', 
         '_read', 
         '_write', 
         '_destroy', 
         '_clean'); 

Pero cuando me conecto o nada en el sitio que compruebe la mesa y nada se ha escrito. No estoy seguro si necesito cambiar algo en el archivo php.ini. Si es así, ¿cuál es el valor para cambiar?

Gracias!

EDIT: Funciones:

function _open(){  
    global $con; 
    connect(); 
} 

function _close(){ 
    global $con; 
    //mysql_close(); 
} 

function _read($id){  
    global $con;  
    $id = mysql_real_escape_string($id);  
    $sql = "SELECT data FROM sessions WHERE id = '$id'";  
    if ($result = mysql_query($sql, $con)) {   
     if (mysql_num_rows($result)) {    
      $record = mysql_fetch_assoc($result);    
      return $record['data'];   
     }  
    }  
    return ''; 
} 

function _write($id, $data) 
{ 
    global $con; 

    $access = time(); 

    $id = mysql_real_escape_string($id); 
    $access = mysql_real_escape_string($access); 
    $data = mysql_real_escape_string($data); 

    $sql = "REPLACE 
      INTO sessions 
      VALUES ('$id', '$access', '$data')"; 

    return mysql_query($sql, $con); 
} 

function _destroy($id) 
{ 
    global $con; 
    $id = mysql_real_escape_string($id); 
    $sql = "DELETE 
      FROM sessions 
      WHERE id = '$id'"; 
    return mysql_query($sql, $con); 
} 

function _clean($max) 
{ 
    global $con; 

    $old = time() - $max; 
    $old = mysql_real_escape_string($old); 

    $sql = "DELETE 
      FROM sessions 
      WHERE access < '$old'"; 

    return mysql_query($sql, $con); 
} 

session_set_save_handler('_open', 
         '_close', 
         '_read', 
         '_write', 
         '_destroy', 
         '_clean'); 
+0

¿Puedes publicar las funciones en cuestión? ¿Están en una clase, son funciones independientes, etc.? –

+0

Acabo de editar la publicación, gracias :) –

Respuesta

1

La función que está usando interrumpirá la función de sesión normal e inserte su código en acto, después llevar a cabo otras funciones internas.

En las funciones en las que realmente no está haciendo nada en la sesión (cosas como '_open' y '_close'), necesita devolver algo para llevar a cabo el comando o simplemente va a morir allí mismo.

Ejemplo:

function _open($save_path, $session_name){  
    global $con; 
    connect(); 

    return true; //Do nothing but carry on 
} 

function _close(){ 
    global $con; 
    //mysql_close(); 

    return true; //Do nothing but carry on 
} 
+0

Acabo de codificar esto. Todavía no funciona:/ –

+0

No creo que deba devolver los objetos de resultados de la consulta para '_write' y '_clean'. Intente reemplazarlos con return true. (Y mantenga el '_destroy' como está) –

+0

Todavía nada: '( –

0

Realmente esto no es la respuesta a su pregunta, pero si usted necesita realmente una alta disponibilidad que puede sugerir que el almacenamiento de sesiones en MySQL no es un buen método.

Una mejor práctica: ponga sus sesiones en Memcache. Servidor Memcache es fácil de instalar. El cliente de Memcache es fácil de instalar y el soporte de php almacena la sesión en memcache sin programación. Memcache almacena los datos en la memoria, no en el disco y es más rápido.

Aquí se puede ver un buen post sobre esto: http://kevin.vanzonneveld.net/techblog/article/enhance_php_session_management/

Suerte !!

+1

-1: Eso es totalmente no escalable. En un sitio web de alto tráfico, o bien comenzará a perder sesiones restantes y justo porque tocará el límite configurado de memcached, o tendrá que comprar más y más RAM a medida que sus sesiones concurrentes aumenten con su base de usuarios. La RAM no es barata. Por otro lado, los discos duros son ... –

+0

Esto es EC2 de lo que estamos hablando. Las pequeñas instancias de presupuesto son lo suficientemente potentes para alojar una instancia de memoria dedicada * dedicada * si al OP le preocupa la memoria en sus instancias principales. La memoria no es realmente un problema en este escenario específico. – Charles

+0

Memcache no es un reemplazo de una base de datos para sesiones. Es genial agregarlo como capa para el rendimiento, pero aún así debería estar escribiendo en una tienda más persistente y luego leer la tienda en caché. – davidjbullock

0

¿Cómo es que no puede usar las cookies? y simplemente haga que el script verifique si las cookies están presentes, luego lea los valores desde allí. A menos que la seguridad sea un problema. Sugiero cookies durante las sesiones para una escalabilidad económica. Escribir sesiones en la base de datos no será bueno y probablemente genere consultas costosas que se ejecutarán sin ningún motivo.

0

La mejor base de datos para sesiones va a ser algo así como Redis o MonogDB y no MySQL y no memcached. Puede usar memcached dependiendo de la cantidad de tráfico que obtenga, pero Redis o MongoDB es una base de datos mucho más escalable. Además, dado que está en EC2, es posible que desee ver Amazon SimpleDB. Es un almacén de claves/valores, por lo que debería prestarse bien para las sesiones.

Personalmente corrí con MongoDB porque no solo puedes almacenar tus sesiones allí, sino que puedes tomar lo que tienes de MySQL y almacenarlo allí también, así como almacenar otros datos en Mongo ... O simplemente pensar acerca de la conversión total de la base de datos de su sitio porque probablemente se enamore de MongoDB =)

También puede consultar la configuración de HAProxy en Cookies de aplicación. Eso también puede ayudarte.

Cuestiones relacionadas