«Прятал» медленный REST API за nginx.

Возникли известные сложности — как обеспечить когерентность кэша?

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

Очень хотелось вот такой(или подобной) конфигурации:
location ~ ^/zone_two/(.*)$ {
    proxy_cache            zone_two;
    proxy_cache_key        $document_uri;
    proxy_cache_valid      60m;

    set $do_invalidate 0;
    if ($request_method = PUT) {
        set $do_invalidate 1;
    }
    proxy_cache_invalidate $do_invalidate; # Tadaaa!!!

    proxy_pass             http://127.0.0.1:9102/$1;
}


В итоге родился велосипед — github.com/egorse/ngx-proxy-cache-invalidate.
Работает с 1.8.0, 1.8.1.
Другие версии nginx не тестировал.

Критика всячески приветствуется. Особенно, если по «потрохам» nginx.

Update1: инвалидится не единичный элемент в кэш зоне а _все_ элементы из кэш зоны определенной по proxy_cache.

Комментарии (8)


  1. el777
    05.04.2016 10:29

    Я предпочитаю

     rm -rf /path/to/cache/zone/* 

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


    1. rustler2000
      05.04.2016 10:58
      +1

      В нашем случае это ближе к IoT — ни memcached ни varnish не влезет во flash и ram столько нет.
      Очищать же кэш через rm может делать stop world если лочить в nginx, или отдавать старые данные.


      1. el777
        05.04.2016 11:59

        rm вроде как официальное решение.
        Не в курсе точных ограничений в IoT, но я бы попробовал реализовать через rm, ради простоты инструментов и дальнейшей поддержки.


        1. rustler2000
          05.04.2016 12:46

          Еще есть http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_purge — но он по подписке.


          1. el777
            05.04.2016 12:49

            Не очень понимаю, что там по подписке.
            Я эту функциональность реализовывал в самом nginx c помощью cache_bypass.


  1. david_mz
    05.04.2016 13:15

    Вы инвалидируете по одному элементу? Но это можно сделать средствами самого nginx: proxy_cache_bypass принудительно берёт новый ответ с бэкенда и сохраняет в кэш (если не установлен proxy_no_cache).


    1. rustler2000
      05.04.2016 14:11

      Не один элемент из кэш зоны а все элементы в кэш зоне.


      1. david_mz
        05.04.2016 14:18

        А, виноват, не так понял.