Перейти к содержимому
IMOEX 2209.84 0.6%
·Технологии·31 июля 2026 г.

"__TypeId__": как один Kafka-заголовок незаметно связывает микросервисы именами Java-классов

"__TypeId__": как один Kafka-заголовок незаметно связывает микросервисы именами Java-классов

Если два сервиса обмениваются JSON, но один из них не может десериализовать сообщение без знания полного имени Java-класса другого сервиса - значит, транспортный контракт зависит не только от данных, но и от реализации.

Звучит как теория? Увы, но это суровая практика Spring Kafka, с которой многие разработчики имеют дело каждый день.

Вы пишете сервис A, сериализуете объект в JSON, отправляете в kafka-топик. Консьюмер сервиса B, который понятия не имеет о существовании класса com.company.a.event.UserEvent, должен бы прочитать JSON по структуре полей - ведь это же просто данные, верно? Но нет.

JsonDeserializer по умолчанию смотрит в заголовок TypeId, видит там полное имя класса отправителя и пытается выполнить Class.forName(). Класса нет - контейнер падает.

Ваш независимый сервис внезапно стал зависимым от classpath источника запроса.

Приглашаю разобраться, как возникла эта проблема и как из неё выбраться, не затаскивая общую DTO-библиотеку в каждый микросервис.

Техническая оговорка: в это статье рассматривается конкретика про JsonSerializer/JsonDeserializer в Spring Kafka. На Avro/Protobuf со Schema Registry эта проблема не воспроизводится - там контракт вынесен в схему, и имя Java-класса просто не играет роли.

Это отрывок статьи. Полную версию читайте на сайте источника по ссылке ниже.

Источник: Habr