我正在开发一个网站。目前,我正在使用cheapo共享主机。但是一个男孩可以做梦,而且我已经在思考我网站上有大量用户会发生什么。
访问者将需要偶尔进行数据库写入,因为他们会记录他们在网站游戏中的进度。
我想通过将进度和其他信息直接写入$_SESSION
变量来最小化查询。只有当会话被销毁(注销,浏览器关闭或超时)时,我才想将$_SESSION
的内容写入数据库。
问题:
这可能吗?当会话被超时或关闭浏览器销毁时,有没有办法执行函数?
这是否明智?几百个并发SQL查询对于共享服务器来说是一个问题,并且使用$_SESSION
作为缓冲区来减轻其中的一部分。
答案 0 :(得分:6)
当会话被销毁时,有没有办法执行函数 超时或关闭浏览器?
是的,但它可能不会像你想象的那样起作用。您可以使用session_set_save_handler
定义自己的自定义会话处理程序,部分定义是提供destroy
和gc
回调函数。当会话被明确销毁并且由于已经过期而被销毁时,会调用这两个,因此它们完全按照您的要求执行。
然而,由于超时导致的会话到期,不以发条精度发生;在过期的会话实际上是“垃圾收集”之前可能需要很长时间。此外,垃圾收集触发probabilistically所以在理论中,过期的会话有可能从不被垃圾收集。
这是否合情合理?是否有几百个并发SQL查询 成为共享服务器的问题,并且是使用$ _SESSION的想法 作为缓冲来减轻其中一些。
我真的不会这样做有几个原因:
替代方案呢?
好吧,既然我们正在谈论el cheapo共享主机,那么你绝对不会控制服务器,所以任何涉及PHP扩展的东西(例如memcached)都是有条件的。数据库端缓存也不会飞。此外,服务器上的负载将受到控制之外的变量的影响,因此您无法进行任何容量规划。
在任何情况下,我首先要确保数据库本身的结构是最佳的,并且代码的编写方式可以最大限度地减少数据库的负载(通过在编辑器中输入内容来实现免费性能)。 p>
之后,您可以引入只读缓存:通常有很多东西需要显示但不打算修改。对于“几乎从不”更新的数据,会在您需要的时候使您无效的会话缓存可以是一个简单而有效的改进(您甚至可以在失效方面有误报,只要它们不是太多了宏伟的计划)。
最后,如果您担心在单个请求期间从数据库中提取相同的数据两次,则可以添加按请求缓存(在变量中)。
答案 1 :(得分:5)
在会话被销毁时写入数据不是一个好主意。由于会话数据可以通过您的主机配置的垃圾收集器销毁,因此您不知道会话何时真正关闭,直到用户的cookie过期为止。
所以...我建议您使用共享内存(RAM)缓存系统,如memcache(如果您的主机提供)或基于磁盘的缓存系统。
顺便说一句,如果您的查询已经过优化,列被正确编入索引等,那么您的共享托管可能会在同一时间内收集大量查询,并且#34;。
答案 2 :(得分:2)
这是否合情合理?几百个并发SQL查询对于共享服务器来说是一个问题,并且使用$ _SESSION作为缓冲区来减轻其中的一部分。
没有。首先,你永远不知道会话发生了什么(退出很明显,超时几乎检测不到),所以它无论如何都不是值得信赖的缓存机制。如果有多个结果在多个请求的范围内多次查询(不会经常更改),请将这些查询的结果保存到专用的缓存机制,例如APC或memcached。
现在,我知道你的webhost不会提供这些缓存系统,但是,你可能会做不同的事情来优化你的网站。对于初学者来说,我最复杂的软件产品( 相当复杂)平均每页查询数据库约6次。如果结果是可重用的,我倾向于使用缓存,这样可以减少查询次数。
最重要的是,编写体面的查询更为重要;您的设计和查询质量比数量更重要。如果您正确地获得了架构,索引和查询,则10个查询比未优化的一个查询更快。我会花时间研究如何编写有效的查询,并阅读索引,而不是尝试通过“解决方法”克服问题,例如在会话中缓存。
祝你好运,我希望你的网站能够取得成功,你真的需要上面的建议;)
答案 3 :(得分:1)
实际上你可以使用$ _SESSION作为缓冲区以避免重复读取,这对我来说似乎是一个好主意(memcached甚至比那更好),当然不是为了延迟写入(这要复杂得多,应该由分贝);
您可以使用保存在$ _SESSION
中的简单哈希$cache = array();
$_SESSION['cache'] = $cache;
然后你必须进行查询
if(isset($_SESSION['cache'][$id]){
//you have a cache it
$question = $_SESSION['cache'][$id];
}else{
//no cache, retrieve your $question and save it in the cache
$_SESSION['cache'][$id] = $question ;
}