当会话存储在memcached(Rails)中时,用户会占用其他用户的会话

时间:2009-10-06 08:01:23

标签: ruby-on-rails session memcached

在Memcached中存储会话时,我遇到了一个非常奇怪的问题。有些用户不时会参加其他人的会话。例如。 John,以Maria,Maria和Chris等身份登录。

我使用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 个答案:

答案 0 :(得分:5)

我已经看到了这一点,发现它很难调试。

如果您正在使用乘客,您可能希望使用保守的方法来生成新服务器。

默认方法是服务器将单个套接字共享到memcache。

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

答案 1 :(得分:3)

这可能是会话cookie在两个值之间翻转的问题。例如,您可能有一个分配给example.com而另一个分配给www.example.com,这是一些常见情况,有些网站会对两者做出响应,而不会重定向以制作一个规范。

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

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

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

答案 2 :(得分: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

答案 3 :(得分:2)

我之前从未遇到过这样的问题,我无法想象它甚至会发生。这是我的承诺:

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

答案 4 :(得分:0)

Dalli Gem可能有所帮助。一个recent commit固定套接字共享,因此您可以查看他们的代码,看看他们是如何做到的。