【问题标题】:Laravel 5.1 randomly dropping session dataLaravel 5.1 随机丢弃会话数据
【发布时间】:2016-05-07 10:31:44
【问题描述】:

我有一个关于 Laravel 5.1 应用程序的奇怪问题。

间歇性地,它正在删除会话数据。我通过编写一些中间件来检测到这一点,该中间件将该请求的会话内容写入日志文件。虽然会话 ID (Session::getId()) 没有改变,但使用Session::all() 检索到的会话数据中_token 的值会发生变化。

正如我所说,这会间歇性地发生。我可以多次刷新同一个 URL,然后随机刷新一次,会话数据消失了,_token 值与之前的请求不同。

这是什么原因造成的?我还注意到 flash 对象不在“丢弃的”会话数据中。

下面是日志的sn-p。在最后两行可以看到session_data键的内容随机改变“形状”,但会话ID保持不变。

另外,不确定它是否相关,但我启用了DebugBar

更新:通过调试,我发现在某些页面加载时,会话完全为空,例如,没有_token(因此获得了一个新的生成)。什么都没有。

【问题讨论】:

  • 这种情况多久发生一次?因为我试图通过启用 DebugBar 来重现这一点,创建一个中间件,将会话 id 和数据记录为序列化 JSON,就像你正在做的那样,然后调用一个具有每秒自动刷新的视图的路由,并将其保留为大约10分钟。但它没有刷新 CSRF 令牌或删除任何会话数据。这是使用 artisan servefile 会话驱动程序完成的,因此您可能需要发布有关您的环境的更多信息。
  • 每隔一两分钟就会发生一次。该应用程序在 Apache 下运行。我可以刷新一个 URL,它会在多次刷新后根据屏幕截图随机丢失数据。它没有真正的规律,这使得寻找原因变得困难。
  • 我的第一个建议是尝试在全新安装的 Laravel 上重现问题,就像我在第一条评论中描述的那样,至少看看问题是否出在你的应用程序代码或设置中的其他内容。
  • 在 L4,2 上搜索了类似问题后发现了这个问题。脚本完成后将写入会话。脚本是否有可能根本没有完成,而是被杀死了?我已经看到在一些使用字节缓存和重 AJAX 页面的 VPS 服务器上 - 太多的快速请求会导致 HTTP500 和 PHP 处理程序因某种内存违规而死亡。在这些情况下不会写入会话。
  • 我也有同样的问题。 1. 当响应返回为 view::make() 时,它工作正常。 2.当response()->json()返回响应时刷新session._token hash。

标签: laravel session laravel-5.1


【解决方案1】:

如果您使用 Linux,请尝试使用 Redis (http://redis.io) 作为 laravel 中的会话/缓存管理器。过去,我在某些服务器中遇到了一些关于 text/cookie 和 laravel 的问题。当我安装 Redis 时,我再也没有问题了。

更多信息:https://laravel.com/docs/5.1/redis

【讨论】:

  • 谢谢,但替代驱动程序并不能真正解决问题。我们的暂存环境正在使用文件驱动程序,这就是问题所在。
  • 你能试试数据库驱动吗?相反,它将保留在数据库表中,也许它可以工作。 laravel.com/docs/5.1/session
  • 一直在使用数据库驱动,问题依旧。不确定它是否是驱动程序的罪魁祸首。我注意到这种情况经常发生在中间件中,如果我们要在刀片中打印,它会很好。不知道发生了什么奇怪的事情......
【解决方案2】:
  1. 如果您使用的是文件驱动程序,您可能会遇到并发请求的竞争条件。然后文件被截断,Laravel 无法读取它,因此它刷新会话。竞争条件也可能导致您在会话中放入的东西没有被放入的症状。这往往是随机的,因此很难调试。根据 Laravel 团队的说法,这是文件驱动程序的一个已知限制,并且似乎没有得到修复,所以我建议使用不同的驱动程序。这将解决您的随机会话刷新问题,但它仍然引入了对未添加的会话进行更改的可能性。据我所知,目前使用 Laravel 5.1,您必须自己管理。

  2. 不知何故,您的会话数据太长且被截断。如果您正在使用数据库驱动程序(尚未测试其他驱动程序),并且您尝试保存比字段长度更长的会话数据,那么后续请求将无法从该会话中拉取,并且您会缠绕进行新的会话。如果此问题是在会话数据非常短的情况下随机发生的,则可能是上面列出的原因。

【讨论】:

  • 我只花了 2 天时间来追踪这个问题,而 #1 是罪魁祸首。由于不相关的原因,我们试图包含一个不存在的 JS 文件。这必须通过应用程序/路由器才能解析为 404,这导致了竞态条件。删除指向虚假 js 文件的链接似乎已经解决了这个问题。谢谢!
【解决方案3】:

使用像 memcached 这样的不同驱动程序并没有解决我的问题。 这是一个实现会话锁定的包,它可以工作并且非常容易合并到您的项目中。

https://github.com/rairlie/laravel-locking-session

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    相关资源
    最近更新 更多