Rails: Запланированное задание на разогрев кеша?

Я использую следующее для кэширования медленной загрузки страницы с использованием memcached:

caches_action :complex_report, :expires_in => 1.day

Действие контроллера защищено аутентификацией Devise.

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

Проблема в том, что первоначальный запрос загружается за 20-30 секунд. Можно ли заполнить кеш заранее по расписанию?

Любые предложения высоко ценится.

4 ответа

Решение

Вот расширение предыдущего решения на основе cron, которое использует возможность curl для хранения файлов cookie, чтобы вы могли выполнить аутентификацию за один шаг, а затем снова использовать файл cookie в качестве аутентифицированного пользователя на следующем этапе. Так что если вы поместите эти строки в сценарий с именем "prepare_cache.sh"

rm /tmp/cookiejar
curl --request POST -d "login=<username>" -d "password=<password>" -c /tmp/cookiejar http://yourwebpages.url/login
curl --request GET -b -c /tmp/cookiejar http://yourwebpages.url/page_to_cache
rm /tmp/cookiejar

заменив параметры логина и пароля на те, которые соответствуют переменным, используемым в вашей форме входа, и, очевидно, URL-адресам для вызова. Я удаляю cookiejar прежде, чтобы убедиться, что там уже нет файла, и удаляю его в конце, чтобы убедиться, что нет cookie, плавающего с уровнями доступа, которых он не должен иметь.

Затем вы можете вызвать этот скрипт с помощью задания cron:

*/15 * * * * /home/myname/prepare_cache.sh > /dev/null 2>&1

И, надеюсь, это должно сработать. Казалось, работает на меня, когда я попробовал это.

Посмотрите на этот драгоценный камень:

https://github.com/tommyh/preheat

Драгоценный камень предназначен для подогрева вашего Rails.cache.

Из документации:This will "preheat" all your Rails.cache.fetch calls on your homepage. It is as simple as that!

    #app/models/product.rb
    def slow_method
      Rails.cache.fetch("product-slow-method-#{self.id}") do
        sleep 15
        Time.now
      end
    end

    #lib/tasks/preheat.rake
    namespace :preheat do
      desc "Preheat product caches"
      task (:products => :environment) do
        Preheat.it do
          Product.all.each do |product|
            app.get(app.products_path(product)) #or you could just call product.slow_method directly, whatever makes more sense
          end
        end
      end
    end

    #crontab -e
    0 * * * * /path/to/rake preheat:products RAILS_ENV=production 2>&1 >> #{Rails.root}/log/preheat.log &

Если это процесс запуска отчета и сбора результатов, который отнимает много времени, вы можете кэшировать эти результаты (вместо кэширования действий или параллельно), используя Rails.cache.write а также Rails.cache.read,

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

Вероятно, самым основным решением было бы создать простую cron запись, чтобы загрузить страницу, вы хотите иметь "горячий" кэш. Это может быть так просто добавить следующее к crontab пользователя на вашем сервере с помощью crontab -e открыть редактор:

*/15 * * * * wget -q http://yourwebpages.url/ > /dev/null 2>&1

Что это будет делать, это использовать wget получать данные по указанному URL каждые 15 минут каждого часа, дня, месяца и года, игнорировать результаты и не отправлять *nix почту в случае, если что-то пойдет не так.

Другие вопросы по тегам