【问题标题】:PHP - Storing Session in a DatabasePHP - 在数据库中存储会话
【发布时间】:2011-07-14 13:44:18
【问题描述】:

我正在使用负载均衡器设置 EC2 集群。我有单独的数据库服务器,上面运行着 mysql。我有 3 个网络服务器正在运行,主要是为了实现高可用性,当然还有它看起来的循环负载平衡,所以你访问的每个页面都会得到一个不同的服务器,这会失去你的会话。

我正在尝试设置 PHP 以将其存储在数据库中。我已经设置了一个表,并设置了所有功能(打开、关闭等)。我已经设置:

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');

【问题讨论】:

  • 你能发布有问题的功能吗?它们是否在一个类中,它们是独立的函数,等等......
  • 刚刚编辑了帖子,谢谢:)

标签: php mysql apache amazon-ec2 load-balancing


【解决方案1】:

您正在使用的函数会中断正常的会话函数并插入您的代码以执行操作,然后继续执行其他内部函数。

在你实际上并没有在会话方面做任何事情的函数中(像'_open'和'_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
}

【讨论】:

  • 我认为您不需要返回“_write”和“_clean”的查询结果对象。尝试用 return true 替换它们。 (并保持 '_destroy' 的原样)
  • '_open' 也有两个变量:$save_path 和 $session_name。添加我上面的那些。
  • 还是什么都没有。我很沮丧......有没有像调试这样我可以看到到底发生了什么的地方??
  • 它都是基于标题的,所以你不能 var_dumping 你的东西。您可以尝试 var_export 或其他一些函数,并将所有输出路由到最后回显的全局字符串变量?不太确定,你已经对我对这个问题的大部分想法征税了。
【解决方案2】:

确实这不是您问题的答案,但如果您需要真正的高可用性,我可以建议将会话存储在 mysql 中不是一个好方法。

更好的做法:将会话放在内存缓存中。 Memcache 服务器很容易安装。 Memcache 客户端易于安装,php 支持将 session 存储在 memcache 中,无需编程!!! Memcache 将数据存储在内存中,而不是磁盘中,而且速度更快。

在这里你可以看到一篇关于这个的好帖子:http://kevin.vanzonneveld.net/techblog/article/enhance_php_session_management/

好运!!

【讨论】:

  • -1:这完全不可扩展。在高流量网站上,您将开始左右丢失会话,因为您将达到 memcached 配置的限制,或者您将不得不购买越来越多的 RAM,因为您的并发会话随着用户群的增加而增加。 RAM 并不便宜。另一方面,硬盘是...
  • 这就是我们所说的 EC2。如果 OP 担心他的主要实例中的内存,那么微小的预算实例足以托管一个 dedicated memcached 实例。在这种特定情况下,内存并不是真正的问题。
  • Memcache 不能替代会话数据库。添加作为性能层非常好,但您仍应写入更持久的存储,然后在缓存未命中时读取存储。
【解决方案3】:

为什么不能使用cookies?并且只需让脚本检查 cookie 是否存在,然后从那里读取值。除非安全是一个问题..我建议使用cookies而不是会话以获得廉价的可扩展性..在数据库中写入会话不会很好,并且可能会导致无缘无故运行昂贵的查询。

【讨论】:

    【解决方案4】:

    会话的最佳数据库将是 Redis 或 MonogDB 之类的,而不是 MySQL 和 memcached。您可以根据获得的流量使用 memcached,但 Redis 或 MongoDB 是一个更具可扩展性的数据库。此外,由于您使用的是 EC2,因此您可能需要查看 Amazon SimpleDB。它是一个键/值存储,因此它应该很适合会话。

    我个人会使用 MongoDB 运行,因为您不仅可以将会话存储在那里,而且您可以从 MySQL 中获取您所拥有的并将其缓存到那里以及在 Mongo 中存储其他数据......或者只是想一想完全转换您网站的数据库,因为您可能会爱上 MongoDB =)

    您还可以在应用程序 Cookie 下查看 HAProxy 的设置。这也可能对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多