Redis/Distributed File Storage System/database storage session solves session inconsistency in the Server Load balancer cluster, redissession

Source: Internet
Author: User

Redis/Distributed File Storage System/database storage session solves session inconsistency in the Server Load balancer cluster, redissession

Let's talk about the similarities and differences between sessions and cookies.

 

Session and cookie are not only stored on the server, but also stored on the client.

Although the session is stored on the server side, it also needs to match with the client. Imagine that the session of a browser is always the same (expiration or close is not counted), mainly because there is a cook on the browser side, the cookie named "PHPSESSID" contains a string. This string is used to indicate the session, when session is used, when the server finds this cookie, it will go to the session file storage directory on the server side to find the file named "sess_PHPSESSID value" (created if no cookie exists ), this file contains some session data (serialized data)

So, even if you delete this file, the next time you use session, it will re-create a file with the same name. Of course, if you delete the cookie, you have to rename it.

By default, sessions are stored in the local directory of each server, and corresponding configurations are available in 'php. ini '.

 

Server Configuration:

Session. save_handler = files (the default value is file, which defines the session storage method on the server. file means to save the sesion to a temporary file. If we want to save it in another way, for example, you need to set the database to 'user ')

 

Session. save_path = "D:/wamp/php/sessiondata/" (defines the location of the temporary file where the server stores the session)

 

Session. auto_start = 0 (if set to 1, you do not need to write session_start () in each file; session automatic start :)

 

Session. gc_probability = 1

Session. gc_divisor = 100

Session. gc_maxlifetime = 1440 (the above three garbage collection mechanisms constitute the session, session. gc_probability and session. gc_divisor constitutes the probability of executing session cleanup. Theoretically, the server periodically has a certain probability to call the gc function to clear the session. The probability of cleaning is: gc_probability/gc_divisor for example: 1/100 indicates that each new session is recycled by the garbage collection mechanism at initialization, And the cleanup standard is session. time defined by gc_maxlifetime)

 

Some client-related configurations

Session. use_cookies = 1, $ _ the COOKIE variable $ _ COOKIE ['phpsessionid'] exists.

 

Session. use_only_cookies = 1 (this is also the storage method used to define sessionid on the client. Setting 1 indicates that session IDs are only stored using cookies)

 

Session. use_trans_sid = 0 (corresponding to the above setting. If this parameter is set to 1, sessionid is allowed to be passed through the url parameter. Similarly, it is recommended to set it to 0, so here we will correct some questions about whether session can be used to disable cookies. The answer is, of course, if this value is set to 1)

 

Session. referer_check = (this setting is in session. use_trans_sid = 1 will take effect, the purpose is to check the "Referer" in the HTTP header to determine whether the session id contained in the URL is valid, HTTP_REFERER must contain the string specified by this parameter, otherwise, the session id in the URL is considered invalid. Therefore, the default value is null, that is, no check is performed)

 

Session. name = PHPSESSID (defines the name of sessionid, that is, the variable name, therefore, you can see PHPSESSID =################## in the http header file of the browser ##############)

 

Session. cookie_lifetime = 0 (the life cycle of the cookie file storing sessionid. If it is set to 0, the session ends, and sessionid disappears automatically. It is common to force the browser to close, the last sessionid will be lost)

 

Therefore, we can know from the above that the session is stored locally on each server by default, so if you want to use the session in the cluster environment, if you use the default configuration, there will be problems, that is, the session file of the client accessing server A exists on server A, but it may be allocated to the client server B later. In this case, the file on server B does not exist and the data will be lost.

 

In this case, the solution is to store the session on a separate server, either a database, redis, or a file server.

I will describe the settings here.

 

1. Use redis to store sessions

This is the simplest case. If you do not use a lot of people, you need to write a PHP class rule to store it. (You can also do this if you have special requirements)

First modify the php. ini configuration

session.save_handler = redissession.save_path = "tcp://127.0.0.1:6379"

Of course, you can also set it in the php Program

ini_set('session.save_handler','redis');ini_set('session.save_path','tcp://127.0.0.1:6379');

If you have configured a password in redis, you can set it like this.

session.save_handler = redissession.save_path = "tcp://127.0.0.1:6379?auth=authpwd"

 

Ii. Use the file server to store sessions

I think this is relatively simple. In my company, I directly mount the distributed file server to a specified directory, and then access the distributed file server, just like accessing a local folder. Here, I only need to set the storage path.

session.save_path = "xxxx"

 

3. Use a database to store sessions

This is a bit complex. You need to write a PHP class to specify how to open, read, write, destroy, recycle GC garbage, and disable it. However, I am not lazy, but I still want to manually write it.

<? Php class sessionHandler {/*** session database */const SESSION_DB = 'mytest';/*** session table */const SESSION_TABLE = 'session '; /*** @ var string $ _ dbHandler database link handle */private $ _ dbHandler;/*** @ var string $ _ dbHost Database Host */private $ _ dbHost; /*** @ var string $ _ dbUser database username */private $ _ dbUser;/*** @ var string $ _ dbUser Database Password */private $ _ dbPasswd; /*** @ var string $ _ name session name */pri Vate $ _ name; /*** constructor ** @ param string $ dbHost Database Host * @ param string $ dbUser database username * @ param string $ dbPasswd Database Password * @ return void */public function __ construct ($ dbHost, $ dbUser, $ dbPasswd) {$ this-> _ dbHost = $ dbHost; $ this-> _ dbUser = $ dbUser; $ this-> _ dbPasswd = $ dbPasswd ;} /*** link database * @ param string $ savePath storage path * @ param string $ name * @ return boolean */public function open ($ savePath, $ Name) {$ this-> _ dbHandler = mysql_connect ($ this-> _ dbHost, $ this-> _ dbUser, $ this-> _ dbPasswd); if (! $ This-> _ dbHandler) {return false;} $ this-> _ name = $ name; mysql_select_db (self: SESSION_DB, $ this-> _ dbHandler ); return true;}/*** read session * @ param string $ sessionId session id * @ return mixd returns an array; otherwise, it returns NULL */public function read ($ sessionId) {$ data = ''; $ SQL = sprintf ('select 'data' FROM '. self: SESSION_TABLE. 'Where 'id' = "% s" ', $ sessionId); $ result = mysql_query ($ SQL, $ this-> _ dbHandler ); If (mysql_num_rows ($ result) = 1) {list ($ data) = mysql_fetch_array ($ result, MYSQL_NUM);} return $ data ;} /*** link database * @ param string $ sessionId session id * @ param string $ data * @ return boolean */public function write ($ sessionId, $ data) {$ SQL = sprintf ('replace '. self: SESSION_TABLE. '('id', 'data', 'last _ Time') VALUES ("% s", "% s", % d)', $ sessionId, mysql_escape_string ($ data), tim E (); mysql_query ($ SQL, $ this-> _ dbHandler); return mysql_affected_rows ($ this-> _ dbHandler)> 0 ;} /*** link database * @ param int $ expire lifecycle * @ return boolean */public function gc ($ expire) {$ SQL = sprintf ('delete FROM ''. self: SESSION_TABLE. ''where 'last _ time' <NOW ()-% d', $ expire); mysql_query ($ SQL, $ this-> _ dbHandler ); return mysql_affected_rows ($ this-> _ dbHandler)> 0;}/*** close database link * @ pa Ram void * @ return boolean */public function close () {return mysql_close ($ this-> _ dbHandler );} /*** destroy session * @ param string $ sessionId * @ return boolean */public function destroy ($ sessionId) {$ SQL = sprintf ('delete FROM ''. self: SESSION_TABLE. ''where 'id' = "% s" ', $ sessionId); mysql_query ($ SQL, $ this-> _ dbHandler); $ _ SESSION = array (); return mysql_affected_rows ($ this-> _ dbHandler)> 0 ;}} $ SessionHandler = new sessionHandler ('localhost', 'root', '123abc + '); session_set_save_handler (array ($ sessionHandler, 'open'), array ($ sessionHandler, 'close'), array ($ sessionHandler, 'read'), array ($ sessionHandler, 'write'), array ($ sessionHandler, 'deststroy'), array ($ sessionHandler, 'gc');/* in PHP 5.0.5, the write and close callback functions are called only after the object is destroyed. Therefore, objects cannot be used in these two callback functions, you cannot throw an exception. If an exception is thrown in a function, PHP will neither capture it nor trace it. This will cause the program to terminate unexpectedly. However, object destructor can use sessions. You can call the session_write_close () function in the destructor to solve this problem. But registering the shutdown callback function is more reliable */register_shutdown_function ('session _ write_close '); session_start (); $ _ session ['test'] = 'a ';

Create a table named session. Remember to create a database named 'mytest'. The session table has three fields.

Primary Key of id vchar (100) primary sessionid

Data vchar (1000) data content (serialized)

Last_time int (10) Last modified Timestamp

 

The contents in the table are found after running.

As you can see, this method of customizing sessions by code can be applied not only to databases, but also to other applications, such as files and redis.

 

 

So far, the principle of session, how to customize session storage, and how to use the session in the cluster have been completed.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.