2009-10-06 65 views
14

将会话存储在Memcached中时,我有一个非常奇怪的问题。有时用户会参加其他会话。例如。 John,以Maria身份登录,Maria以Chris身份登录等等。当会话存储在memcached中时,用户将其他用户的会话(Rails)

我使用的Rails 2.3.4,但同样的问题已经发生与早期版本的Rails。我只使用一台Memcache服务器,它运行在同一台机器上。调试这个问题是我无法重现它。

如果有人能指导我如何解决这个问题或调试它,我将非常高兴。如果你使用Memcached进行会话,并且你分享你的例子,我也会很高兴。

这是我的配置:

# memcache options 
memcache_options = { 
    :c_threshold => 10_000, 
    :compression => false, 
    :debug => false, 
    :namespace => 'app_prod', 
    :readonly => false, 
    :urlencode => false, 
} 
memcache_servers = ['localhost:11211'] 

CACHE = MemCache.new(memcache_options) 
CACHE.servers = memcache_servers 

config.cache_store = :mem_cache_store, memcache_servers, memcache_options 
config.action_controller.session_store = :mem_cache_store 
config.action_controller.session = { 
    :session_key => '_appname', 
    :cache => CACHE, 
# :expires => 10, 
# :session_expires => 10, 
    :secret  => '5391aaaaaaaaaa56f8e8234beb638b97b32bbbbbbbbbbcc9dcae2beccccccccc89e8b508328def001a368da0678b061eb0e9d5a82a5ac94c8d35bd31a9a49e1' 
} 

谢谢你在前进, 斯坦

回答

5

我见过这个,发现它很难调试。

如果您使用的是乘客,您可能需要考虑使用保守的方法来产生新的服务器。

缺省方法的服务器共享单个套接字到memcache。

该文档更详细地讨论它。 http://www.modrails.com/documentation/Users%20guide%20Apache.html#_example_1_memcached_connection_sharing_harmful

+0

是的,我使用Passenger。 我会在我的两个应用程序上测试它,并在这里分享结果。 非常感谢您的帮助。我可以“闻到”问题出在这里。 – 2009-10-15 11:07:54

+0

我羡慕你的鼻子,但我不会标记答案为正确的,直到结果得到验证 – zvolkov 2009-10-27 20:01:15

3

这可能是两个值之间的会话cookie翻转的问题。例如,您可能会将一个分配给example.com,另一个分配给www.example.com,这是一些常见的情况,即某些网站会对这两个网站做出响应,而无需将其重定向到一个规范。

某些浏览器的行为是发送匹配最长子域的cookie,而其他浏览器实际上是通过这两个值发送的,并且它们可能会有所不同。这可能会导致会话在不可预知的时间在两个不同的值之间切换。

修复此问题的一种方法是将您的Cookie锁定到.domain.com,而不是让它假定为www或www-less版本(如果是这种情况)或重定向以强制只使用一个。

另一种诊断会话状态性质的方法是有一个显示会话ID的调试页面,或者以某种方式将其嵌入到页面输出中,以便遇到问题的人可以帮助诊断它。像/ session_info这样的东西很容易创建。

+0

OK,我有这样的配置选项: 的ActionController :: Base.session_options [:session_domain] =“.mysite.com” 我觉得这个配置选项意味着应用程序将不得不使用一个会话的所有子域,包括主要(mysite.com)。 另外,如果我看到有问题的用户的session_id,可以给出进一步的建议吗? – 2009-10-07 14:17:31

+0

这就是正确设置cookie的方式,所以应该有很多工作。 如果您想获得冒险精神,可以查看使用session_id值的production.log文件。通常当一个用户翻到另一个时,这是因为会话混淆了。如果不是这样,至少你可以把你的搜索关注于其他领域。 – tadman 2009-10-07 15:15:37

+0

是的,我认为会议越来越混乱,我正在寻找这个问题的解决方案。 – 2009-10-07 15:25:48

2

我从未遇到过这样的问题,我无法想象它甚至发生了。这是我的conf:

require 'memcache' 

memcache_options = { 
    :c_threshold => 10_000, 
    :compression => true, 
    :debug => false, 
    :namespace => "app-me", 
    :readonly => false, 
    :urlencode => false 
} 
memcache_servers = [ "#{MEMCACHED_HOST}:#{MEMCACHED_PORT}" ] 

CACHE = MemCache.new memcache_options 

CACHE.servers = memcache_servers 
ActionController::Base.session_options[:expires] = 1800 
ActionController::Base.session_options[:cache] = CACHE 

# Inside the Rails initializer 
config.action_controller.session_store = :mem_cache_store 
+0

就像你所看到的,与我的memcache_options唯一的区别是我不使用:压缩。但我不认为这应该是一个问题。 在这两个有会话问题的应用程序中,我配置了这样的重定向:http://www.mysite.com => http://mysite.com。 你有域名/子域名重定向吗? – 2009-10-07 14:21:28

3

这能解决问题,我的代码:

我添加了这些线在

的environment.rb

if defined?(PhusionPassenger) 
    PhusionPassenger.on_event(:starting_worker_process) do |forked| 
    if forked 
     CACHE.reset 
     if Rails.cache.class == ActiveSupport::Cache::MemCacheStore 
     Rails.cache.instance_variable_get(:@data).reset 
     end 
    end 
    end 
end 
+0

不适用于我的红宝石2.3 Rails 4.2.5 – 2017-01-21 19:04:39

0

Dalli Gem可能有助于结束。 A recent commit固定套接字共享,所以你可以看看他们的代码,看看他们是如何做到的。

+0

这仍然发生在我的Ruby 2.3 Rails 4.2.5与Dalli宝石。 – 2017-01-31 04:32:53