оптимизация работы с API

116
10 августа 2019, 03:30

Есть сайт, при загрузке одной страницы идут несколько десятков одинаковых запросов к апи(/api/products, /api/objects), нужно сделать оптимизацию запросов к апи, т.е. уменьшить количество одинаковых запросов.

Чтобы это сделать, думаю, нужно сохранить где-то несколько массивов JSON, которые вовзращает АПИ (весом примерно 1мб.), чтобы не ломиться к апи за одними и теми же данными.

Важно, что данные нужно обрабатывать на стороне сервера (php).

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

Сохранять в сессиях думаю, что не очень хорошо будет.

Answer 1

Вам поможет кеширование. Их бывает два вида.

Клиентское кеширование

Давайте кешировать запросы на 1 час прямо в браузере? Тогда добавьте такой заголовок:

$maxAge = 3600;
header(sprintf('Cache-Control: max-age=%d, must-revalidate', $maxAge));

Проверить можно в Хроме через консоль разработчика - вкладка сеть, фильтр XHR. Закешированные запросы будут показываться как (from disk cache).

Этот заголовок также можно добавить на уровне веб-сервера. В Nginx: add_header Cache-Control "max-age=3600";.

Серверное кеширование

В принципе, клиентское кеширование спасет от кучи однотипных запросов. Однако если запросы идут от разных клиентов (разные люди в разных браузерах), включите кеширование на сервере.

В примере ниже игнорируется заголовок Set-Cookie. Это заставляет кешировать ответы для всех запросов, игнорируя авторизацию (не учитывается пользователь) и прочее. Если не уверены в том, что делаете, не используйте :) Удачное решение, если информация по продуктам / ценам одинакова для всех.

Чтобы лучше разбираться в отдельных тонкостях, отсылаю к официальной документации

Так как я люблю nginx, пример будет для него:

# Настройки кеша
proxy_cache_path /tmp/nginx   # путь
  levels=1:2                  # количество уровней
  keys_zone=my_cache:10m      # название:размер зоны, 1Мб ~ 8000 ключей (1 ключ - 1 запрос)
  max_size=10g                # размер данных кеша, при превышении удаляются наиболее старые
  inactive=60m                # время хранения запроса на диске с момента последнего обращения, независимо от Cache-Control
  use_temp_path=off;          # off - используем proxy_cache_path; on - используем proxy_temp_path, указанный в location
server {
  # тут настройки вашего веб-сервера

  # укажите тут свой location, который следует кешировать
  location /api/ {
    # Какой кеш использовать? Эта инструкция работает также на уровне server
    proxy_cache my_cache;
    # Так можно будет в браузере понять, взят ли запрос диска, или пришлось запустисть веб-сервер
    # HIT - из кеша, MISS - с сервера, EXPIRED - время кеширования истекло, взято с сервера
    add_header X-Cache-Status $upstream_cache_status;
    # Начинаем игнорировать заголовки:
    # Expires - точно нужно игнорировать, иначе не будет кешироваться, на счет остальных - не уверен
    proxy_ignore_headers Expires Cache-Control Set-Cookie;
    # Добавляем свой Cache-Control
    add_header Cache-Control "max-age=3600";
    # форсируем кеширование, хотя эта опция нужна не для всех случаев !!!
    proxy_cache_valid any 60m;
    # Если источник "отвалился", будем отдавать с диска
    proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
    # но будем обновляться в фоне, (c версии Nginx 1.11.10), если ваш Nginx старый, закомментируйте
    proxy_cache_background_update on;
    # Веб-сервер - источник данных
    proxy_pass http://$http_host$uri$is_args$args;
  }
}

UPD

Кеширование - палка о двух концах. Данные устаревают. Важно понять причины устаревания данных, типичную продолжительность их жизни и выработать стратегию инвалидации кеша.

Если указать срока жизни кеша в 1 час, это значит, что мы осознано идем на то, что данные могут быть просрочены на 1 час. Для описательной части товара это я считаю приемлемым. Отзывы о товаре - нет (человек только что оставил отзыв, и его не видит).

Добавление параметра GET позволяет полностью инвалидировать кеш.

Допустим, вы обновляете каталог раз в сутки. Тогда новый URI будет содержать дату /api/products?d=15012018.

Если вы обновляете свой API с возможной "поломкой" обратной совместимости, добавьте версию API: /api/products?v=0.101.

Если кеш совершенно не приемлем, а запрос обрабатывается долго, смотрите в сторону ускорения производительности (в том числе оптимизации и кеширование отдельных SQL запросов, etc) и балансировки потока запросов на несколько веб-серверов.

Answer 2

Есть сайт, при загрузке одной страницы идут несколько десятков одинаковых запросов

Вместо десятков одинаковых запросов к /api/products надо сделать один запрос, который возвращает десятки значений.

Повторить то же самое для /api/objects. Проблема решена.

READ ALSO
Кодировать строку UTF-8 в URL-код php, js

Кодировать строку UTF-8 в URL-код php, js

Решение возможно на php и\или js

100
Не работают простые запросы типа SELECT

Не работают простые запросы типа SELECT

Храню в MySQL словарь: 1 таблица, 2 столбца (id и ru_word)Параметры второго столбца: тип Varchar(100), сравнение urf8_general_ci

103
Имена текстур assimp C++

Имена текстур assimp C++

Разбираюсь с структурой assimp Разработал класс на основе примера для рисования модели ни никак не могу понять как получить адрес файла с текстурой

135
C++ const char to char

C++ const char to char

имею структуру

120