会否是你测试的问题。
共有6次对index.php的请求:
第一次, 初始化session_id cookie.
但当第二次第三次,很可能第一次服务器还没来得及响应,请求就已经发出。而此时session_id cookie还未设置,于是再度初始化session_id cookie。
这样第一次请求设置的session_id cookie就被覆盖了,数据也就没法读出来了
共有6次对index.php的请求:
第一次, 初始化session_id cookie.
但当第二次第三次,很可能第一次服务器还没来得及响应,请求就已经发出。而此时session_id cookie还未设置,于是再度初始化session_id cookie。
这样第一次请求设置的session_id cookie就被覆盖了,数据也就没法读出来了
现在不说session,就是直接去用memcache的set方法,也有数据丢失。
代码如下
<?php
$mem = new Memcache;
$mem->connect("192.168.234.234",11211);
$Method = $_GET['method']."|";
if($mem->get('key')){
$aa = $mem->get('key');
$mem->set('key',$aa.$Method,0,60);
}else{
$mem->set('key',$Method,0,60);
}
$val = $mem->get('key');
?>
问题我公司里的2台memcache都存在这个问题。
而且这个丢失很容易重现。
我怀疑是不是memcache或PHP配置的有问题# Controls IP packet forwarding
net.ipv4.ip_forward = 0# Controls source route verification
net.ipv4.conf.default.rp_filter = 1# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0# Controls whether core dumps will append the PID to the core filename
# Useful for debugging multi-threaded applications
kernel.core_uses_pid = 1# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1# Controls the maximum size of a message, in bytes
kernel.msgmnb = 65536# Controls the default maxmimum size of a mesage queue
kernel.msgmax = 65536# Controls the maximum shared segment size, in bytes
kernel.shmmax = 4294967295# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 268435456这是memcache的sysctl.conf文件的内容。默认的。没动过
麻烦memcache玩的熟的人给指点下。
写后要校对,至少要有CRC校验
在这个层面上,你不应该相信任何人我们在讨论的代码,都是原理性代码,实际使用时都是要另加判错的
就说 memcache 也只是给你一个通讯的环境并不是简单的几行代码就能解决问题的
软件开发就是不断地发现问题和解决问题,一旦不需要维护了,那么这个软件就快要寿终正寝了
我在memcache里遍历了数据,确实是没有写进去。并不是没读出来。
不过我没用过,只是一直耳闻是memcache的替代品
2两台都有问题,可以检查一下代码。先别用memcache,用mysql实现了。换之前,在实现session的函数中,都把数据写到一个文件中,检查一下。
3使用tcpdump,检查一下请求是否发过了。要是还是不行。改下memcache吧,也是跟踪变量。(感谢上天,我暂时没这需求)。我用的方法比较笨,希望对你有点启发。
看你程序你想要的结果123456.
js是顺利加载。应该没并发的问题吧。你检查数据的时候,主要检查一下sessionid
失效时间为60秒你可以把60值修改为更大。
应该是并发写的问题。我把每次请求后生成的SESSION都写入到数据库以后发现,SESSION存的值经常就被重写了,而不是在后面追加的。
下面这是按我贴出的测试代码进行的一次测试结果。我在上面的代码后面加了写入数据库的操作。可以看出第一个先到的请求是4,SESSION的值被写成了4,第二个是5,session本应该是45,却被直接写成了5,请求值 请求时间 session_id 当前生成的SESSION值
"4",1334029029,"7j1jcsdkv583cb60nb3kfemnd6","4"
"5",1334029029,"7j1jcsdkv583cb60nb3kfemnd6","5"
"6",1334029029,"7j1jcsdkv583cb60nb3kfemnd6","6"
"2",1334029029,"7j1jcsdkv583cb60nb3kfemnd6","2"
"1",1334029029,"7j1jcsdkv583cb60nb3kfemnd6","1"
"3",1334029029,"7j1jcsdkv583cb60nb3kfemnd6","43"
测试完成成功。memcache_session.php (摘自http://imysql.cn/?q=node/215)<?php
//设定 SESSION 有效时间,单位是 秒
define('SESS_LIFTTIME', 3600);//定义memcache配置信息
define('MEMCACHE_HOST', 'localhost');
define('MEMCACHE_PORT', '11211');if (!defined('MemcacheSession'))
{
define('MemcacheSession', TRUE);class MemacheSession
{ // {{{ 类成员属性定义
static $mSessSavePath;
static $mSessName;
static $mMemcacheObj;
// }}} // {{{ 初始化构造函数
/**
* 构造函数
*
* @param string $login_user 登录用户
* @param int $login_type 用户类型
* @param string $login_sess 登录Session值
* @return Esession
*/
public function __construct()
{
//我的memcache是以php模块的方式编译进去的,可以直接调用
//如果没有,就请自己包含 Memcache-client.php 文件
if (!class_exists('Memcache') || !function_exists('memcache_connect'))
{
die('Fatal Error:Can not load Memcache extension!');
} if (!empty(self::$mMemcacheObj) && is_object(self::$mMemcacheObj))
{
return false;
} self::$mMemcacheObj = new Memcache; if (!self::$mMemcacheObj->connect(MEMCACHE_HOST , MEMCACHE_PORT))
{
die('Fatal Error: Can not connect to memcache host '. MEMCACHE_HOST .':'. MEMCACHE_PORT);
} return TRUE;
}
// }}} /** {{{ sessOpen($pSavePath, $name)
*
* @param String $pSavePath
* @param String $pSessName
*
* @return Bool TRUE/FALSE
*/
public function sessOpen($pSavePath = '', $pSessName = '')
{
self::$mSessSavePath = $pSavePath;
self::$mSessName = $pSessName; return TRUE;
}
// }}} /** {{{ sessClose()
*
* @param NULL
*
* @return Bool TRUE/FALSE
*/
public function sessClose()
{
return TRUE;
}
// }}} /** {{{ sessRead($wSessId)
*
* @param String $wSessId
*
* @return Bool TRUE/FALSE
*/
public function sessRead($wSessId = '')
{
$wData = self::$mMemcacheObj->get($wSessId); //先读数据,如果没有,就初始化一个
if (!empty($wData))
{
return $wData;
}
else
{
//初始化一条空记录
$ret = self::$mMemcacheObj->set($wSessId, '', 0, SESS_LIFTTIME); if (TRUE != $ret)
{
die("Fatal Error: Session ID $wSessId init failed!"); return FALSE;
} return TRUE;
}
}
// }}} /** {{{ sessWrite($wSessId, $wData)
*
* @param String $wSessId
* @param String $wData
*
* @return Bool TRUE/FALSE
*/
public function sessWrite($wSessId = '', $wData = '')
{
$ret = self::$mMemcacheObj->replace($wSessId, $wData, 0, SESS_LIFTTIME); if (TRUE != $ret)
{
die("Fatal Error: SessionID $wSessId Save data failed!"); return FALSE;
} return TRUE;
}
// }}} /** {{{ sessDestroy($wSessId)
*
* @param String $wSessId
*
* @return Bool TRUE/FALSE
*/
public function sessDestroy($wSessId = '')
{
self::sessWrite($wSessId); return FALSE;
}
// }}} /** {{{ sessGc()
*
* @param NULL
*
* @return Bool TRUE/FALSE
*/
public function sessGc()
{
//无需额外回收,memcache有自己的过期回收机制 return TRUE;
}
// }}} /** {{{ initSess()
*
* @param NULL
*
* @return Bool TRUE/FALSE
*/
public function initSess()
{
$domain = '.imysql.cn';
//不使用 GET/POST 变量方式
ini_set('session.use_trans_sid', 0); //设置垃圾回收最大生存时间
ini_set('session.gc_maxlifetime', SESS_LIFTTIME); //使用 COOKIE 保存 SESSION ID 的方式
ini_set('session.use_cookies', 1);
ini_set('session.cookie_path', '/'); //多主机共享保存 SESSION ID 的 COOKIE
ini_set('session.cookie_domain', $domain); //将 session.save_handler 设置为 user,而不是默认的 files
session_module_name('user'); //定义 SESSION 各项操作所对应的方法名:
session_set_save_handler(
array('MemacheSession', 'sessOpen'), //对应于静态方法 My_Sess::open(),下同。
array('MemacheSession', 'sessClose'),
array('MemacheSession', 'sessRead'),
array('MemacheSession', 'sessWrite'),
array('MemacheSession', 'sessDestroy'),
array('MemacheSession', 'sessGc')
); session_start(); return TRUE;
}}//end class}//end define$memSess = new MemacheSession;
$memSess->initSess();
?>memcache_test.php
<?phprequire 'memcache_session.php';$method = $_GET['Method'];
if(isset($_SESSION['Method'])){
$_SESSION['Method'] = $_SESSION['Method'].$method;
}else{
$_SESSION['Method'] =$method;
}echo "var test={$_SESSION['Method']}";
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
</head>
<script type="text/javascript" src="http://localhost/session/session_test.php?Method=1" reload="1"></script>
<script type="text/javascript" src="http://localhost/session/session_test.php?Method=2" reload="1"></script>
<script type="text/javascript" src="http://localhost/session/session_test.php?Method=3" reload="1"></script>
<script type="text/javascript" src="http://localhost/session/session_test.php?Method=4" reload="1"></script>
<script type="text/javascript" src="http://localhost/session/session_test.php?Method=5" reload="1"></script>
<script type="text/javascript" src="http://localhost/session/session_test.php?Method=6" reload="1"></script>
<body>
</body>
</html>