将所有用户活动存储为会话值,并在会话结束时保存会话值



通常情况下,我会保存所有的用户活动,页面视图和所有值通过执行查询每次页面加载,在php。

  • 现在我正在考虑将所有这些存储为会话值和在会话结束时执行查询。但是,我不知道如何在php中处理这个"结束会话"事件。

我想到了一个后台进程,它在会话超时之前存储所有会话值,但我对php中的多线程方法一无所知,尽管我听说有些规避是可能的。

  • 我想确定用户是否在没有用户的情况下处于非活动状态触发器(如页面加载)并将所有会话值保存在会话结束,在超时之前。

这将在数据库引擎上节省一些工作量,就像这样:如果用户查看了很多页面,我就增加session的值,而不是执行像

这样的查询。
update pageviews set numberofviews=numberofviews+1

  • 问题是这样的:"我如何在php中处理会话结束事件没有用户活动?"

对实际问题的解决方案也表示赞赏。不管与加粗的问题是否相关。(我还没有开始写代码,我的问题不是关于bug修复)

可能的解决方案:

  • 将数据存储在内存类型的mysql表中并移动每隔一段时间记录到另一个表。
  • Php在这里有一个会话销毁处理程序

我已经发现了php会话处理函数,但文档没有说任何关于它是否可以有空参数回调参数?

如果我为$callback参数输入null参数,我会失去标准功能吗?

我只想修改session $destroy事件。这件事我需要帮助,现在。

相关文章:RP1

你不能真正使用session_destroy处理程序,因为它只有在你显式调用session_destroy时才会被调用,如果用户只是关闭浏览器并结束会话,就不会发生这种情况。由于在这种情况下无法捕获会话"事件"的结束,因此您必须执行某种定期检查,以查看会话是否在给定的时间段内处于空闲状态。要做到这一点,最简单的方法是在会话中创建一个保存上次访问时间的字段,然后创建一个脚本,定期(通过cron或触发PHP脚本中的其他功能)检查该字段中所有活动的会话,并且对于时间戳超过xx秒的会话,运行更新查询。

注意,为了使用存储在文件系统上的标准PHP会话来执行此操作,您必须实际打开文件并直接解析它们。另一种方法是将会话存储在数据库中,但这可能不是您想要做的,因为您正在尝试减少数据库上的负载。

另一种不太需要开发的可能性是:

  1. 为会话添加最后访问时间戳
  2. 每次更新会话时检查时间戳
  3. 如果时间戳超过xx秒,在数据库上运行更新查询,并将时间戳设置为当前时间

这样你只需要每隔一段时间更新数据库,而不是每次加载页面。当然,这种方法的缺点是,除非会话上的最后一个活动与调用更新函数的时间间隔完全对应,否则您可能无法在db中存储最新的会话信息。

这不是创建会话的目的,所以你想要实现的是不可能仅通过会话机制实现的。

对于标准的PHP会话,您的选择是有限的,并且取决于会话存储:

  1. 默认会话存储在文件中。如果禁用会话垃圾收集,则可以运行一个cron作业,该作业将解析比您定义的时间更早的会话文件。它并不完美,但迄今为止是最简单的。文件会话也很糟糕——写入每个请求。
  2. Memcached中的会话。由于没有好的方法来获取早于x的记录,而且Memcached在过期时只会删除数据,因此在这里可以做的事情不多。
  3. 会话数据库-你已经有一个更新的每个请求。

所以你在标准会话上的选择是有限的。我的建议是:用你自己的会话替换标准会话,但这意味着你将不再通过$_SESSION访问session,并且需要你重写大量的代码。

我已经用APC/Memcached以及DB中存储会话数据的单例替换了常规会话。会话数据保存在DB只有当我请求它(Session::persistentStore($key,$value)),或者如果在处理请求APC/Memcached存储的会话数据表明它没有写足够长的时间。这极大地限制了写入次数。有了这个替换,你就会从DB端强制会话保存:从DB中获取未更新x分钟的会话的会话id,从APC/Memcached中获取每个会话的信息,如果那里没有更新信息(表明会话将很快结束),将其保存到DB。

这里只是一个疯狂的想法,您可以在从javascript卸载窗口时触发http请求来保存会话数据。问题是浏览器通常会在页面关闭后停止请求,所以这个请求甚至可能不会到达服务器,但我想值得测试一下。

尽管存在一些变通方法,但您可以找到的解决此问题的每种解决方案都比记录每个请求中的每个用户活动效率更低。

你想解决什么问题?我不明白为什么你在每次请求时都向数据库发起一个更新查询。这应该不会超过10000秒。

我绝对会选择更新每个请求。它只有一行代码,不会给数据库带来过多的负载,而且效率更高。

你建议的方法很难测试,产生不必要的负载,甚至可能创建全局状态。你可以通过传统的解决方案来避免这一切。当决定何时"结束"时,会话是一个(…)。

我想到了一个存储所有会话值的后台进程就在会话超时之前,但我不知道php中的多线程方法,尽管我听说过一些规避是可能的。

如果你正在使用基于数据库的会话,你可以很容易地做到这一点。

  1. 不需要多线程
  2. 写一个每分钟/每5分钟运行一次的cron作业
    • 选择所有即将过期的记录
    • 将它们保存到其他表

关键是使用cron作业,而不是试图在HTTP请求中处理过期事件

您正在谈论延迟统计写和会话管理。你真正的问题,我猜,是避免每http请求写查询数据库。

一些可能对这些问题有用的提示:

    注意在会话上的并行访问。我们通常认为会话只由一个进程访问,但这是错误的,让我们说,例如,你正在执行一个多文件上传与一些js打开几个ajax请求到服务器,每个进程使用相同的会话。当你用浏览器在同一个网站上打开10个选项卡时也是如此。
  1. 为每个请求添加更新查询是一件繁重的事情。选择查询速度很快,通常在SQL端使用某种缓存。更新查询很慢,可能会重建索引,并且通常意味着在SQL服务器上进行一些缓存清理。如果您在数据库上使用不同的用户进行只读或读写访问,它们也可能意味着不同的SQL会话。
  2. 会话大小不应该太大,因为每个请求都必须加载会话,并且每次在会话中写入内容时,都会设置机制(因为1)并将数据推送到物理会话存储(默认为文件)。所以会话写入会减慢进程。
  3. 一个NoSQl后端,如MongoDbReddit可能是存储每个请求统计信息的好地方,它们有正确的工具来确保原子更新,锁,并且可能比关系数据库执行得更快(但你也可以检查关系数据库中的内存表性能)。因此,您可以使用这些工具来跟踪活动,并通过使用这些后端作为实时统计的主要目标来避免SQL更新。您可以异步地从这些后端为数据库收集一些统计信息。现在会话是临时对象,这些NoSQl后端也可以是很好的会话存储(如果你编写自己的会话存储处理程序)。

EDIT:并行使用原子更新问题的示例:执行查询请求增量counter = counter +1与读取计数器,增加它并执行更新查询counter = mynewvalue相同。当多个进程使用相同的数据时,第二个是错误的。

有点偏离轨道,但是您可以自己进行垃圾收集。

  • 使用PHP将会话保存在一个目录中,最好是tmpfs,禁用垃圾收集。

  • 编写一个周期性的PHP脚本来查找所有超过20分钟的会话文件,打开它们,将它们写入数据库并删除它们

相关内容

  • 没有找到相关文章

最新更新