水平扩展环境中的Laravel数据库会话

时间:2015-01-26 20:21:15

标签: php session laravel

我在多个前端/应用服务器环境中使用Laravel(即 - 负载均衡器后面的两个Web服务器)。

我正在调试Laravel应用程序在向服务器发出一些请求后丢失其会话数据的问题。我们使用单个MySQL数据库实例的数据库会话。

我注意到每次重新加载页面时,laravel_session cookie都会发生变化。一页刷新看起来像这样

eyJpdiI6I-mRudUNnM0ZpQzdxYmNyaWw0d21nWFE9PSIsInZhbHVlIjoiazVDQTVuZ0IzYUg5V0l3czBxaFl6bFRrXC9aTjFmT0VBeGVDYXg1REZQM2pIS1U0U1JCSVVreHprYU44ZjhKQTU4OTVUUGxpXC9qbWZpd0FcL2NtXC9ST25B-PT0iLCJtYWMiOiJ-hZWYxNTU4MDY0ODQxODViNDRjMjQzZGE1ZDQwZDA0YzQ0ZDY1YjE3YWE3YTc3ZjcwNTg4NGE3NDhhMWMzMGU0In0

然后再次重新加载页面,它看起来像这样

eyJpdiI6I-nFjRjN1TGp0Q3Z3VmlrOG1PQlwveDF3PT0iLCJ2YWx1ZSI6IkVRYkpuWXFIVms5YnBwRXU2b1wvMFZSbW14RkVTZm8yVEpnaHRiOEhpWnlJWm9OM0JRR1wvYUI1VWhmeGYxQm0yaEFrc25PZUVcL3NSZ0RtUytzWHR3THp3-PT0iLCJtYWMiOiJ-jNTQ1YjM0MTkwZDVmM2RlMTAxYmNkMjAzMTY1NzVjMDExNTkxODAyZDM0YmQ5ZTk5NzFiNmY1YjQxYzE3ZjY1In0

-是我的补充,表明其中的部分保持不变。

问题:

  1. 这会改变会话ID标准的Laravel行为吗?

  2. Laravel的4.2数据库会话是否可以在多个前端Web服务器环境中开箱即用?

  3. 在Laravel的核心会话中,会话实现在哪里,所以我可以自己捅它?

  4. Re:#1,每ceejayozlaravel_session Cookie在每个服务器请求上重新加密,此加密包含一些随机化 - 这意味着更改laravel_session价值是标准的劳拉维尔行为。

2 个答案:

答案 0 :(得分:1)

这可能有很多原因,但最有可能的原因是您的负载均衡器会将您引导到另一台不知道您的会话ID的服务器,从而为您生成一个新会话。

解决方法是使用像redis这样的共享密钥库。 Laravel有native support for redis,因此不应该花费太多精力来启动和运行,然后您的应用之间会共享会话缓存。 Redis非常高性能且易于设置,因此您的服务器不会因此而严重超载。您可能需要考虑RAM升级,具体取决于高负载下的会话数。

当然,您也可以将会话缓存目录移动到网络共享。这可能是表现不佳和浪费的努力,但你的竞争对手会笑得很开心;)

编辑:同时确保两个应用都具有相同的加密密钥

答案 1 :(得分:0)

  

这会改变会话ID标准的Laravel行为吗?

是的,这是标准的Laravel行为 - Illuminate\Cookie\Guard中间件层使用从Illuminate\Encryption\Encrypter类实例化的对象(包括creating an initialization vector from a random source)自动加密应用程序cookie。

#File: vendor/laravel/framework/src/Illuminate/Cookie/Guard.php
public function encrypt($value)
{           
    $iv = mcrypt_create_iv($this->getIvSize(), $this->getRandomizer());
    //...
    $value = base64_encode($this->padAndMcrypt($value, $iv));
    //...
}
  

Laravel的4.2数据库会话是否可以在多个前端Web服务器环境中开箱即用?

从我所见,是的。 Laravel的数据库会话是基于ID的,假设相同的应用程序和配置被发送到每个服务器,该ID可以在负载均衡器在服务器之间交换用户时生存。

  

Laravel的核心在哪里实现了会话实现,所以我可以自己捅它?

Laravel的会话处理在会话中间件

中设置
#File: vendor/laravel/framework/src/Illuminate/Session/Middleware.php

对于好奇的人来说,会议结束了一个红鲱鱼。问题是表单URL设置从安全URL发布到不安全的URL。当发生这种情况时,浏览器会丢弃您的cookie,这意味着会话ID被重新生成。因此,这仍然是由我们的负载平衡设置间接造成的,而我们的猴子修补Request对象并未考虑使用Laravel url->to()生成的网址。我们的解决方案是将表单URL生成切换为使用命名route,并仅在https

中将路由配置为app/routes.php