Пользователи принимают сеансы других пользователей, когда сеансы хранятся в memcached (Rails) - PullRequest
14 голосов
/ 06 октября 2009

У меня очень странная проблема при сохранении моего сеанса в Memcached. Время от времени некоторые пользователи принимают сеанс других. Например. Джон становится зарегистрированным как Мария, Мария как Крис и так далее.

Я использую Rails 2.3.4, но та же проблема возникала с более ранними версиями Rails. Я использую только один сервер Memcache, и он работает на той же машине. Проблема с отладкой заключается в том, что я не могу воспроизвести ее.

Я буду очень рад, если кто-нибудь может подсказать мне, как решить эту проблему или отладить ее. Я также буду рад, если вы используете Memcached для сеансов, и вы поделитесь своим примером config.

Это мои конфигурации:

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

Спасибо заранее, Stan

Ответы [ 5 ]

5 голосов
/ 15 октября 2009

Я видел это и мне было очень трудно отлаживать.

Если вы используете пассажира, возможно, вы захотите использовать консервативный метод порождения новых серверов.

В методе по умолчанию серверы совместно используют один сокет для memcache.

Документы обсуждают это более подробно. http://www.modrails.com/documentation/Users%20guide%20Apache.html#_example_1_memcached_connection_sharing_harmful

3 голосов
/ 03 ноября 2009

Вот код, который решает проблему для меня:

Я добавил эти строки в конце

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 голосов
/ 07 октября 2009

Это может быть проблемой при переключении файла cookie сеанса между двумя значениями. Например, у вас может быть один, назначенный для example.com, а другой - для www.example.com, что является обычной ситуацией для некоторых сайтов, которые отвечают на оба без перенаправления, чтобы сделать один канонический.

Поведение некоторых браузеров заключается в отправке cookie, соответствующего самому длинному поддомену, тогда как другие отправляют через оба значения, и они могут отличаться. Это может привести к переключению сеанса между двумя разными значениями в непредсказуемое время.

Один из способов исправить это - заблокировать ваши куки на .domain.com, вместо того, чтобы позволить ему принять версию www или без www, если это так, или перенаправить, чтобы принудительно использовать только одну.

Еще один способ диагностировать природу ситуации сеанса - это иметь страницу отладки, которая отображает идентификатор сеанса, или каким-либо образом встраивать его в выходные данные страницы, чтобы тот, кто сталкивается с проблемой, мог помочь в ее диагностике. Нечто подобное / session_info легко создать.

2 голосов
/ 07 октября 2009

Я никогда не сталкивался с такой проблемой раньше, я просто не могу представить, что это даже происходит. Это мой конф:

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 голосов
/ 05 сентября 2012

Может помочь Dalli Gem . недавний коммит исправлено совместное использование сокетов, чтобы вы могли посмотреть на их код и посмотреть, как они это сделали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...