GH GambleHub

Shadow-трафік і порівняння

1) Що таке Shadow-трафік і навіщо він потрібен

Shadow-трафік (він же traffic mirroring/dark launch) - це безпечна «прогонка» реальних запитів/подій на нову версію сервісу паралельно з продакшн-версією без впливу на користувачів. Результати нової версії не повертаються клієнту і не виробляють зовнішніх сайд-ефектів, а збираються в систему порівняння.

Ключові цілі:
  • Перевірка сумісності: схем, контрактів, бізнес-логіки.
  • Оцінка продуктивності: латентність, стійкість під реальним навантаженням.
  • Детекція дрейфу: відмінності у відповідях, розподілах, частоті помилок.
  • Підготовка до канареечних релізів: зниження ризику перед реальним перемиканням трафіку.
Коли застосовувати:
  • Переписування ядра/алгоритмів, міграції БД/кешів, перехід на інший рантайм/SDK, зміна провайдера зовнішнього API.

2) Архітектурні патерни Shadow-трафіку

2. 1 L7-проксі/шлюз (HTTP/gRPC)

Проксі приймає запит → віддає бойову відповідь зі старої версії → асинхронно дзеркалює копію запиту в «тінь».

Підходить для синхронних API.
Управління часткою/фільтром дзеркалювання: по дорозі, хедеру, користувачеві, тенанту.

Приклад (Envoy):
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 Зіставлення zapros↔otvet

Обов'язковий 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 релізів і прискорює еволюцію архітектури.

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Telegram
@Gamble_GC
Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.