Конвеєр злиття, що надійно працює під навантаженням, не проєктується — він ітерується. Перша ітерація майже завжди провалюється з однієї причини: недостатньої дисципліни на шарі джерел і схем. Адаптери просочують специфічні для джерел поняття вгору за течією, схема треків недостатньо стабільна, щоб підтримати еволюцію, канонічна модель змішує поняття, які мали б залишатись окремими, і за пів року команда переписує рушій злиття, доки оператори ще користуються зламаним. Ця серія з чотирьох частин розповідає, як уникнути такого результату. Частина 1 охоплює фундамент: каталогізацію джерел, проєктування канонічної схеми треків і шар адаптерів, що тримає все інше чистим.

Архітектурне обрамлення цієї серії — у статті Повний посібник зі злиття оборонних даних. C2-аналог — побудова повного стека C2, у якому злиття є одним з компонентів — це паралельна серія, що починається з Побудови системи C2 з нуля, Частина 1. Ця серія йде вузько на підсистему рушій злиття плюс шар даних.

Крок 1: Каталогізуйте джерела, перш ніж писати код

Єдина діяльність з найвищим важелем на початку програми злиття — каталог джерел: документ, що описує кожен датчик, розвідувальний потік і зовнішній вхід, який платформа поглинатиме. Каталог нецікаво будувати, нецікаво читати — і критично важливо зробити правильно. Він стає контрактом, від якого залежить кожен подальший компонент.

Каталог фіксує для кожного джерела:

  • Ідентичність джерела — стабільний ідентифікатор, дружня назва, організація-власник.
  • Формат на дроті — категорія та версія ASTERIX, реліз STANAG 4586, AIS NMEA 0183, версія схеми CoT XML, версія NITF тощо.
  • Транспорт — UDP-multicast, TCP-unicast, MQTT-топік, HTTP-webhook, file drop. Включає адресацію, аутентифікацію, поставу шифрування.
  • Темп — частота повідомлень за номінального навантаження, пікова частота, очікувані інтервали тиші.
  • Профіль затримки — час спостереження проти часу доповіді проти часу поглинання. Одні джерела реального часу; інші мають пакетні затримки, виміряні в годинах.
  • Точність і невизначеність — що стверджує специфікація, що показують оперативні дані, як виглядають режими відмов.
  • Поставу класифікації — на якому рівні класифікації працює джерело, які компартменти застосовуються, які правила releasability керують даними.
  • Відомі режими відмов — обриви каналу, простої з боку джерела, поступова деградація, можливості навмисної маніпуляції.
  • Зіставлення схем — як кожне поле джерела зіставляється з канонічною схемою треків (заповнюється, щойно з'явиться схема).

Каталог — це версіонований артефакт, що зберігається в репозиторії поряд з кодом, переглядається інженерною командою та (де доречно) операційною спільнотою, чиї датчики його живлять. Нове джерело не вважається «інтегрованим», доки не має запису в каталозі; сама ця дисципліна запобігає найпоширенішому багаторічному рефакторингу у проєктах злиття.

Детальний розгляд викликів інтеграції джерел, зокрема мульти-INT семантика, що виринає в обороні, — у статті Виклики інтеграції оборонних даних.

Крок 2: Спроєктуйте канонічну схему треків

Трек — центральна структура даних будь-якої платформи злиття. Кожен адаптер виробляє треки; кожне рішення злиття оновлює треки; кожен споживач читає треки. Схема — це контракт, з яким платформа живе впродовж операційного життя, зазвичай 15-20 років. Витратьте спринт, щоб зробити її правильно; витратьте тиждень на її документування.

Мінімально життєздатна схема включає:

Track ID. Глобально унікальний, стабільний упродовж життя треку, ніколи не перевикористовуваний. UUIDv7 або типізований префікс плюс UUID — безпечний дефолт. ID є непрозорим — він не кодує джерело, ідентичність чи будь-який інший атрибут, що може змінитися.

Ідентичність. Структурований тип із трьома підполями: таксономія типу (судно, повітряне судно, транспортний засіб, особа, підрозділ, сигнал, некласифіковане-інше), підтип (точніша класифікація по доменах) та ідентифікуючі атрибути (бортовий номер, хвостовий номер, позивний, MMSI, ID транспондера). Ідентичність оновлюється злиттям у міру накопичення доказів; ID — ні.

Позиція та невизначеність. Широта, довгота, висота у WGS84 за замовчуванням. Невизначеність представлена або коваріаційною матрицею (бажано для кінематичного злиття), або великою/малою віссю з пеленгом (прийнятно для простіших випадків). Ніколи не одним числом невизначеності — це втрачає геометричну інформацію, потрібну злиттю.

Кінематичний стан. Вектор швидкості, кутова швидкість повороту, похідний курс/швидкість для відображення. Із часовою міткою моменту оцінки.

Набір джерел. Які адаптери внесли спостереження до цього треку, з класифікацією, releasability та довірою на джерело. Набір джерел — фундамент для поширення класифікації та аудиту. Детальний розгляд — у Пояснення військового злиття даних.

Три часові мітки. Час спостереження (коли датчик побачив об'єкт), час доповіді (коли повідомлення покинуло датчик), час поглинання (коли платформа його отримала). Змішування цих міток — найпоширеніше джерело багів в інженерії злиття. Операторам потрібен час спостереження; replay-аналітиці — час поглинання; різниця між ними оприявнює затримку датчика для моніторингу.

Стан життєвого циклу. Тентативний, підтверджений, зрілий, згасаючий, втрачений. Деталі state-machine — у Частині 2.

Конверт класифікації. Ефективна класифікація, обчислена з набору джерел. Теги releasability, обчислені як перетин releasability джерел. Маркування компартментів, де застосовно.

Довіра та певність. Довіра рівня треку як єдиний калібрований бал. Певність по атрибутах, де вона суттєво відрізняється — наприклад, трек може мати високу певність позиції, але тентативну ідентичність.

Крок 3: Зобов'яжіться до додавального розвитку схеми

Схема еволюціонуватиме. Потрібні нові атрибути; виринатимуть рідкісні випадки, яких початковий дизайн не передбачав. Дисципліна, що тримає платформу операційною крізь цю еволюцію, — це додавальне версіонування (additive-only versioning).

Правила:

  • Нові поля — необов'язкові. Наявні споживачі ігнорують їх, доки не оновляться. Виробники заповнюють їх, коли релевантні дані доступні.
  • Наявні поля ніколи не змінюють семантику. Поле, що сьогодні означає «швидкість у м/с», має означати «швидкість у м/с» назавжди. Зміна сенсу вимагає нового поля, а не зміни на місці.
  • Видалення — це депрекації. Поле, позначене як deprecated, залишається у схемі; нові виробники припиняють його писати; нові споживачі припиняють його читати; старі дані продовжують працювати безстроково.
  • Ламкі зміни — це підняття мажорної версії. Вони трапляються — рідко. Коли трапляються, міграція документується, тестується та координується з усіма споживачами. Ламка зміна має статися щонайбільше раз за життя платформи, а не раз за реліз.

Обгорніть схему в кодогенеровану клієнтську бібліотеку, спільну для кожної мови споживача. Схема-як-код запобігає повільному розходженню, що інакше призводить до «платформа злиття v3.4 в сервісі A, v3.6 в сервісі B, v4.0 в сервісі C» — оперативного жаху, з яким стикається кожна програма злиття без цієї дисципліни.

Ключова думка: Схема треків — найвпливовіший артефакт платформи. Схеми, спроєктовані в перший тиждень як додавальні, переживають 20 років операційної еволюції. Схеми, спроєктовані неформально і доточені пізніше, стають джерелом багатомісячного рефакторингу, що випускається кожні два роки. Інвестуйте спринт наперед; пожинайте вигоду впродовж життя платформи.

Крок 4: Будуйте шар адаптерів зі суворою ізоляцією

Шар адаптерів перекладає нативний формат кожного джерела в канонічну схему треків. Архітектурне правило брутальне й варте запам'ятовування: жодне специфічне для датчика поняття не просочується за адаптер. Якщо код вашого рушія злиття згадує категорії ASTERIX — у вас протікаюча архітектура. Якщо ваше сховище треків має колонку для типів повідомлень AIS — у вас протікаюча архітектура. Правило структурне — порушите одного разу, і ціна капіталізується крізь роки.

Структура добре спроєктованого адаптера, у чотирьох шарах:

Транспорт. Конектор до джерела. UDP-сокет, TCP-listener, MQTT-підписка, HTTP-webhook, file-watcher. Стійкий до відмов з боку джерела: автоматичне перепідключення з backoff, облік втрачених повідомлень, телеметрія, експортована в моніторинговий стек платформи.

Парсер. Перекладає формат на дроті в строго типізовану внутрішньопроцесну структуру. Валідує проти специфікації формату. Відкидає малформований вхід гучно, зі структурованим логуванням, що оприявнює малформацію, ідентифікатор джерела й часову мітку. Тихе відкидання поганого входу — неправильний дефолт: воно ховає операційні проблеми, які мали б бути оприявнені.

Нормалізатор. Зіставляє специфічні для джерела поля з полями канонічної схеми. Конверсія системи координат (зазвичай у WGS84). Нормалізація часових міток у UTC з дисципліною трьох часових міток. Нормалізація полів ідентичності крізь різні способи, якими той самий бортовий номер чи позивний може форматуватись у різних джерелах.

Емітер. Публікує канонічне оновлення треку на шину повідомлень платформи, з тегами ідентифікатора джерела, класифікації джерела, releasability та свіжою часовою міткою поглинання. Емітер — єдиний компонент в адаптері, що знає про платформу; усе вище за течією від нього — ізольований код, специфічний для джерела.

Кожен адаптер працює як окремий сервіс або процес. Вони ділять кодогенеровану клієнтську бібліотеку для канонічної схеми, але жодних інших шляхів коду. Додавання нового джерела означає написання нового адаптера; це не зачіпає жодного іншого компонента. Детальні патерни інтеграції для найпоширеніших оборонних джерел — у Інтеграція AIS і ADS-B у військову картину, а CoT-бік — у Cursor on Target (CoT).

Крок 5: Підключіть адаптери до тривкої шини повідомлень

Адаптери публікують у тривкий, упорядкований, партиціонований лог. Сервіси злиття його споживають. Як і аудит, історичний replay та подальша аналітика. Шина повідомлень — спинний мозок платформи злиття.

Патерн, що масштабується: Kafka або NATS JetStream як тривкий лог подій; топік-на-тип-джерела на вході; топік-на-тип-виходу на боці злиття. Адаптери публікують у raw.<source-type>; рушій злиття їх споживає та публікує в tracks.updates, tracks.lifecycle, tracks.classification. Споживачі підписуються на ті топіки, що їм потрібні.

Детальні компроміси між Kafka і NATS, дисципліна моделювання топіків і операційні міркування — у Черги повідомлень для оборонних конвеєрів даних.

Архітектурне правило, варте оприявнення: не викликайте HTTP між компонентами злиття. Синхронне request-response з'єднання між адаптерами, сервісами злиття та споживачами робить конвеєр ламким. Сплеск датчиків, що стопорить одного споживача, не повинен стопорити бік виробника. Шина з обробкою backpressure — структурне рішення; HTTP між компонентами злиття — повторюване джерело простоїв.

Крок 6: Перевіряйте каталог джерел проти реальності

Каталог джерел — це гіпотеза, доки не перевірений. Дисципліни, що валідують його, перш ніж конвеєр піде в експлуатацію:

Replay захоплених даних. Для кожного джерела захопіть дні чи тижні реального трафіку в форматі на дроті у файл. Програвайте файл проти адаптера на оригінальній швидкості й на прискореній. Адаптер, що тримає реальні дані на 10× швидкості, — це адаптер, що витримає операційні сплески датчиків; адаптер, що тримає лише каталог-синтетичні дані, ще не готовий.

Тестування ворожого входу. Інжектуйте малформовані повідомлення, підроблений AIS, радарні плоти, що порушують фізику (наземні треки на Mach 5), CoT XML із порушеннями схеми. Адаптер мусить відхиляти їх гучно, не падати, не тихо поширювати. Дисципліна продовжується в самому рушії злиття — розглянуто у Поясненні військового злиття даних.

Тести round-trip схеми. Кожен адаптер мусить вміти round-trip свій нативний вхід через канонічну схему й назад, зберігаючи оперативно-значущі поля. Lossy-адаптер — це провал дизайну, що оприявнюється через місяці під час conformance-тестування.

Аудит каталогу проти реальних виробничих даних. Щойно конвеєр запрацює в пілотному розгортанні, проведіть аудит каталогу джерел проти реальних даних поглинання. Джерела, що виробляють атрибути, яких каталог не передбачав, затримки, що перевищують очікування каталогу, або режими відмов, не задокументовані в каталозі, — це знахідки, що оновлюють каталог, адаптер або обидва.

Що далі

Частина 1 охопила фундамент. Джерела каталогізовані, канонічна схема треків спроєктована з додавальним розвитком, адаптери побудовані зі суворою ізоляцією, шина повідомлень підключена, дисципліни тестування, що валідують шар. Конвеєр тепер поглинає дані джерел і виробляє канонічні спостереження треків на шині — але ці спостереження ще не корельовані в треки.

Частина 2: Кореляція треків та управління життєвим циклом бере канонічний потік спостережень і будує серце рушія злиття. Гейтинг на правилах, ймовірнісна асоціація даних (JPDA, MHT), state-машина життєвого циклу та сховище треків як event-sourced read model.