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

在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' } 

先谢谢你,斯坦

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

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

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

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

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

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

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

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

这是解决问题的代码:

我在最后添加了这些行

的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 

我之前从未遇到过这样的问题,我无法想象它甚至会发生。 这是我的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 

Dalli Gem可能会有所帮助。 最近提交固定套接字共享,所以你可以查看他们的代码,看看他们是如何做到的。