Что можно добавить для сокращения количества обращений к стороннему API
Что проверяют
Отличаете ли вы меры, которые действительно уменьшают число вызовов, от тех, что просто ускоряют клиент. И понимаете ли, что у кэша есть вторая половина, инвалидация, без которой он превращается в источник устаревших данных.
Как отвечать
Сначала про сокращение обращений:
- кэш ответов по ключу запроса с явным сроком жизни:
functools.lru_cacheилиcachetoolsвнутри процесса, Redis как общий кэш для нескольких воркеров; - условные запросы по заголовкам
ETagиIf-None-MatchлибоLast-Modified: ответ 304 дешевле и у многих поставщиков считается иначе; - пакетирование: один запрос на список идентификаторов вместо цикла по ним;
- схлопывание одинаковых параллельных запросов, чтобы десять обработчиков сходили за одними данными один раз;
- вебхуки или выборка изменений с момента последней синхронизации вместо регулярного опроса;
- фоновое обновление справочников по расписанию, чтобы пользовательский запрос ходил только в свою базу.
Дальше про устойчивость: собственный ограничитель скорости, повторы только на 429 и 5xx с экспоненциальной паузой и случайной добавкой, уважение заголовка Retry-After, предохранитель, который перестаёт добивать упавшего поставщика. Отрицательные ответы тоже надо кэшировать, иначе запросы за несуществующим объектом уходят наружу каждый раз.
Где спотыкаются
Предлагают асинхронность как способ сократить обращения. aiohttp и общая сессия убирают ожидание и накладные расходы, но количество вызовов остаётся тем же, а лимит выбирается быстрее. Это ускорение клиента, а не экономия квоты.
Ставят кэш без срока жизни и без стратегии сброса. Через сутки приложение уверенно показывает цену, которой уже нет, и найти это по логам тяжело, потому что ошибок нет.
Полагаются на lru_cache в многопроцессной выкладке. У каждого воркера свой кэш, экономия делится на число процессов, после перезапуска всё начинается заново, а неограниченный размер держит ссылки на аргументы и незаметно растит память.