如何在负载均衡群集中使用PHP会话?

好的,所以我已经得到了这个完全罕见的负载平衡的PHP网站的独特场景。 令人沮丧的是 – 它并没有用来平衡负载。 现在我们开始发现问题了

目前唯一的问题是PHP会话。 自然没有人想到这个问题,所以PHP会话configuration保持其默认。 因此,这两个服务器都有自己的一小撮会话文件,不幸的是获取下一个请求的用户被抛出到另一个服务器上,因为他没有在第一个服务器上创build的会话。

现在,我已经阅读了PHP手册了解如何解决这种情况。 在那里我find了session_set_save_handler()的很好的function。 (巧合的是, 这个话题就这么 )整洁。 除了我必须在网站的所有页面上调用这个函数。 未来页面的开发人员也必须记得随时调用它。 感觉有点笨拙,更不用说可能违反了一打最好的编码做法。 如果我可以翻转一些全局configuration选项和Voilà – 会话全部被神奇地存储在一个数据库或一个内存caching或其他东西中,那将会更好。

任何想法如何做到这一点?


补充:澄清 – 我希望这是一个标准的解决scheme的标准情况。 仅供参考 – 我有一个MySQL数据库可用。 一定有一些现成的代码可以解决这个问题吗? 当然,我可以编写我自己的会话保存的东西和Greg指出的auto_prepend选项似乎很有前途 – 但是这将感觉重新发明轮子。 :P


新增2:负载均衡是基于DNS的。 我不知道这是如何工作,但我想这应该是这样的 。


添加3:好的,我看到一个解决scheme是使用auto_prepend选项插入到每个脚本session_set_save_handler()的调用,并写我自己的数据库持久化,也许投入调用memcached更好的性能。 很公平。

是否还有一些方法可以避免自己编码? 就像一些着名且经过充分testing的PHP插件一样?

添加了很多,后来:这是我最后的方式: 如何在PHP + MySQL中正确实现自定义会话持久化?

另外,我只是将会话处理程序手动包含在所有页面中。

您可以设置PHP来处理数据库中的会话,所有服务器共享相同的会话信息,因为所有服务器都使用相同的数据库。

一个很好的教程可以在这里find 。

我们处理这个的方式是通过memcached。 所需要的是改变php.ini类似于以下内容:

 session.save_handler = memcache session.save_path = "tcp://path.to.memcached.server:11211" 

我们使用AWS ElastiCache,所以服务器path是一个域,但是我确定它也和本地memcached类似。

此方法不需要任何应用程序代码更改。

你没有提到你用于负载平衡的技术(软件,硬件等); 但无论如何,解决您的问题是在负载均衡器上使用“粘性会话”。

总而言之,这意味着当来自“新”访问者的第一个请求进入时,它们被分配到集群中的特定服务器:所有未来对其会话生命周期的请求将被引导到该服务器。 实际上,这意味着在单个服务器上编写的应用程序可以通过零/less量代码更改扩展到一个平衡的环境。

如果您使用的是硬件平衡器(例如Radware设备),那么粘性会话将被configuration为群集设置的一部分。 硬件设备通常会给你更细致的控制:比如分配给新用户的服务器(他们可以检查健康状况等,select最健康/最less使用的服务器),以及更多的控制服务器失败并退出群集。 硬件平衡器的缺点是成本 – 但它们是值得的。

至于软件平衡器,则归结为你正在使用的是什么。 对于Apache有mod_proxy上的stickysession属性 – 以及大量的文章通过谷歌得到这个工作与PHP会话( 例如 )


编辑:从原来的问题后发布的其他意见,这听起来像你的“平衡”是通过循环DNS完成的,所以上述可能不会适用。 我会避免进一步评论,并开始对循环赛DNS的火焰。

最简单的方法是将您的负载均衡器configuration为始终将相同的会话发送到同一台服务器。

如果你仍然想使用session_set_save_handler那么也许看看auto_prepend。

当我们遇到这种情况时,我们实现了一些生活在共同标题中的代码。

本质上,我们检查每个页面是否知道会话ID。 如果我们不检查是否处于所描述的情况,那么检查是否已经在DB中存储了sesion数据。否则,我们只是开始一个新的会话。

显然,这需要将所有相关的数据复制到数据库中,但是如果将会话数据封装在单独的类中,则可以正常工作。

您也可以尝试使用memcache作为会话处理程序

如果您使用的是php会话,则可以使用NFS与集群中所有服务器之间的/ tmp目录(我认为会话存储在该目录中)共享。 这样你就不需要数据库了。

编辑:您也可以使用像memcachedb(持久和快速)的外部服务,并将会话信息存储在memcachedb索引中,并使用内容的散列或甚至会话ID对其进行标识。

如果你有时间,你还想检查更多的解决scheme,看看http://redis4you.com/articles.php?id=01 ..

使用redis你是容错的。 从我的angular度来看,这可能比memcache解决scheme更好,因为这种健壮性。

可能为时已晚,但请查看: http : //www.pureftpd.org/project/sharedance

Sharedance是一个高性能的服务器,用于集中远程主机上的临时密钥/数据对,而无需SQL数据库的开销和复杂性。

它主要是为了在一组Web服务器之间共享caching和会话而devise的。 访问共享服务器通过一个简单的PHP API是微不足道的,它与PHP 4和PHP 5会话处理程序的期望兼容。

当涉及到负载平衡群集中的php会话处理时,最好有粘滞会话。 为此,请维护负载均衡器的数据中心networking启用粘滞会话。 一旦启用,你将不需要担心会议在PHP结束