Red de conocimiento informático - Material del sitio web - Cómo compartir datos de SESIÓN en múltiples servidores web

Cómo compartir datos de SESIÓN en múltiples servidores web

1. Origen del problema

Los sitios web un poco más grandes suelen tener varios servidores, cada servidor ejecuta módulos con diferentes funciones. utilizado, pero para un sitio web completo, el sistema de usuario está unificado, es decir, se puede iniciar sesión y utilizar un conjunto de nombres de usuario y contraseñas en cada módulo de todo el sitio web

. Es relativamente fácil para cada servidor compartir datos de usuario. Solo necesita colocar un servidor de base de datos en el back-end y cada servidor puede acceder a los datos de usuario a través de una interfaz unificada. Pero todavía hay un problema, es decir, después de iniciar sesión en este servidor, los usuarios aún deben iniciar sesión nuevamente cuando ingresan a otros módulos de otro servidor. Este es un inicio de sesión único y todos los problemas comunes se asignan a la tecnología. De hecho, se trata de cómo compartir datos de SESIÓN entre servidores.

2. Cómo funciona PHP SESSION

Antes de resolver el problema, primero comprendamos

Cómo funciona PHP SESSION. Cuando el cliente (como un navegador) inicia sesión en el sitio web, la página PHP visitada puede usar session_start() para abrir

SESSIÓN, lo que generará la ID de SESIÓN de identificación única del cliente (esta ID se puede pasar a través de la función session_id() get/set). El ID de SESIÓN

se puede retener en el cliente de dos maneras, de modo que al solicitar diferentes páginas, el programa PHP pueda aprender el ID de SESIÓN del cliente. Una es agregar automáticamente el ID de SESIÓN

<; p> A la URL GET (esto sólo se puede lograr en sistemas Unix, los sistemas Windows no pueden agregarla automáticamente a la URL), o al formulario POST

De forma predeterminada, el nombre de la variable es PHPSESSID; other El primer método es guardar el ID de SESIÓN en COOKIE

a través de COOKIE. Por defecto, el nombre de esta COOKIE es PHPSESSID. Aquí utilizamos principalmente el método COOKIE para explicarlo, porque se usa ampliamente.

Entonces, ¿dónde se almacenan los datos de la SESIÓN? Por supuesto, están en el lado del servidor, pero no se almacenan en la memoria, sino en un archivo o base de datos. De forma predeterminada, el método para guardar la SESIÓN establecido en php.ini es

files(session.save_handler = files), es decir, la lectura y escritura de archivos se usa para guardar los datos de la SESIÓN y el directorio donde están los archivos de la SESIÓN. Lo guardado se controla mediante la sesión. Se especifica save_path, el nombre del archivo tiene el prefijo

sess_, seguido del ID de SESIÓN, como por ejemplo: sess_c72665af28a8b14c0fe11afe3b59b51b. Los datos del archivo son los datos de la SESIÓN después de la serialización. Si el número de visitas es grande, se pueden generar más archivos SESSION. En este caso, puede configurar un directorio jerárquico para guardar archivos SESSION, lo que mejorará mucho la eficiencia. El método de configuración es: session.save_path="N. ;/ save_path", N es el número de niveles jerárquicos

y save_path es el directorio inicial. Al escribir datos de SESSION, PHP obtendrá el SESSION_ID del cliente y luego usará este ID de SESSION para encontrar el archivo SESSION correspondiente en el directorio para guardar el archivo SESSION especificado. Si no existe, créelo Los datos se escriben en el archivo después de la serialización. .

Leer datos de SESSION es un proceso de operación similar. Los datos leídos deben deserializarse y generar la variable SESSION correspondiente.

3. Los principales obstáculos y soluciones para compartir SESSION entre múltiples servidores

 

Al comprender el principio de funcionamiento de SESSION, podemos encontrar que, de forma predeterminada, En esta situación, cada servidor generará un ID de SESIÓN

para el mismo cliente respectivamente. Por ejemplo, para el mismo navegador de usuario, el ID de SESIÓN generado por el servidor A es 30de1e9de3192ba6ce2992d27a1b6a0a, mientras que el servidor B

.

El generado es c72665af28a8b14c0fe11afe3b59b51b. Además, los datos de SESIÓN

de PHP se almacenan por separado en el sistema de archivos de este servidor.

Después de identificar el problema, puedes empezar a solucionarlo. Si desea compartir datos de SESIÓN, debe lograr dos objetivos:

Uno es que el ID de SESIÓN generado por cada servidor para el mismo cliente debe ser el mismo y se puede pasar a través de la misma COOKIE. es decir, cada servidor debe poder leer la misma COOKIE llamada PHPSESSID;

La otra es que el método de almacenamiento/ubicación de los datos de la SESIÓN debe garantizar que cada servidor pueda acceder a ellos. En pocas palabras, varios servidores deben compartir el ID de SESIÓN del cliente y también deben compartir los datos de SESIÓN

del servidor.

La realización del primer objetivo es realmente muy simple. Solo necesita configurar especialmente el dominio de la COOKIE. De forma predeterminada, el dominio de la COOKIE es el nombre de dominio/dirección IP del servidor actual. y Si los dominios son diferentes las COOKIES configuradas por cada servidor no pueden acceder entre sí.

4. Implementación del código

Primero cree la tabla de datos. La declaración SQL de MySQL es la siguiente:

CREATE TABLE `sess` (

` sesskey` varchar(32) NOT NULL predeterminado '',

`expiry` bigint(20) NOT NULL predeterminado '0',

`data` longtext NOT NULL ,

CLAVE PRIMARIA (`sesskey`), LLAVE `expiry` (`expiry`)

) TYPE=MyISAM

sesskey es el ID de SESIÓN, vencimiento es el tiempo de vencimiento de la SESIÓN, los datos se utilizan para guardar los datos de la SESIÓN.

De forma predeterminada, los datos de SESSION se guardan en modo archivo. Si desea guardarlos en modo de base de datos, debe redefinir las funciones de procesamiento de cada operación de SESSION.

PHP proporciona la función session_set_save_handle()

. Puede usar esta función para personalizar el proceso de procesamiento de SESSION. Por supuesto, primero debe cambiar session.save_handler a usuario, que se puede configurar en PHP: session_module_name('. user' );

A continuación, centrémonos en la función session_set_save_handle(),

 

Esta función tiene seis parámetros: session_set_save_handler (cadena abierta, cadena cerrada, cadena

lectura, escritura de cadena, destrucción de cadena, gc de cadena) Cada parámetro es el nombre de la función de cada operación. Estas operaciones están en orden:

Abrir, cerrar, leer, escribir. destruir, recolección de basura.

Hay ejemplos detallados en el manual de PHP.

Aquí usamos OO para implementar estas operaciones. El código detallado es el siguiente:

define('MY_SESS_TIME', 3600); SESIÓN Duración

//Definición de clase

clase My_Sess

{

/**

* Conexión a base de datos El objeto está configurado como una variable estática. Debido a que no está configurado como una variable estática, el objeto de conexión de la base de datos no se puede llamar con otros métodos. No está claro por qué.

*

* @var obj

*/

static public $db;

/**

* Constructor

*

* @param obj $dbname objeto de conexión de base de datos

*/

función __construct($dbname){

self ::$db = $dbname;

}

/**

* Inicialice la sesión, use la base de datos mysql para almacenar el valor de la sesión y use el método session_set_save_handler para implementarlo

*

*/

función init()

{

$ domain = '';

//No utilizar el método de variable GET/POST

ini_set('session.use_trans_sid', 0);

//Establecer el tiempo máximo de vida útil de la recolección de basura

ini_set('session.gc_maxlifetime', MY_SESS_TIME);

//Cómo usar COOKIE para guardar el ID de SESIÓN

ini_set( 'session.use_cookies', 1);

ini_set('session.cookie_path','/');

//Varios hosts comparten la COOKIE que guarda el ID de SESIÓN. Estoy probando en un servidor local, configuré $domain=''

ini_set('session.cookie_domain',$domain);

//Establecí session.save_handler como usuario en su lugar de los archivos predeterminados

session_module_name( 'user');

//Definir los nombres de los métodos correspondientes a varias operaciones SESSION

session_set_save_handler(

array('My_Sess', 'open') , ​​//corresponde al método open() de la clase My_Sess, lo mismo a continuación.

array('Mi_Sesión','cerrar'),

array('Mi_Sesión','leer'),

array('Mi_Sesión',' escribir'),

array('My_Sess', 'destroy'),

array('My_Sess', 'gc')

); p>

//session_start() debe ubicarse después del método session_set_save_handler

session_start();

}

función open($save_path , $session_name) {

//print_r($sesskey);

return true;

} //finalizar función

función close(){

if(self::$db){

self::$db-gt();

}

devuelve verdadero;

}

función de lectura($sesskey) {

$sql = 'SELECCIONAR `datos` DE `sess` DONDE ` sesskey`=' . (self::$db-gt; qstr($sesskey)) ' AND `expiry`gt;=' . -gt;ejecutar ($sql);

si($rs){

si($rs-gt;EOF){

return '';

} else {//Leer datos de SESIÓN correspondientes al ID de SESIÓN

$v = $rs-gt; campos[0];

$rs-gt ; cerrar();

devolver $v;

}

}

devolver '';

}

función escribir($sesskey, $data){

$qkey = $sesskey;

$expiry = time() MY_SESS_TIME;

$arr = array(

'sesskey' =gt; $qkey,

'expiry' =gt; $expiry,

'datos' = gt; $datos);

self::$db-gt;replace('sess', $arr, 'sesskey', verdadero);

devuelve verdadero;

}

función destruir($sesskey) {

$sql = 'BORRAR DE `sess` DONDE `sesskey`='.self::$db-gt ; qstr($sesskey);

$rs =self::$db-gt;execute($sql);

devuelve verdadero;

}< / p>

función gc($maxlifetime = null) {

$s

ql = 'BORRAR DE `sess` DONDE `expiry`lt;'.time();

self::$db-gt;execute($sql);

// Debido a las frecuentes operaciones de eliminación en la tabla sess, es probable que se produzca fragmentación.

//Por lo tanto, la tabla se optimiza durante la recolección de basura.

$sql = 'OPTIMIZAR TABLA `sess`';

self:: $db-gt; Ejecutar($sql); /p>

}

}

//Utilice ADOdb como capa de abstracción de la base de datos.

require_once('adodb/adodb.inc.php');

// Los elementos de configuración de la base de datos se pueden colocar en el archivo de configuración (como: config.inc.php).

$db_type = 'mysql';

$db_host = '127.0.0.1'

$db_user = 'raíz'; >$db_pass = '111';

$db_name = 'sess_db';

//Crear una conexión a la base de datos.

$cnn=amp; ADONewConnection($db_type);

$cnn-gt; $db_host, $db_user, $db_pass, $db_name; p>//Inicializa la configuración de SESSION, session_start() ya está incluida durante la inicialización.

$sess = new My_Sess($cnn);

$sess-gt;init();

$_SESSION['a']='aaa';

$_SESSION['b']='bbb'; ']='ccc';

print_r($_SESSION); gt;

5. Cuestiones pendientes Si el sitio web tiene un gran número de visitas, la lectura y escritura de SESSION será necesaria. Con frecuencia La base de datos se opera, por lo que la eficiencia se reducirá significativamente. Teniendo en cuenta que los datos de la SESIÓN generalmente no son muy grandes, puede intentar escribir un programa de subprocesos múltiples en C/Java, usar una tabla HASH para guardar los datos de la SESIÓN y leer y escribir datos a través de la comunicación de socket, de modo que se guarde la SESIÓN. En la memoria, la lectura y la escritura deberían ser mucho más rápidas. Además, la carga del servidor también se puede compartir

mediante el equilibrio de carga.