Websites with a slightly larger size usually have several servers. each server runs modules with different functions and uses different second-level domain names. The User System of a website with a strong integrity is unified, that is, a user name and password can be used to log on to each module of the entire website.
I. problem origin
Websites with a slightly larger size usually have several servers. each server runs modules with different functions and uses different second-level domain names. The User System of a website with a strong integrity is unified, that is, a user name and password can be used to log on to each module of the entire website. Sharing user data between servers is easy to implement. you only need to set up a database server on the backend. each server can access user data through a unified interface. However, there is still a problem, that is, the user still needs to log on again after logging on to the server and entering another module of the server. this is a logon and all traffic problems, ing to the technology is actually a question about how each server shares SESSION data.
II. working principles of PHP sessions
Before solving the problem, let's take a look at the working principles of the php session. When a client (such as a browser) logs on to a website, you can use session_start () to open the SESSION on the Accessed PHP page, this will generate a unique session id of the client (this ID can be obtained/set through the session_id () function ). The session id can be retained on the client in two ways, so that the PHP program can obtain the session id of the client when requesting different pages; one is to automatically add the session id to the get url or the POST form. by default, the variable name is PHPSESSID, and the other is through COOKIE, save the session id in the COOKIE. by default, the COOKIE name is PHPSESSID. Here we mainly describe the COOKIE method, because it is widely used.
Where can SESSION data be stored? Of course, it is on the server side, but not stored in the memory, but saved in a file or database. By default, php. the SESSION storage method set in ini is files (session. save_handler = files), that is, SESSION data is saved by reading and writing files, and the SESSION file directory is saved by session. save_path is specified. the file name is prefixed with sess _ and followed by the session id. for example, sess_c000065af28a8b14c0fe11afe3b59b51b. The data in the file is the serialized SESSION data. If the traffic volume is large, many SESSION files may be generated. you can set a hierarchical directory to store SESSION files, which improves the efficiency. the setting method is session. save_path = "N;/save_path", where N is the classification level, and save_path is the start directory. When writing SESSION data, PHP will get the SESSION_ID of the client, and then find the corresponding SESSION file in the saved Directory of the specified SESSION file based on the session id. if the SESSION file does not exist, it will be created, finally, the data is serialized and written to the file. Reading SESSION data is a similar operation process. The read data needs to be deserialized to generate the corresponding SESSION variable.
III. main obstacles and solutions to multi-server SESSION sharing
By understanding the working principle of the SESSION, we can find that by default, each server generates a session id for the same client, for example, for the same user browser, the session id generated by server A is 30de1e9de3192ba6ce2992d27a1b6a0a, while that generated by server B is c000065af28a8b14c0fe11afe3b59b51b. In addition, the SESSION data of PHP is stored in the file system of the current server. As shown in:
After confirming the problem, you can start to solve it. To share SESSION data, you must achieve two goals: one is that the SESSION IDs generated by each server on the same client must be the same and can be transmitted through the same COOKIE, that is to say, each server must be able to read the same COOKIE named PHPSESSID; the other is the SESSION data storage method/location, which must be accessible to each server.
Simply put, multiple servers share the session id of the client, and must also share the SESSION data of the server.
The implementation of the first target is actually very simple. you only need to set the COOKIE domain. by default, the COOKIE domain is the domain name/IP address of the current server, if the domain is different, the cookies set by each server cannot access each other, for example
Www.aaa.com
The server cannot read/write
Www.bbb.com
The COOKIE set by the server. The servers of the same website have their own particularity, that is, they belong to the same level-1 domain, such as aaa.infor96.com and
Www.infor96.com
All belong to the domain .infor96.com, so we can set the COOKIE domain to .infor96.com, so that aaa.infor96.com and www.infor96.com can access this COOKIE. The setting method in PHP code is as follows:
('Session. cookie_domain ',' .infor96.com ');
?>
In this way, each server shares the same client session id.
The implementation of the second target can use the file sharing method, such as the NFS method, but the settings and operations are somewhat complicated. We can refer to the previous method of unified user system, that is, using a database to save SESSION data, so that each server can easily access the same data source and obtain the same SESSION data.
The solution is shown in:
IV. code implementation
CREATE a data TABLE. the SQL statement of MySQL is as follows: CREATE TABLE 'SS '(
'Sskey' varchar (32) not null default '',
'Expiry' bigint (20) not null default '0 ',
'Data' longtext not null,
Primary key ('sskey '),
KEY 'expiry' ('expiry ')
) ENGINE = MyISAM default charset = utf8 COLLATE = utf8_unicode_ci
Sesskey is the session id, expiry is the SESSION expiration time, and data is used to save SESSION data.
By default, SESSION data is saved as files. to save data as a database, you must redefine the processing functions of each SESSION operation. PHP provides
Session_set_save_handle ()
Function. you can use this function to customize the SESSION processing process. of course, you must first change session. save_handler to user, which can be set in PHP:
('User ');
?>
Next we will focus on the session_set_save_handle () function. this function has six parameters: session_set_save_handler (string open, string close, string read, string write, string destroy, string gc)
Each parameter is the function name of each operation. these operations are: open, close, read, write, destroy, and garbage collection. The PHP manual contains detailed examples. here we use the OO method to implement these operations. the detailed code is as follows:
('My _ SESS_TIME ', 3600); // SESSION survival duration
// Class definition
Class My_Sess
{
Function init ()
{
$ Domain = '.infor96.com ';
// Do not use the GET/POST variable method
Ini_set ('session. use_trans_sid ', 0 );
// Set the maximum time to live for garbage collection
Ini_set ('session. gc_maxlifetime ', MY_SESS_TIME );
// Use cookies to save SESSION IDs
Ini_set ('session. use_cookies ', 1 );
Ini_set ('session. cookie_path ','/');
// Multiple hosts share the COOKIE that saves the SESSION ID
Ini_set ('session. cookie_domain ', $ domain );
// Set session. save_handler to user instead of the default files
Session_module_name ('user ');
// Define the method name for each SESSION operation:
Session_set_save_handler (
Array ('My _ sess', 'open'), // corresponds to the static method My_Sess: open (), the same below.
Array ('My _ sess', 'close '),
Array ('My _ sess', 'read '),
Array ('My _ sess', 'write '),
Array ('My _ sess', 'deststroy '),
Array ('My _ sess', 'gc ')
);
} // End function
Function open ($ save_path, $ session_name ){
Return true;
} // End function
Function close (){
Global $ MY_SESS_CONN;
If ($ MY_SESS_CONN) {// Close the database connection
$ MY_SESS_CONN-> Close ();
}
Return true;
} // End function
Function read ($ sesskey ){
Global $ MY_SESS_CONN;
$ SQL = 'SELECT data FROM sess WHERE sesskey = '. $ MY_SESS_CONN-> qstr ($ sesskey).' AND expiry> = '. time ();
$ Rs = & $ MY_SESS_CONN-> Execute ($ SQL );
If ($ rs ){
If ($ rs-> EOF ){
Return ";
} Else {// read the SESSION data corresponding to the SESSION ID
$ V = $ rs-> fields [0];
$ Rs-> Close ();
Return $ v;
} // End if
} // End if
Return ";
} // End function
Function write ($ sesskey, $ data ){
Global $ MY_SESS_CONN;
$ Qkey = $ MY_SESS_CONN-> qstr ($ sesskey );
$ Expiry = time () + My_SESS_TIME; // Set the Expiration time
// Write the SESSION
$ Arr = array (
'Sskey' => $ qkey,
'Expiry' => $ expiry,
'Data' => $ data );
$ MY_SESS_CONN-> Replace ('sess', $ arr, 'sesskey', $ autoQuote = true );
Return true;
} // End function
Function destroy ($ sesskey ){
Global $ MY_SESS_CONN;
$ SQL = 'delete FROM sess WHERE sesskey = '. $ MY_SESS_CONN-> qstr ($ sesskey );
$ Rs = & $ MY_SESS_CONN-> Execute ($ SQL );
Return true;
} // End function
Function gc ($ maxlifetime = null ){
Global $ MY_SESS_CONN;
$ SQL = 'delete FROM sess WHERE expiry. time ();
$ MY_SESS_CONN-> Execute ($ SQL );
// Due to frequent deletion operations on the table sess, fragments are easily generated,
// Optimize the table in garbage collection.
$ SQL = 'optimize TABLE sess ';
$ MY_SESS_CONN-> Execute ($ SQL );
Return true;
} // End function
}///:~
// Use ADOdb as the database abstraction layer.
Require_once ('adodb/adodb. inc. php ');
// Database configuration items, which can be placed in the configuration file (for example, config. inc. php ).
$ Db_type = 'mysql ';
$ Db_host = '192. 168.212.1 ';
$ Db_user = 'sess _ user ';
$ Db_pass = 'sess _ pass ';
$ Db_name = 'sess _ db ';
// Create a database connection. this is a global variable.
$ GLOBALS ['My _ sess_conn'] = & ADONewConnection ($ db_type );
$ GLOBALS ['My _ sess_conn']-> Connect ($ db_host, $ db_user, $ db_pass, $ db_name );
// Initialize the SESSION settings, which must be run before session_start !!
My_Sess: init ();
?>
V. legacy issuesIf the website has a large access volume, the SESSION reads and writes the database frequently, which significantly reduces the efficiency. Considering that the SESSION data is generally not very large, you can try to write a multi-threaded program in C/Java, store SESSION data in HASH tables, and perform data read/write through socket communication, in this way, the SESSION will be stored in the memory, and the read/write speed should be much faster. In addition, server load balancing can be used to share the server load. However, these are just some of my own ideas and assumptions, and I have never put them into practice.