我目前有一个很大的问题。两天前,我在一台服务器上运行的网站太多,所以我再购买了两台并将它们集群化(rsync和负载均衡)。
然后我开始注意到用户会点击server-1,然后在下一个请求命中server3但是他们的会话仍在server1而不是server3上,并且他们不再登录。
我被建议使用memcache进行会话存储。
我的脚本已使用$_SESSION
。
我们可以安装memcache并启用会话处理程序支持并设置session.save_handler = "memcache"
以强制php使用memcache吗?
是否需要使用memcache进行应用程序编程?
这会解决我在服务器问题之间的会话吗?
会话存储在创建时是存储在所有服务器上还是像主存储器服务器一样存储?
我正在使用codeiginiter框架
答案 0 :(得分:14)
问题分为两部分:
这取决于您的负载均衡器/反向代理。通常通过IP地址或代理设置的透明cookie使客户端坚持一台服务器是很常见的。但是,如果你有一个分布式会话存储,那么就没有必要为会话提供客户端粘性,这会将我们带到memcache。
memcache有一个适当的无共享分布式架构,因此大部分智能都在客户端。所以你要做的就是继续使用memcache会话存储,但不是指向一个服务器,而是指向 ALL 。这包括in the docs。在php.ini中,您应该将session.save_path设置为memcached服务器列表,例如server1:11211, server2:11211
。
请注意,PHP中有两个不同的memcache客户端库,名为memcache
和memcached
,并且它们具有不同的语法。
由于memcache的工作方式,您无需关心会话数据的存储位置 - 它会为您完成。
正如NathanD所指出的,memcache是易失性的,并且在重启时会丢失数据,当你有多个服务器时,这意味着如果重新启动了一些(但不是全部)用户,它们将被注销。如果一台服务器完全死亡您的会话存储将继续工作。会话数据位于死亡服务器上的用户将被启动,但他们可以重新登录并继续运行,而不会出现该服务器。
答案 1 :(得分:5)
两个主要的memcache PHP PECL扩展都有会话处理程序。要么在使用前要么安装PECL模块。
使用php.ini中的以下内容启用Memcache PECL扩展会话处理程序:
session.save_handler = "memcache"
session.save_path = "tcp://memcacheServerAddressHere:11211?persistent=1&weight=2&timeout=2&retry_interval=10"
使用php.ini中的以下内容启用Memcached PECL扩展会话处理程序:
session.save_handler = "memcached"
session.save_path = "memcacheServerAddressHere:11211"
请注意,Memcache扩展似乎允许更多配置Memcache环境。
答案 2 :(得分:2)
您需要设置memcache以在其中一台服务器上运行,并让所有服务器为会话使用相同的memcache实例。否则,如果他们各自运行自己的memcache实例,那么你将遇到与以前相同的问题。
除了相应地配置memcache并告诉PHP将其用作会话处理程序之外,您不必对代码进行任何更改。
〜
为了澄清我在这里给出的建议,如果将所有三个服务器组合到一个池中,只要每个PHP实例以相同的顺序引用这些服务器,就不会有任何问题。 memcache使用client side hashing,因此可以保证在同一台服务器上读/写相同的密钥。当然,如果您以任何方式更改该列表,那么会话将失效。
memcache开发人员实际上甚至不建议您使用memcache来存储会话数据,因为它不是持久性的,因此如果您必须重新启动memcache(或者某些事情发生),那么您的所有用户都将被注销
答案 3 :(得分:1)
你要小心这样做。需要注意的一件事是不要将会话信息与其他非会话数据一起托管。当它只包含您自己网站的数据时,清除缓存并不是最大的优惠,但您不希望随之消除人们的会话。
只要您使用与memcache相同的密钥,您每次都应该使用相同的服务器。所以这个问题应该消失。
答案 4 :(得分:0)
最好使用memcachedb作为memcache本身的持久存储,甚至使用我在你的情况下强烈推荐的更智能的redis
答案 5 :(得分:0)
您还可以将会话编写到SQL DB。这还将为您提供跨服务器的持久会话。请参阅以下教程:http://culttt.com/2013/02/04/how-to-save-php-sessions-to-a-database/
如果你坚持在memcached中运行会话(为了获得更好的性能,但是更低的一致性),你可以简单地在几个地方重写他的代码
答案 6 :(得分:0)
您也可以同步基于文件的会话。我是在两台负载均衡的服务器上完成的。
在Ubuntu和许多其他Linux上,会话存储在/var/lib/php5
。
我按照over here on Superuser步骤操作,将PHP会话文件夹从一台服务器挂载到另一台服务器上。