Май 2026 Интеграции · Продакшен 5 минут

Протухшая сессия: как один баг научил меня не доверять чужим API

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

Симптом

Часть запросов к API перевозчика возвращала ошибку авторизации, хотя учётные данные были верными. Перезапуск «лечил» проблему — на время. Классическая примета: если рестарт помогает, ищите состояние, которое живёт дольше, чем должно.

Причина

Чтобы не логиниться на каждый запрос, я кэшировал идентификатор сессии внешнего API. Логика выглядела разумно: сессия живёт долго, зачем дёргать авторизацию. Но у провайдера сессия могла умереть раньше заявленного срока — по их внутренним причинам, о которых документация умалчивала. Мой кэш продолжал уверенно отдавать труп.

Кэш чужого состояния — это всегда гипотеза о чужой системе. Гипотезы нужно проверять, а не постулировать.

Решение

  1. Консервативный TTL кэша — заметно короче официального времени жизни сессии.
  2. Инвалидация по факту: получил ошибку авторизации — сбрось кэш, получи новую сессию, повтори запрос один раз. Пользователь этого даже не видит.
  3. Логирование каждого перелогина: если сессии умирают чаще обычного, я узнаю об этом из логов, а не из письма клиента.

Три правила, которые я из этого вывел

  1. Чужой API врёт. Не по злому умыслу — просто документация описывает намерения, а не поведение. Проектируйте под поведение.
  2. Любой кэш должен уметь ошибаться дёшево. Стоимость промаха — один лишний логин. Стоимость протухшего значения без инвалидации — сломанный продакшен.
  3. Ретрай — часть интеграции, а не заплатка. Один повтор с обновлённой авторизацией закрывает целый класс проблем и пишется за полчаса.

Интеграция с внешним API — это на 20% «подключить» и на 80% «пережить все способы, которыми оно ломается». Если вам нужна интеграция, которая переживает, — напишите мне.