Users take sessions of other users when sessions are stored in memcached (Rails)

后端 未结 5 2167
眼角桃花
眼角桃花 2020-12-14 10:30

I have a very weird problem, when storing my session in Memcached. From time to time some users takes the session of others. E.g. John, becomes logged in as Maria, Maria as

相关标签:
5条回答
  • 2020-12-14 10:54

    I never ran into such a problem before, I just can't imagine that it's even happening. This is my 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 讨论(0)
  • 2020-12-14 10:57

    The Dalli Gem might help. A recent commit fixed socket sharing, so you could look at their code and see how they did it.

    0 讨论(0)
  • 2020-12-14 11:02

    This could be a problem with the session cookie flipping between two values. For example, you might have one assigned to example.com and another to www.example.com, a common situation with some sites that respond to both without redirecting to make one canonical.

    The behavior of some browsers is to send the cookie matching the longest subdomain, whereas others actually send through both values, and they may differ. This could lead to a session toggling between two different values at unpredictable times.

    One way to fix this is to lock your cookies to .domain.com instead of letting it assume the www or www-less version, if this is the case, or redirecting to force the use of one only.

    Another way to diagnose the nature of the session situation is to have a debugging page that displays the session ID, or embed it in the page output somehow so someone who encounters the problem can help in diagnosing it. Something like /session_info is easy to create.

    0 讨论(0)
  • 2020-12-14 11:16

    I've seen this and found it very difficult to debug.

    If you're using passenger, you may want to look at using the conservative method for spawning new servers.

    The default method has servers sharing a single socket to memcache.

    The docs discuss it in more detail. http://www.modrails.com/documentation/Users%20guide%20Apache.html#_example_1_memcached_connection_sharing_harmful

    0 讨论(0)
  • 2020-12-14 11:16

    Here it is the code that resolves the problem for me:

    I added these lines at the end of

    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 讨论(0)
提交回复
热议问题