Shadow-трафик и сравнение
1) Что такое Shadow-трафик и зачем он нужен
Shadow-трафик (он же traffic mirroring / dark launch) — это безопасная «прогонка» реальных запросов/событий на новую версию сервиса параллельно с продакшен-версией без влияния на пользователей. Результаты новой версии не возвращаются клиенту и не производят внешних сайд-эффектов, а собираются в систему сравнения.
Ключевые цели:- Проверка совместимости: схем, контрактов, бизнес-логики.
- Оценка производительности: латентность, устойчивость под реальной нагрузкой.
- Детекция дрейфа: различия в ответах, распределениях, частоте ошибок.
- Подготовка к канареечным релизам: снижение риска перед реальным переключением трафика.
- Переписывание ядра/алгоритмов, миграции БД/кэшей, переход на другой рантайм/SDK, смена провайдера внешнего API.
2) Архитектурные паттерны Shadow-трафика
2.1 L7-прокси/шлюз (HTTP/gRPC)
Прокси принимает запрос → отдает боевой ответ из старой версии → асинхронно зеркалирует копию запроса в «тень».
Подходит для синхронных API.
Управление долей/фильтром зеркалирования: по пути, хедеру, пользователю, тенанту.
yaml route:
route:
cluster: prod-v1 request_mirror_policies:
- cluster: shadow-v2 runtime_fraction:
default_value:
numerator: 10 # 10% denominator: HUNDRED trace_sampled: true
Пример (Nginx):
nginx location /api/ {
proxy_pass http://prod_v1;
mirror/shadow; # request copy
}
location = /shadow {
internal;
proxy_pass http://shadow_v2; # answer ignored
}
2.2 Шины событий (Kafka/Потоки)
На уровне топика делается tee:- Продюсер пишет как обычно → консюмеры prod читают.
- Параллельно «тень» (shadow-pipeline) читает тот же поток в отдельную песочницу.
Опции: MirrorMaker/Replicator, dual-write (осторожно), бриджи «source → prod + shadow».
2.3 Replayer (запись/воспроизведение)
Снимок реальных запросов/трейсов (PCAP/NGINX access, gRPC taps) → проигрывание в «тень» с контролируемым темпом.
2.4 «Синтетическая тень»
Генерация нагрузочного профиля из прод-логов + фазы дозаполнения краевых кейсов — полезна при ограничениях конфиденциальности.
3) Изоляция состояния и сайд-эффектов
Золотое правило: тень не изменяет внешний мир.
Рид-онли доступ к БД/кэшу или отдельная песочница (snapshot/реплика).
Запрет исходящих побочек: платежи, письма, пуши, webhooks → stub/blackhole/record-only.
Идемпотентность на уровне команд/POST: Shadow не должен регистрироваться как повтор оригинала.
Маскирование PII/секретов, токены тестовых провайдеров.
Пример: маскирование в зеркале
yaml shadowFilter:
headers:
redact:
- Authorization
- X-Api-Key body:
jsonPaths:
- replace "$ .email" # with token
- "$.card. number"
4) Стратегии семплирования и безопасная нагрузка
Доля трафика: 1–10% на старте; повышать, если v2 укладывается в бюджет.
Критерии отбора: по маршруту, пользователю, размеру запроса, типу операции (GET-ы безопаснее).
Перф-бюджет: зеркалирование не должно увеличивать p95/p99 боевого сервиса. Тень всегда асинхронна.
Back-pressure: при перегреве shadow-цепочки — дропать тень, а не боевые запросы.
Время: минимум 24–72 часа, чтобы покрыть суточные и пиковые паттерны.
5) Сравнение результатов: методы и уровни
5.1 Уровни сравнения
1. Байтовый дифф: тело ответа/события один-в-один. Просто, но хрупко (таймстемпы, порядок ключей).
2. Семантический дифф: нормализуем и сортируем поля, игнорируем эпемериды (traceId, timestamps, counters).
3. Бизнес-инварианты: те же ли суммы, статусы, количества, границы.
4. Статистический анализ: распределения метрик совпадают? (p50/p95, KS-тест, χ² на категориальные).
5.2 Политика сравнения
Маски/ignore-списки полей (напр., `updatedAt`, `etag`).
Точность: абсолютная/относительная погрешность для чисел (например, ±1e-6).
Допуски (tolerance bands): «разница в цене ≤ 0.01», «ошибок не больше +0.1% относительно prod».
Псевдокод компаратора
pseudo compare(prod, shadow, policy):
a = normalize(prod, policy)
b = normalize(shadow, policy)
diffs = deepDiff(a, b, ignore=policy. ignore, floatTol=policy. floatTol)
invariants_ok = checkInvariants(a, b, policy. invariants)
return Result(diffs, invariants_ok)
5.3 Сопоставление запрос↔ответ
Обязателен Correlation-ID (прокидывать в тень).
Линковка спанов: shadow-трасса получает link на боевую.
6) Наблюдаемость и артефакты сравнения
Метрики:- `shadow_requests_total{route,...}`
- `shadow_discrepancies_total{type=byte|semantic|invariant}`
- `shadow_error_ratio` и `shadow_slo_breach_total`
- Перф: `shadow_latencies_ms{p50,p95,p99}`
- Логи диффов: компактные JSON-дельты по ключам.
- Отчетность: ежедневный отчет с топ-N расхождений, тепловые карты по маршрутам/тенантам.
- UI «diff explorer»: фильтры по типу, маршруту, полю, export в CSV.
7) Особые случаи и тонкости
7.1 Последовательность и консистентность
Shadow-запросы могут приходить позже/раньше; нормализуйте по версиям/часам (Lamport/vector) или допускам окна.
Read-after-write: тень с read-replica без синхронной репликации даст разные ответы — сравнивайте через лаг-окна.
7.2 Кэш/рекомендации
Не смешивайте кэши prod и shadow.
Для ML/рекомендателей сравнивайте онлайн-метрики и оффлайн-метрики отдельно; следите за drift входных признаков.
7.3 Внешние провайдеры
Оборачивайте клиенты record-only/stub-режимом.
Для расчетных сервисов (налоги, курсы) — фиксируйте снимок справочников для обеих сторон.
8) Сопоставление с канареечными/blue-green
Shadow: нулевой риск для пользователей, но нет реальных сайд-эффектов; прекрасно для логики и перфа.
Canary: малый процент реальных ответов от новой версии; требует готовой стратегии отката и SLA.
Blue-green: мгновенное переключение после валидации; Shadow часто используется перед ним.
9) План внедрения (GitOps-стиль)
1. Цели и метрики: какие инварианты и допуски проверяем, какой SLO на расхождения.
2. Трассировка: Correlation-ID, распределенные трейс-линки.
3. Прокси-настройка: mirror-политика, семплирование, redaction.
4. Изоляция: песочница БД/кэш, заглушки побочек, тестовые ключи.
5. Компаратор: нормализация, ignore-мапы, инварианты, отчеты.
6. Нагрузочный план: старт с 1–5%, рост до 20–50% при зеленых метриках.
7. Наблюдаемость: дашборды «расхождения/перф/объем».
8. Критерии выхода: «0 критических расхождений 48 ч», «ошибки не хуже prod», «перф в пределах ±5%».
9. Переход к canary: включить реальные ответы с безопасной долей и автоматическими гард-правилами.
10) Примеры конфигураций
10.1 Istio (Traffic Mirroring)
yaml apiVersion: networking. istio. io/v1beta1 kind: VirtualService spec:
hosts: ["svc. example"]
http:
- route: [{ destination: { host: svc, subset: v1 } }]
mirror:
host: svc subset: v2 mirrorPercentage:
value: 0. 1 # 10%
10.2 Kafka Tee (эскиз)
text source-topic -> prod-consumer-group
-> shadow-consumer-group (isolated sink/db)
10.3 Правила сравнения (yaml-политика)
yaml ignoreFields:
- $.traceId
- $.meta. generatedAt floatTolerance:
default: 1e-6 fields:
$.price: 0. 01 invariants:
- name: "nonNegativeTotal"
expr: "$.total >= 0"
- name: "statusMapping"
expr: "map($.status in ['ok','fail'], true)"
11) Анти-паттерны
Shadow пишет наружу: реальные платежи/уведомления из тени.
Общий кэш/общие очереди: перекрестное влияние и загрязнение.
Отсутствие нормализации: байтовые диффы «краснят» из-за часов/порядка ключей.
Слишком высокий процент с ходу: деградация перфа prod.
Долгая «вечная тень»: вторая система живет отдельно и расходится с реальностью.
12) Чек-лист запуска Shadow-режима
- У прокси настроен mirror с долей и redaction.
- Тень изолирована: БД/кэши/внешние интеграции — только readonly/stub.
- Везде прокинут Correlation-ID; трассировки линкуются.
- Компаратор умеет ignore/normalize и проверку инвариантов.
- Дашборды и алерты на расхождения и нагрузку.
- Семплирование по маршрутам/тенантам; лимиты и back-pressure.
- Определены допуски и критерии «зеленого света».
- План перехода к canary/blue-green и отката.
13) FAQ
Q: Чем Shadow отличается от A/B?
A: В A/B обе версии возвращают ответы пользователям (сплит-эксперимент), в Shadow новая версия не влияет на пользователя — ее ответы только анализируются.
Q: Можно ли шадовить POST/PUT?
A: Да, если гарантирована изоляция побочек (stub) и идемпотентность. Часто начинают с GET, затем расширяют.
Q: Как сравнивать ответы, если порядок элементов нефиксирован?
A: Сортируйте по устойчивому ключу перед сравнением или сравнивайте как множества/по ключам.
Q: Что делать с задержками реплик БД?
A: Вводите «окна сравнения» и снапшоты справочников; агрегируйте результаты по версиям, а не по «стеночасу».
14) Итоги
Shadow-трафик — это «безболезненная репетиция продакшена»: реальная нагрузка, нулевой риск для пользователей, детальная аналитика расхождений. Успех определяется изоляцией, правильным семплированием, качественным компаратором и наблюдаемостью. Следуя предложенному плану, вы получите воспроизводимую практику, которая уверенно мостит путь к canary/blue-green релизам и ускоряет эволюцию архитектуры.