Безопасный scope: Это руководство применимо только к собственным или явно авторизованным QA-, staging- и production-средам. Описаны сценарии диагностики, тестирования и наблюдаемости вашей собственной CAPTCHA-интеграции — не для сторонних сайтов и не для несанкционированных workflow.
TTL ключа в Redis всегда должен быть короче, чем время жизни токена у провайдера проверки. Выставите их равными — и получите класс багов, который почти невозможно воспроизвести локально: токен лежит в кеше, EXISTS возвращает 1, а проверка на стороне провайдера отвечает timeout-or-duplicate. Ниже — как выбрать запас, как собрать идемпотентный ключ, как не отправить пять одинаковых задач вместо одной и по каким метрикам видно, что TTL подобран неверно.
Кеш здесь нужен не ради экономии. У CaptchaAI тарификация по потокам, а не по решениям: в любом тарифе от BASIC ($15/мес, 5 потоков) до VIP-3 ($7,500/мес, 5000 потоков) число решений в месяц не ограничено. Redis решает другую задачу — согласовать состояние между узлами и убрать дубли задач.
Как выбрать запас по времени
Запас — это разница между TTL провайдера и TTL ключа. Он должен покрывать три вещи: сетевой путь от Redis до обработчика, время самой отправки формы и разброс часов между узлами. Для одного дата-центра хватает примерно 10 % от TTL; для распределённой установки — скажем, воркеры в европейском регионе, а приложение на хостинге в Казахстане — закладывайте 20–30 с.
| Тип проверки | TTL у провайдера | TTL ключа Redis | Запас |
|---|---|---|---|
| reCAPTCHA v2 | 120 с | 110 с | 10 с |
| reCAPTCHA v3 | 120 с | 110 с | 10 с |
| Cloudflare Turnstile | 300 с | 270 с | 30 с |
| GeeTest v3 | 120 с | 110 с | 10 с |
Значения во втором столбце — заявленный срок жизни токена у самого провайдера проверки, а не характеристика CaptchaAI. Если ваш обработчик регулярно стоит в очереди дольше запаса, уменьшайте TTL ключа, а не растягивайте его.
Запись с истечением: одна команда вместо двух
SETEX ставит значение и срок жизни одной операцией. Связка SET плюс отдельный EXPIRE создаёт окно, в котором ключ уже существует, а срока у него ещё нет: падение процесса ровно в этот момент оставляет вечный ключ в памяти.
import redis, time
r = redis.Redis()
def remember(idem: str, token: str, ttl: int) -> None:
r.setex(f'captcha:{idem}', ttl, token)
def get(idem: str) -> str | None:
v = r.get(f'captcha:{idem}')
return v.decode() if v else None
Идемпотентный ключ idem собирайте из контекста запроса: sitekey, идентификатор сессии или заказа, тип проверки. Ничего пользовательского в нём быть не должно — один ключ на двух пользователей означает, что чужой токен уйдёт в чужую форму.
Дедупликация задач через SETNX
Типичная картина под нагрузкой: пять воркеров одновременно видят промах кеша и отправляют пять одинаковых задач. Потоки заняты, счёт не растёт (тариф не зависит от числа решений), но задержка увеличивается, а четыре токена сгорают невостребованными.
Лечится блокировкой. Перед отправкой задачи выполните SET lock:<idem> 1 NX EX 120. Тот воркер, который получил OK, отправляет задачу в CaptchaAI; остальные короткими интервалами ждут появления ключа с токеном и забирают готовый результат. TTL на самой блокировке обязателен: если воркер упадёт до DEL, ключ снимется сам через две минуты и очередь не встанет намертво.
Что писать в логи
Структурированные логи помогают сравнивать поведение CAPTCHA между релизами и быстро находить регрессии в собственных формах:
import json, time, logging
log = logging.getLogger('captcha-qa')
def record(event: str, **fields) -> None:
payload = {'ts': time.time(), 'event': event, **fields}
log.info(json.dumps(payload, ensure_ascii=False))
Минимальный набор полей для каждой попытки: slug, captcha_type, task_id, wait_seconds, verify_status, env. Этого достаточно, чтобы построить дашборд медианы / P90 / P99 по типу проверки и по среде.
Отдельно считайте captcha_token_expired_in_use — число случаев, когда токен из кеша был отвергнут при проверке. Пока счётчик около нуля, запас подобран верно. Как только он растёт вместе с нагрузкой, дело не в провайдере, а в слишком длинном TTL ключа.
Если в логи попадают идентификаторы пользователей, держите в уме 152-ФЗ «О персональных данных» и его зарубежные аналоги: пишите только те поля, которые вы вправе обрабатывать. Сам токен в открытый лог не кладите — по сути это одноразовый пароль.
Память и вытеснение
Ключи без TTL — главная причина роста памяти под Redis. Проверяется быстро: redis-cli --scan --pattern 'captcha:*', затем точечный TTL по выборке; значение -1 означает вечный ключ. Для кеша токенов включите maxmemory-policy allkeys-lru — при нехватке памяти Redis вытеснит самые холодные записи вместо того, чтобы отвечать ошибкой на запись.
Диагностика частых симптомов
| Симптом | Вероятная причина | Что сделать |
|---|---|---|
| Токен из кеша отвергнут при проверке | TTL ключа почти равен TTL провайдера | Увеличьте запас на 20–30 с |
| Низкая доля попаданий в кеш | Идемпотентный ключ слишком детальный | Уберите из ключа изменчивые поля |
| Растёт объём памяти | Есть ключи без TTL | Пишите через SETEX, включите allkeys-lru |
| Дубли задач в CaptchaAI | Нет блокировки перед отправкой | SET ... NX EX 120 на время решения |
| Очередь встала после падения воркера | Блокировка без срока жизни | Добавьте EX к ключу блокировки |
QA-чек-лист перед выкатом
- Запрос отправляется только на собственные или авторизованные endpoints.
- Тестовые учётные записи, события и платежи помечены как фиктивные.
- CAPTCHA-токен проверяется на собственном backend, а не доверяется клиенту.
- Каждый ключ получает TTL в той же команде, что и значение.
- Логи содержат
task_id, тип проверки, время ожидания и pass/fail. - Скрипт возвращает корректный exit code, чтобы CI мог принять решение.
FAQ
Какой запас ставить, если воркеры в разных регионах?
Возьмите P99 задержки между узлом Redis и обработчиком, прибавьте время отправки формы и округлите вверх. На практике для распределённой установки это 20–30 с, для одного дата-центра — около 10 с.
Почему SETEX, а не SET плюс EXPIRE?
Две команды дают окно, в котором ключ уже есть, а срока жизни у него нет. Падение процесса ровно в этот момент оставляет ключ в памяти навсегда — именно так набираются «утечки» на десятки гигабайт.
Нужно ли шифровать токены в Redis?
Токен живёт минуты и одноразовый, поэтому шифрование значения обычно избыточно. Важнее закрыть доступ к инстансу на уровне сети и requirepass, а в логи и трассировки токен не писать.
Как понять, что кеш вообще окупается?
Сравните долю попаданий и captcha_token_expired_in_use за неделю. Если попаданий меньше трети, а просрочки заметны, проще решать задачу каждый раз напрямую и оставить Redis только под блокировки.
Влияет ли кеширование на стоимость тарифа?
Нет. CaptchaAI считает параллельные потоки, а не решения, поэтому кеш экономит время ожидания, а не деньги. Тариф подбирают по нужному числу одновременных задач.
Смежные руководства
- Быстрый старт CaptchaAI
- QA-тестирование CAPTCHA в авторизованных средах
- Тестирование CAPTCHA API на собственных формах
- Отладка: браузерный тест падает, API проходит
- Решение reCAPTCHA v2 через API
- Решение Cloudflare Turnstile через API
- Решение GeeTest v3 через API
Нужен рабочий TTL-слой уже сегодня? Получите API-ключ CaptchaAI.