In-depth explanation of multi-server sharing of Memcache Session data

Source: Internet
Author: User

1. Introduction
1. Introduction to multi-server data sharing for memcache + memcache
, See http://www.guigui8.com/index.php/archives/206.html
2. session mechanism:
The session mechanism is a server-side mechanism. The server uses a structure similar to a hash (or a hash) to save information.
When the program needs to create a session for a client request, the server first checks whether the client's request contains a session ID called sessionid, if one sessionid is included, it indicates that a session has been created for this client before, and the server will retrieve and use the session according to the sessionid (if the session cannot be retrieved, a new one may be created ), if the client request does not contain the sessionid, the client creates a session and generates a sessionid associated with the session. The sessionid value should be unique, the sessionid is returned to the client for saving in this response.

The cookie can be used to save the sessionid. In this way, the browser can automatically display the ID to the server according to the Rules during the interaction process.

Generally, the cookie name is similar to SEEESIONID. For example, for the cookie generated by weblogic for web applications, PHPSESSID = ByOK3vjFD75aPnrF3K2HmdnV6QZcEbzWoWiBYEnLerj is named PHPSESSID.

Two motivations
In the actual web production environment, an application system usually distributes different business applications to different servers for processing.
When tracking the current online user information, if it is the same primary domain name, you can use global cookies to handle data sharing issues; if it is under different primary domains, the central concepts of the observer model can be used to solve the corresponding problems. There are many solutions that can be extended through this concept. What I want to talk about today is the previous one, the multi-server data sharing technology of memcache is used to simulate the session to share the current online user data among multiple servers.
The requirements for multi-server unified session are as follows:
1. The session information can be saved on several servers specified by memcached (through the multi-server data sharing of memcache described earlier );
2. You can use session_id ($ sessid) to customize the value of session_id, just like before zend's session_start.
3. During system operation, you can conveniently switch the session information stored in memcached and the session information stored in files.

Code 3
The implementation method is very simple. memcache is used to simulate the session mechanism. Instead, memcache is used to replace the storage medium with the memory of the Shared Server, so that multiple distributed deployed servers can share session information. The called interface is different from the session operation function provided by zend. Therefore, it is convenient to create and switch sessions in memcache and files.
The following code has been tested many times to meet the above functional requirements. Paste the following:

Copy codeThe Code is as follows :/**
* = --------------------------------------------------------------------------- =
* MemcacheSession. class. php
* = --------------------------------------------------------------------------- =
*
* Implement the Session Function Based on Memcache Storage
* (Simulate the session mechanism. Instead, use memcache to replace the storage medium with the memory of the Shared Server)
*
* Disadvantage: at present, no implementation policies are introduced for the session sharing mechanism of different primary domains. That is, only the implementation in the same primary domain is supported.
*
* Copyright (c) 2008 by guigui. All rights reserved.
* @ Author guigui <evan_gui@163.com>
* @ Version $ Id: MemcacheSession. class. php, v 1.0 2008/12/22 $
* @ Package en
* @ Link http://www.guigui8.com
*/

/**
* Class MemcacheSession
*
* 1. Set the Cookie on the client to save the SessionID.
* 2. Save the user data on the server and use the Session Id in the Cookie to determine whether the data is yours.
*/
Class MemcacheSession
{
// {Class member attribute Definition
Public $ memObject = null; // memcache operation object handle
Private $ _ sessId = '';
Private $ _ sessKeyPrefix = 'sess _';
Private $ _ sessExpireTime = 86400;
Private $ _ cookieDomain = '.guigui8.com'; // global cookie Domain Name
Private $ _ cookieName = '_ PROJECT_MEMCACHE_SESS ';
Private $ _ cookieExpireTime = '';

Private $ _ memServers = array ('192. 168.0.3 '=> 192, '192. 168.0.4' => 11211 );
Private $ _ sessContainer = array (); // session information of the current user
Private static $ _ instance = null; // This class is a singleton object.
//}}}

/**
* Static Method obtained by the singleton object.
* (Server parameters for storing memcache information can be provided by the way)
*
* @ Param string $ host-ip address of the memcache Data Storage Server
* @ Param integer $ port-memcache data storage server port number
* @ Param bool $ isInit-whether to start the Session when the object is instantiated
*/
Public static function getInstance ($ host = '', $ port = 11211, $ isInit = true ){
If (null = self: $ _ instance ){
Self: $ _ instance = new self ($ host, $ port, $ isInit );
}
Return self: $ _ instance;
}

/**
* Constructor
*
* @ Param bool $ isInit-whether to start the Session when the object is instantiated
*/
Private function _ construct ($ host = '', $ port = 11211, $ isInit = false ){
! Empty ($ host) & $ this-> _ memServers = array (trim ($ host) => $ port );
$ IsInit & $ this-> start ();
}

/**
* = ----------------------------------------------------------------------- =
* = ----------------------------------------------------------------------- =
* Public Methods
* = ----------------------------------------------------------------------- =
* = ----------------------------------------------------------------------- =
*/

/**
* Start the Session operation.
*
* @ Param int $ expireTime-Session expiration time. The default value is 0. The value is invalid when the browser is closed. The unit is seconds.
*/
Public function start ($ expireTime = 0 ){
$ _ SessId =$ _ COOKIE [$ this-> _ cookieName];
If (! $ _ SessId ){
$ This-> _ sessId = $ this-> _ getId ();
$ This-> _ cookieExpireTime = ($ expireTime> 0 )? Time () + $ expireTime: 0;
Setcookie ($ this-> _ cookieName, $ this-> _ sessId, $ this-> _ cookieExpireTime, "/", $ this-> _ cookieDomain );
$ This-> _ initMemcacheObj ();

$ This-> _ sessContainer = array ();
$ This-> _ saveSession ();
} Else {
$ This-> _ sessId =$ _ sessId;
$ This-> _ sessContainer = $ this-> _ getSession ($ _ sessId );
}
}

/**
* SetSessId
*
* Custom session id, which usually does not need to be processed by cookie operations (therefore, the cookie record session_id is omitted)
*
* @ Param string $ sess_id
* @ Return boolean
*/
Public function setSessId ($ sess_id ){
$ _ SessId = trim ($ sess_id );
If (! $ _ SessId ){
Return false;
} Else {
$ This-> _ sessId =$ _ sessId;
$ This-> _ sessContainer = $ this-> _ getSession ($ _ sessId );
}
}

/**
* Determine whether a Session variable is registered
*
* @ Param string $ varName-
* @ Return bool: returns true if no value exists. returns false if no value exists.
*/
Public function isRegistered ($ varName ){
If (! Isset ($ this-> _ sessContainer [$ varName]) {
Return false;
}
Return true;
}

/**
* Register a Session variable
*
* @ Param string $ varName-variable name to be registered as Session
* @ Param mixed $ varValue-register as the value of the Session variable
* @ Return bool-if the variable name already exists, false is returned. If the registration succeeds, true is returned.
*/
Public function set ($ varName, $ varValue ){
$ This-> _ sessContainer [$ varName] = $ varValue;
$ This-> _ saveSession ();
Return true;
}

/**
* Get a registered Session variable value
*
* @ Param string $ varName-name of the Session variable
* @ Return mixed-if a variable does not exist, false is returned. If a variable exists, the variable value is returned.
*/
Public function get ($ varName ){
If (! Isset ($ this-> _ sessContainer [$ varName]) {
Return false;
}
Return $ this-> _ sessContainer [$ varName];
}

/**
* Destroy a registered Session variable
*
* @ Param string $ varName-name of the Session variable to be destroyed
* @ Return bool return true if the destruction is successful
*/
Public function delete ($ varName ){
Unset ($ this-> _ sessContainer [$ varName]);
$ This-> _ saveSession ();
Return true;
}

/**
* Destroy all registered Session Variables
*
* @ Return returns true if the destruction is successful.
*/
Public function destroy (){
$ This-> _ sessContainer = array ();
$ This-> _ saveSession ();
Return true;
}

/**
* Get all Session Variables
*
* @ Return array-return the value of all registered Session variables.
*/
Public function getAll (){
Return $ this-> _ sessContainer;
}

/**
* Obtain the current Session ID.
*
* @ Return string obtains the SessionID.
*/
Public function getSid (){
Return $ this-> _ sessId;
}

/**
* Get the Memcache Server Information
*
* @ Return array Memcache configuration array information
*/
Public function getMemServers (){
Return $ this-> _ memServers;
}

/**
* Set Memcache Server Information
*
* @ Param string $ host-IP address of the Memcache Server
* @ Param int $ port-Memcache server port
*/
Public function setMemServers ($ arr ){
$ This-> _ memServers = $ arr;
}

/**
* Add a Memcache Server
*
* @ Param string $ host-IP address of the Memcache Server
* @ Param int $ port-Memcache server port
*/
Public function addMemServer ($ host, $ port ){
$ This-> _ memServers [trim ($ host)] = trim ($ port );
$ This-> memObject-> addServer ($ host, $ port );
}

/**
* Remove the Memcache server (note that this is only to remove the configuration and cannot be actually removed from the memcached connection pool)
*
* @ Param string $ host-IP address of the Memcache Server
* @ Param int $ port-Memcache server port
*/
Public function removeMemServer ($ host ){
Unset ($ this-> _ memServers [trim ($ host)]);
}

/**
* = ----------------------------------------------------------------------- =
* = ----------------------------------------------------------------------- =
* Private Methods
* = ----------------------------------------------------------------------- =
* = ----------------------------------------------------------------------- =
*/

/**
* Generate a Session ID
*
* @ Return string returns a 32-bit Session ID.
*/
Private function _ getId (){
Return md5 (uniqid (microtime ()));
}

/**
* Obtain a Session Key stored in Memcache.
*
* @ Param string $ _ sessId-whether to specify the Session ID
* @ Return string the Session Key obtained
*/
Private function _ getSessKey ($ _ sessId = ''){
$ SessKey = ($ _ sessId = '')? $ This-> _ sessKeyPrefix. $ this-> _ sessId: $ this-> _ sessKeyPrefix. $ _ sessId;
Return $ sessKey;
}
/**
* Check whether the path for storing Session data exists.
*
* @ Return bool success return true
*/
Private function _ initMemcacheObj (){
If (! Class_exists ('memcache') |! Function_exists ('memcache _ connect ')){
$ This-> _ showMessage ('failed': Memcache extension not install, please from http://pecl.php.net download and install ');
}
If ($ this-> memObject & is_object ($ this-> memObject )){
Return true;
}
$ This-> memObject = new Memcache;
If (! Empty ($ this-> _ memServers )){
Foreach ($ this-> _ memServers as $ _ host => $ _ port ){
$ This-> memObject-> addServer ($ _ host, $ _ port );
}
}

Return true;
}

/**
* Obtain the data in the Session file.
*
* @ Param string $ _ sessId-SessionId of the Session data to be obtained
* @ Return unknown
*/
Private function _ getSession ($ _ sessId = ''){
$ This-> _ initMemcacheObj ();
$ SessKey = $ this-> _ getSessKey ($ _ sessId );
$ SessData = $ this-> memObject-> get ($ sessKey );
If (! Is_array ($ sessData) | empty ($ sessData )){
// This must be $ _ COOKIE ['_ sesshandler'] error!
Return array ();
}
Return $ sessData;
}

/**
* Save the current Session data to Memcache.
*
* @ Param string $ _ sessId-Session ID
* @ Return returns true if return is successful.
*/
Private function _ saveSession ($ _ sessId = ''){
$ This-> _ initMemcacheObj ();
$ SessKey = $ this-> _ getSessKey ($ _ sessId );

If (empty ($ this-> _ sessContainer )){
$ Ret =@ $ this-> memObject-> set ($ sessKey, $ this-> _ sessContainer, false, $ this-> _ sessExpireTime );
} Else {
$ Ret =@ $ this-> memObject-> replace ($ sessKey, $ this-> _ sessContainer, false, $ this-> _ sessExpireTime );
}

If (! $ Ret ){
$ This-> _ showMessage ('failed': Save sessiont data Failed, please check memcache Server ');
}
Return true;
}

/**
* Display prompt information
*
* @ Param string $ strMessage-information to be displayed
* @ Param bool $ isFailed-whether it is a failure message. The default value is true.
*/
Private function _ showMessage ($ strMessage, $ isFailed = true ){
Return;
If ($ isFailed ){
Echo ($ strMessage );
}
Echo $ strMessage;
}

Application 4
1. Local session storage, the same as the original session operation method, has not changed.For example:Copy codeThe Code is as follows: session_start ();
$ _ SESSION ['file _ session_info '] = 'session information saved in the local file'; // session saved in the local file

2. session storage of the memcache Shared Server
Copy codeThe Code is as follows: $ mem = MemcacheSession: getInstance ('192. 168.0.4 ', 192 );
$ Mem-> addMemServer ('192. 168.0.4 ', 192 );
$ Mem-> addMemServer ('192. 168.0.5 ', 192 );
// If the cookie function is unavailable, set the ing to session_id based on the unique information passed by other parameters.
If (1 ){
$ Sn = '838ece1033bf7c7468e873e79ba2a3ec ';
$ Mem-> setSessId ($ sn );
}
$ Mem-> set ('name', 'guigui '); // sessions shared by multiple memcache servers
$ Mem-> set ('addr ', 'wuhan'); // sessions shared by multiple memcache servers
// $ Mem-> destroy ();

3. Obtain the session information stored locally and in memcache respectively.
Copy codeThe Code is as follows: $ addr = $ mem-> get ('addr ');
$ _ MEM_SESSION = $ mem-> getAll ();
Echo "Var_dump ($ _ SESSION );
Echo "Var_dump ($ _ MEM_SESSION );
// $ Res = $ mem-> delete ('name ');

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.