> Как следить за работой оркестратора и какие метрики использовать для проверки корректности (Go)

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

Компании: InDrive

Стек: Go

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

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

Мониторинг оркестратора - это наблюдение за жизненным циклом задач, очередями, ошибками и производительностью. Ключевые метрики: количество активных/завершённых/упавших задач, время выполнения, глубина очередей, latency между планированием и стартом, rate повторов и poison messages. Для проверки корректности используем end-to-end трассировку, сверку фактического результата с ожидаемым (idempotency, exactly-once), и алерты на аномалии. В Go - экспорт метрик в Prometheus, трейсинг через OpenTelemetry, логирование структурированное.

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

Оркестратор (например, Temporal, Cadence, или самописный на Go) управляет распределёнными workflow. Следить за ним нужно на трёх уровнях:

  1. Инфраструктурный - здоровье самого оркестратора: CPU, память, GC pause, количество goroutine, размер heap. Если оркестратор падает - все workflow стопорятся.

  2. Уровень задач - метрики по каждому типу activity/workflow:

    • workflow_started_total, workflow_completed_total, workflow_failed_total - счётчики по статусам.
    • workflow_duration_seconds - гистограмма времени выполнения.
    • activity_execution_latency - время от планирования до фактического старта (scheduling latency).
    • activity_retry_count - распределение количества ретраев.
    • queue_depth - количество задач, ожидающих в очереди.
    • poison_message_total - задачи, которые упали после N ретраев и отправлены в DLQ.
  3. Корректность - метрики, которые проверяют, что результат соответствует ожиданиям:

    • workflow_sla_violation_total - если workflow не уложился в заданный SLA.
    • workflow_consistency_check_total - результат сверки с внешней системой (например, количество записей в БД после workflow).
    • idempotency_conflict_total - случаи, когда повторное выполнение дало другой результат.
    • out_of_order_total - события, пришедшие не в том порядке (для event-driven workflow).

Для проверки корректности также используем:

  • Tracing - OpenTelemetry, чтобы видеть полный путь задачи через все сервисы.
  • Audit log - запись каждого состояния workflow с timestamp.
  • Reconciliation - периодическая сверка состояния оркестратора с фактическим состоянием системы (например, количество активных задач в БД vs в памяти оркестратора).

На практике

В Go-проекте с Temporal или Cadence:

  • Экспортируем метрики через prometheus/client_golang - регистрируем кастомные коллекторы для workflow.
  • Используем go.temporal.io/sdk/contrib/opentelemetry для трейсинга.
  • Для самописного оркестратора - добавляем middleware, который оборачивает каждый шаг и записывает метрики.
  • Настраиваем алерты: если queue_depth растёт > N в течение 5 минут, если workflow_failed_total > 0.1% от общего числа, если scheduling_latency > 1 секунды.
  • Для проверки корректности - пишем интеграционные тесты, которые запускают workflow и проверяют побочные эффекты (записи в БД, вызовы внешних API). В проде - периодический reconciliation job, который сравнивает состояние оркестратора с источником правды.

Пример кода

GO
package main
import (
"github.com/prometheus/client_golang/prometheus"
"go.temporal.io/sdk/workflow"
)
var (
workflowDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "workflow_duration_seconds",
Help: "Duration of workflow execution",
Buckets: prometheus.DefBuckets,
},
[]string{"workflow_type", "status"},
)
schedulingLatency = prometheus.NewHistogram(
prometheus.HistogramOpts{
Name: "activity_scheduling_latency_seconds",
Help: "Time between activity scheduling and start",
},
)
queueDepth = prometheus.NewGauge(
prometheus.GaugeOpts{
Name: "workflow_queue_depth",
Help: "Current number of tasks waiting in queue",
},
)
)
func init() {
prometheus.MustRegister(workflowDuration, schedulingLatency, queueDepth)
}
// Пример workflow с метриками
func MyWorkflow(ctx workflow.Context, input Input) error {
start := workflow.Now(ctx)
err := workflow.ExecuteActivity(ctx, MyActivity, input).Get(ctx, nil)
status := "success"
if err != nil {
status = "failed"
}
workflowDuration.WithLabelValues("MyWorkflow", status).
Observe(workflow.Now(ctx).Sub(start).Seconds())
return err
}

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

Начни с разделения мониторинга на инфраструктурный и бизнес-уровень. Подчеркни, что метрики корректности - это не только счётчики ошибок, но и проверка соответствия результата ожиданиям (reconciliation, SLA). Упомяни конкретные инструменты: Prometheus, OpenTelemetry, структурированные логи. Если спросят про exactly-once - объясни, что метрики не гарантируют корректность, а лишь сигнализируют о проблемах; сама корректность обеспечивается идемпотентностью и проверкой побочных эффектов. Приведи пример из практики: как ты ловил проблему через метрику scheduling latency или queue depth.

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

  • Понимание жизненного цикла задач в оркестраторе: планирование, выполнение, ретраи, таймауты.
  • Умение отличать метрики производительности от метрик корректности.
  • Знание практических инструментов: Prometheus, Grafana, OpenTelemetry, Temporal/Cadence.
  • Понимание trade-off между метриками и реальной проверкой состояния системы.
  • Способность предложить конкретные алерты и пороговые значения.

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

  • Смешивание метрик производительности и корректности: latency - это не корректность.
  • Упоминание только счётчиков ошибок, без проверки результата.
  • Игнорирование scheduling latency - это ключевая метрика для оркестратора.
  • Отсутствие упоминания reconciliation - без него метрики не доказывают корректность.
  • Предложение собирать все метрики без приоритизации - интервьюер ждёт, что ты выделишь критичные.
  • Забывают про poison messages и DLQ - это важный индикатор проблем с корректностью.

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

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