Я знаю, что этот пост действительно старый, но я решил добавить сюда потенциальное решение и посмотреть, какие комментарии поступят от сообщества.
Мы рассматриваем перемещение наших сессий в 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)
Значения - это хеш, который будет содержать любые подходящие ключи. Просто суммируйте значения ключей, чтобы получить счет за этот период времени.
Вопрос:
- Будет ли этот масштаб? Когда приложение находится под большой нагрузкой, в кеше будет много приращений / приращений счетчиков. Будут ли блокировки ключа, что приведет к замедлению работы приложения? Я думал о том, чтобы поместить секцию увеличения / уменьшения в поток, но вы знаете, не настраивайте производительность, пока не возникнет известная проблема.
Обновление:
Мы внедрили этот шаблон и запустили в производство. У нас он работал очень хорошо, и проблем с производительностью пока не было.