在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'
}
提前谢谢你, 斯坦
答案 0 :(得分:5)
我已经看到了这一点,发现它很难调试。
如果您正在使用乘客,您可能希望使用保守的方法来生成新服务器。
默认方法是服务器将单个套接字共享到memcache。
答案 1 :(得分:3)
这可能是会话cookie在两个值之间翻转的问题。例如,您可能有一个分配给example.com而另一个分配给www.example.com,这是一些常见情况,有些网站会对两者做出响应,而不会重定向以制作一个规范。
某些浏览器的行为是发送与最长子域匹配的cookie,而其他浏览器实际上通过这两个值发送,它们可能不同。这可能导致会话在不可预测的时间在两个不同的值之间切换。
解决此问题的一种方法是将您的Cookie锁定到.domain.com,而不是让它采用www或www-less版本(如果是这种情况),或者重定向以强制仅使用一个。
诊断会话情况性质的另一种方法是使用一个显示会话ID的调试页面,或以某种方式将其嵌入页面输出中,以便遇到问题的人可以帮助诊断它。像/ session_info这样的东西很容易创建。
答案 2 :(得分:3)
这是解决问题的代码:
我在
的末尾添加了这些行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固定套接字共享,因此您可以查看他们的代码,看看他们是如何做到的。