PHP-在数据库中存储会话
我正在设置一个带有负载平衡器的EC2集群。我有一个单独的数据库服务器,上面运行着mysql。我有3台Web服务器在运行,主要是为了实现高可用性,当然,它的循环负载平衡似乎是这样的,所以您访问的每个页面都会得到一台不同的服务器,这会使您的会话中断 我正在尝试设置PHP以将其存储在DB中。我已经设置了一个表,并设置了所有功能(打开、关闭等)。我已经确定:PHP-在数据库中存储会话,php,mysql,apache,amazon-ec2,load-balancing,Php,Mysql,Apache,Amazon Ec2,Load Balancing,我正在设置一个带有负载平衡器的EC2集群。我有一个单独的数据库服务器,上面运行着mysql。我有3台Web服务器在运行,主要是为了实现高可用性,当然,它的循环负载平衡似乎是这样的,所以您访问的每个页面都会得到一台不同的服务器,这会使您的会话中断 我正在尝试设置PHP以将其存储在DB中。我已经设置了一个表,并设置了所有功能(打开、关闭等)。我已经确定: session_set_save_handler('_open', '_close',
session_set_save_handler('_open',
'_close',
'_read',
'_write',
'_destroy',
'_clean');
但是,当我登录或在网站上做任何事情时,我检查了表格,但什么都没有写。我不确定是否需要更改php.ini文件中的某些内容。如果是,更改的值是什么
谢谢
编辑:功能:
function _open(){
global $con;
connect();
}
function _close(){
global $con;
//mysql_close();
}
function _read($id){
global $con;
$id = mysql_real_escape_string($id);
$sql = "SELECT data FROM sessions WHERE id = '$id'";
if ($result = mysql_query($sql, $con)) {
if (mysql_num_rows($result)) {
$record = mysql_fetch_assoc($result);
return $record['data'];
}
}
return '';
}
function _write($id, $data)
{
global $con;
$access = time();
$id = mysql_real_escape_string($id);
$access = mysql_real_escape_string($access);
$data = mysql_real_escape_string($data);
$sql = "REPLACE
INTO sessions
VALUES ('$id', '$access', '$data')";
return mysql_query($sql, $con);
}
function _destroy($id)
{
global $con;
$id = mysql_real_escape_string($id);
$sql = "DELETE
FROM sessions
WHERE id = '$id'";
return mysql_query($sql, $con);
}
function _clean($max)
{
global $con;
$old = time() - $max;
$old = mysql_real_escape_string($old);
$sql = "DELETE
FROM sessions
WHERE access < '$old'";
return mysql_query($sql, $con);
}
session_set_save_handler('_open',
'_close',
'_read',
'_write',
'_destroy',
'_clean');
函数_open(){
全球$con;
connect();
}
函数_close(){
全球$con;
//mysql_close();
}
函数_read($id){
全球$con;
$id=mysql\u real\u escape\u字符串($id);
$sql=“从id=“$id”的会话中选择数据”;
如果($result=mysql\u查询($sql,$con)){
如果(mysql_num_rows($result)){
$record=mysql\u fetch\u assoc($result);
返回$record['data'];
}
}
返回“”;
}
函数_write($id,$data)
{
全球$con;
$access=time();
$id=mysql\u real\u escape\u字符串($id);
$access=mysql\u real\u escape\u string($access);
$data=mysql\u real\u escape\u字符串($data);
$sql=“替换
进入会议
值(“$id”、“$access”、“$data”)”;
返回mysql\u查询($sql,$con);
}
函数_销毁($id)
{
全球$con;
$id=mysql\u real\u escape\u字符串($id);
$sql=“删除
来自会话
其中id=“$id”;
返回mysql\u查询($sql,$con);
}
功能清洁($max)
{
全球$con;
$old=time()-$max;
$old=mysql\u real\u escape\u字符串($old);
$sql=“删除
来自会话
其中访问<'$old';
返回mysql\u查询($sql,$con);
}
会话设置保存处理程序(“打开”),
"关闭",,
"读",,
"写",,
"销毁",,
"清洁",;
您正在使用的功能将中断正常会话功能并插入代码以执行操作,然后继续执行其他内部功能
在函数中,如果您没有真正执行任何与会话相关的操作(例如“\u open”和“\u close”),则需要返回一些内容来执行命令,否则它将立即消失
例如:
function _open($save_path, $session_name){
global $con;
connect();
return true; //Do nothing but carry on
}
function _close(){
global $con;
//mysql_close();
return true; //Do nothing but carry on
}
实际上,这并不是你问题的答案,但是如果你真的需要高可用性,我可以建议在mysql中存储会话不是一个好方法 更好的做法是:将会话放在memcache中。Memcache服务器,易于安装。Memcache客户端易于安装,php支持在Memcache中存储会话,无需编程!!!Memcache将数据存储在内存中,而不是磁盘中,速度更快 在这里你可以看到一篇关于这方面的好文章:
祝你好运 为什么你不能用饼干?让脚本检查cookies是否存在,然后从那里读取值。除非安全是个问题。。我建议在会话上使用cookie,以实现廉价的可伸缩性。在数据库中写入会话将不太好,可能会导致无缘无故地运行昂贵的查询 会话的最佳数据库是Redis或MonogDB,而不是MySQL和memcached。您可以根据获得的流量使用memcached,但Redis或MongoDB是一个更具可伸缩性的数据库。另外,由于您使用的是EC2,您可能需要查看AmazonSimpleDB。它是一个键/值存储,因此它应该适合会话 我个人会使用MongoDB,因为您不仅可以将会话存储在那里,还可以将MySQL中的内容缓存在那里,并将其他数据存储在Mongo中……或者考虑将站点的数据库全部转换,因为您可能会爱上MongoDB=)
您还可以在应用程序Cookies下查看HAProxy的设置。这可能也会对您有所帮助。您可以发布有问题的函数吗?它们在一个类中吗,它们是独立的函数吗,等等…刚刚编辑了这篇文章,谢谢:)我认为您不需要为“\u write”和“\u clean”返回查询结果对象。尝试用return true替换它们。(并保持“_destroy”的原样)“_open”还接受两个变量:$save_path和$session_name。加上我上面提到的那些,还是什么都没有。我很沮丧。。。有没有类似的调试,我可以看到到底是怎么回事?它都是基于标题的,所以你不能随意丢弃你的东西。您可以尝试var_export或其他函数,并将所有输出路由到一个全局字符串变量,然后在结尾回显?不太确定,你已经把我的大部分想法都浪费在这个问题上了。在一个高流量的网站上,要么因为达到memcached配置的限制而开始左右丢失会话,要么随着concurrents会话数量的增加,您必须购买越来越多的RAM。RAM不便宜。另一方面,硬盘是……这是我们正在谈论的EC2。如果OP担心其主实例中的内存,那么这些小预算实例的功能足以承载一个专用的memcached实例。在这个特定的场景中,内存不是真正的问题。Memcache不是会话数据库的替代品。添加一个性能层很好,但是您仍然应该写入一个更持久的存储,然后在缓存未命中时读取存储。