PHP - 在数据库中存储会话

时间:2011-03-13 18:39:40

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

嘿伙计们,我正在建立一个带有负载均衡器的EC2集群。我有单独的DB服务器,上面运行了mysql。我有3个web服务器正在运行,主要是为了获得高可用性,当然它似乎是循环负载平衡,所以你去的每个页面都会得到一个不同的服务器,这会破坏你的会话。

我正在尝试设置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');

4 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:0)

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

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

在这里,您可以查看有关此内容的好文章:http://kevin.vanzonneveld.net/techblog/article/enhance_php_session_management/

运气!!

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

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