Зафиксируйте ожидания потребителя в контракте и проверяйте новую версию провайдера против него в CI. Интеграционный тест должен проверять не только JSON-схему, но и смысл полей и ошибок.
Исправьте изменяемый аргумент по умолчанию, проверьте блокирующий API-вызов и разделите ошибки клиента и отдельного заказа. Повторный импорт должен быть идемпотентным.
Независимость данных означает владение каждым сервисом своей моделью и запрет прямой записи в чужие таблицы. Обмен идёт через API или события с явными контрактами.
Сначала измерьте число и длительность SQL-запросов, затем устраните подтверждённый N+1 через подходящую загрузку связей. Кеширование не должно маскировать необъяснённую дорогую выборку.
Semaphore ограничивает число одновременных запросов, а не RPS. Для жёсткого ограничения скорости нужен отдельный временной лимитер, который разрешает старт только в допустимый момент.
Health checks позволяют системе понять, жив ли процесс и готов ли он принимать запросы. Liveness и readiness решают разные задачи и не должны проверять одно и то же без разбора.
Сервисы находят друг друга через service discovery: DNS, реестр или стабильную точку балансировки. Приложение обращается к имени сервиса, а не хранит случайные IP экземпляров.
Для двустороннего live-чата обычно подходит WebSocket, для односторонней браузерной ленты — SSE, для типизированного межсервисного streaming — gRPC. Выбор меняется при других требованиях.
threading.local() хранит состояние по потоку, а несколько async-запросов работают в одном потоке и могут перезаписать request_id друг друга. ContextVar разделяет значения по контексту задачи.
Нужно атомарно проверить и уменьшить лимит в том месте, где он хранится: командой/скриптом Redis для общего состояния либо asyncio.Lock для одного процесса. Измерение ожидания полезно дополнительно.
Опишите события переходов заявки, ключ partition по заявке, надёжную публикацию и идемпотентных потребителей. Консистентность между сервисами обычно достигается с задержкой, а не общей транзакцией Kafka и БД.
Если это обработчики обычного def и в thread pool есть два свободных места, оба запроса завершатся примерно за 5 секунд, а не последовательно за 10. Точное время зависит от загрузки.