> Как понимать доступность сервиса (Python)

Уровень: senior · Роль: backend · Язык: Python · Категория: Технические вопросы

Компании: Сбер

Стек: Python

> Пример ответа

Короткий ответ

Доступность сервиса - это метрика, показывающая долю времени, в течение которого сервис успешно обрабатывает запросы, относительно общего времени наблюдения. Обычно выражается в процентах (например, 99.9%) и рассчитывается как uptime / (uptime + downtime). Важно различать доступность инфраструктуры (сервер поднят) и доступность с точки зрения пользователя (запросы реально проходят и возвращают корректный ответ). Для senior-позиции ключевое - понимать trade-off между высокой доступностью и стоимостью её обеспечения, а также уметь проектировать системы под целевой SLO.

Подробное объяснение

Доступность - это не просто "сервер работает". Это комплексная характеристика, которая включает:

  • Uptime - время, когда сервис отвечает на запросы корректно.
  • Downtime - время, когда сервис недоступен или отвечает с ошибками (5xx, таймауты).
  • SLO (Service Level Objective) - целевой уровень доступности, например 99.95% за месяц.
  • SLA (Service Level Agreement) - договорное обязательство, часто с финансовыми последствиями при нарушении.

Ключевая идея: доступность всегда считается за определённый интервал (сутки, месяц, год). Для 99.9% допустимый downtime - около 43 минут в месяц, для 99.99% - около 4.3 минут. При этом важно понимать, что доступность бывает:

  • Инфраструктурная - сервис запущен, порт слушается, healthcheck проходит.
  • Функциональная - сервис выполняет бизнес-логику и возвращает корректные данные.
  • Пользовательская - реальный клиент получает ответ за приемлемое время.

Для распределённых систем доступность определяется слабым звеном: если один компонент недоступен, страдает весь сервис. Поэтому на практике используют избыточность (redundancy), отказоустойчивость (failover), балансировку нагрузки и деградацию функциональности (graceful degradation).

Также важна связь доступности с другими метриками: latency, error rate, throughput. Высокая доступность не означает, что сервис быстрый - он может отвечать медленно, но стабильно. Однако пользовательский опыт страдает, поэтому часто используют SLO на latency (например, p99 < 200ms).

На практике

Для backend-разработчика на Python доступность означает:

  1. Мониторинг - настройка healthcheck-эндпоинтов (/health, /ready), метрик в Prometheus, алертов в Alertmanager.
  2. Graceful shutdown - корректная обработка сигналов SIGTERM/SIGINT, завершение in-flight запросов.
  3. Retry и timeout - на стороне клиента и сервера, чтобы избежать каскадных отказов.
  4. Circuit breaker - защита от перегрузки зависимых сервисов.
  5. Резервирование - несколько инстансов за load balancer, репликация БД.
  6. Деплой без даунтайма - rolling update, blue-green, canary.
  7. Тестирование отказов - chaos engineering, проверка поведения при падении БД, Redis, внешних API.

Для Python-стека типичные проблемы: GIL не влияет на доступность напрямую, но блокирующие операции в sync-коде могут создавать "молчаливые" деградации. Асинхронные фреймворки (FastAPI, aiohttp) требуют аккуратной работы с blocking calls - иначе event loop блокируется и сервис перестаёт отвечать.

Пример кода

PYTHON
# Пример healthcheck для FastAPI с проверкой зависимостей
from fastapi import FastAPI, Response
import redis
import psycopg2
app = FastAPI()
@app.get("/health")
async def health(response: Response):
# Проверяем только сам процесс - сервис жив
return {"status": "ok"}
@app.get("/ready")
async def ready(response: Response):
# Проверяем зависимости - сервис готов принимать трафик
try:
r = redis.Redis(host="localhost", port=6379)
r.ping()
except Exception:
response.status_code = 503
return {"status": "unavailable", "dependency": "redis"}
try:
conn = psycopg2.connect("dbname=app user=app")
conn.close()
except Exception:
response.status_code = 503
return {"status": "unavailable", "dependency": "postgres"}
return {"status": "ready"}
PYTHON
# Пример graceful shutdown для aiohttp
from aiohttp import web
async def handle(request):
return web.Response(text="ok")
async def cleanup(app):
# Закрываем пулы соединений, сохраняем состояние
print("Shutting down gracefully")
app = web.Application()
app.router.add_get("/", handle)
app.on_cleanup.append(cleanup)
if __name__ == "__main__":
web.run_app(app, host="0.0.0.0", port=8080)

Как отвечать на собеседовании

Начни с формального определения: доступность = uptime / (uptime + downtime). Затем переходи к практическим аспектам: как измеряем, какие SLO ставим, как обеспечиваем. Обязательно упомяни разницу между инфраструктурной и пользовательской доступностью - это показывает глубину понимания.

Расскажи про конкретный опыт: как ты настраивал мониторинг, какие алерты ставил, как деплоил без даунтайма. Приведи пример из своей практики, когда сервис "падал" и как ты это диагностировал. Если спросят про 99.9% - посчитай допустимый downtime и объясни, почему для критичных сервисов этого мало.

Покажи системное мышление: доступность - это не только код, но и процессы (он-call, runbooks, postmortem). Упомяни, что высокая доступность имеет цену - дополнительные инстансы, репликация, сложность операций.

Что проверяет интервьюер

Интервьюер оценивает:

  • Понимание базовых метрик и их взаимосвязи (availability, latency, error rate).
  • Умение проектировать отказоустойчивые системы - не просто "сделать реплику", а объяснить trade-off.
  • Практический опыт с мониторингом и алертингом - какие инструменты, какие пороги.
  • Понимание жизненного цикла запроса и точек отказа (network, DNS, LB, app, DB).
  • Способность рассуждать о SLO/SLA и их влиянии на архитектуру.
  • Знание специфики Python: async vs sync, GIL, блокирующие вызовы.

Для senior-уровня важно показать, что ты думаешь не только о коде, но и об эксплуатации: как деплоить, как откатываться, как диагностировать инциденты.

Типичные ошибки

  • Сводить доступность только к uptime - игнорировать latency и error rate.
  • Не различать health и readiness - сервис может быть жив, но не готов принимать трафик.
  • Забывать про зависимости - доступность сервиса зависит от БД, Redis, внешних API.
  • Не учитывать пользовательский опыт - сервис "доступен", но отвечает за 10 секунд - это фактически недоступность.
  • Путать SLO и SLA - SLO это внутренняя цель, SLA - внешнее обязательство.
  • Не упоминать graceful degradation - при отказе зависимости можно отдавать частичный функционал, а не падать целиком.
  • Игнорировать деплой - даже идеальный код не поможет, если релиз приводит к даунтайму.
  • Не говорить про мониторинг - без метрик и алертов доступность невозможно контролировать.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью