Обзор архитектуры: дайте конечной точке вывода бесплатного уровня входной конверт, а не повторную попытку Рассмотрим приведенный ниже порядок событий, который любой клиент со слепыми повторами может создать для общей конечной точки вывода. В нем нет ничего экзотичного...
Обзор архитектуры: дайте конечной точке вывода бесплатного уровня входной конверт, а не повторную попытку
Рассмотрим приведенный ниже порядок событий, который любой клиент со слепыми повторами может создать для общей конечной точки вывода. В нем нет ничего экзотического, и именно в этом вся проблема.
t0 работник-1 отправляет запрос A (время обслуживания неизвестно, срок 30 с)
t1 worker-1 сдается через 30 секунд (A все еще выполняется на сервере)
t2 worker-1 повторяет попытку как A' (без ключа идемпотентности, без наблюдения)
t3 worker-2 отправляет B (считает, что емкость свободна)
Конечная точка t4 возвращает 429 для A' и B (сервер работает на пределе, не сломан)
t5 оба работника спят ~1 с, затем повторяют попытку (синхронизированное стадо)
Конечная точка t6 снова возвращает 429 (очередь никогда не опустошается)
Конечная точка никогда не отключалась. Мой клиент просто не имел теории о его возможностях, поэтому каждый тайм-аут становился новым решением о допуске, принимаемым процессом, который ничего не знал. Инвариант, который мне нужен, является узким и проверяемым: запрос может поступить в систему только в том случае, если его прогнозируемое ожидание укладывается в установленный срок, а повторная попытка никогда не может превысить наблюдаемую скорость обслуживания. Типичная реализация не сохраняет ни одной половины.
Это обзор архитектуры этой границы — набор ограничений, поток данных, область отказов.