Rails - список активных сессий - PullRequest
2 голосов
/ 11 июля 2009

Я пытаюсь найти наиболее простой и безопасный способ подсчета количества активных сеансов с использованием опции хранилища memcached. В хранилище сеансов на основе БД я могу просто посчитать количество строк в таблице, но не могу сделать то же самое с memcached.

Спасибо, Викрам

Ответы [ 3 ]

1 голос
/ 11 июля 2009

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

К сожалению, before_filter не будет работать, потому что сеансы могут истечь в memcached без уведомления вашего приложения об этом.

Почему вы хотите получить эту информацию?

0 голосов
/ 14 января 2017

Я знаю, что этот пост действительно старый, но я решил добавить сюда потенциальное решение и посмотреть, какие комментарии поступят от сообщества.

Мы рассматриваем перемещение наших сессий в memcached, так как мы используем его для кэширования фрагментов (и других вещей). Этот подход работает на моей машине, но у него не было возможности очистить код и протестировать его в более надежной среде.

Решение довольно простое. Он использует ключ на основе часа: минуты и увеличивает / уменьшает ключи при продлении сеанса. Контейнер (ключ), в который помещается сессия, возвращается и сохраняется в сессии. В следующий раз, когда сеанс попадает в приложение, предыдущий сегмент, в который он был помещен, передается методу count. Таким образом, сеанс может перемещаться между ключами (перемещаться из предыдущего сегмента в новый)

Вот метод:

def count(previous_bucket)
    # All this does is construct a key like this:
    # _session_counter_10:15
    key = KEY_PREFIX + time_key(Time.now.hour, Time.now.min)

    # do nothing if previous bucket = key
    return key if previous_bucket.present? && key.eql?(previous_bucket)

    # Increment the count in the cache
    Rails.cache.increment(key, 1, expires_in: 30.minutes)

    # If there is a previous bucket, decrement the count there
    if previous_bucket.present?
        Rails.cache.decrement(previous_bucket, 1)
    end

    # Return the key used so it can be stored in the session which was counted.  This will be returned on the next
    # call to bump to keep the numbers accurate
    return key
end

Для использования вызывающий метод делает это:

counter = SessionCounter.new
session[:counter_bucket] = counter.count(session[:counter_bucket])

Чтобы получить количество сеансов за определенный период времени, вы можете просто создать массив ключей для этого периода времени, а затем использовать read_multi для получения счетчиков за это время.

Например:

keys = ["_session_count_10:15","_session_count_10:14","_session_count_10:13"]
values = Rails.cache.read_multi(*keys)

Значения - это хеш, который будет содержать любые подходящие ключи. Просто суммируйте значения ключей, чтобы получить счет за этот период времени.

Вопрос:

  • Будет ли этот масштаб? Когда приложение находится под большой нагрузкой, в кеше будет много приращений / приращений счетчиков. Будут ли блокировки ключа, что приведет к замедлению работы приложения? Я думал о том, чтобы поместить секцию увеличения / уменьшения в поток, но вы знаете, не настраивайте производительность, пока не возникнет известная проблема.

Обновление:

Мы внедрили этот шаблон и запустили в производство. У нас он работал очень хорошо, и проблем с производительностью пока не было.

0 голосов
/ 11 июля 2009

Я не думаю, что вы можете сделать это с memcache.

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

...