0 RU:Broker
Vasiliy Tolstov edited this page 2021-11-18 00:46:49 +03:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Реализации интерфейса https://pkg.go.dev/go.unistack.org/micro/v3/broker#Broker

Брокер - абстракция отвечающая за реализацию асинхронного взаимодействие (паблишинг/сабскрайбинг). При использовании напрямую в сервисе предоставляет только реализацию асинхронного взаимодействия, а за сериализацию/десериализацию отвечает разработчик. Чаще всего используется внутри клиентов и серверов(прокидывается как зависимость), а те, в свою очередь, берут на себя ответственность за сериализацию/десериализацию(с помощью кодеков) и взаимодействие с брокером (метод Publish клиента и Subscribe сервиса). Кодек так же присутствует в опциях брокера, он декларирует как маршалить/анмаршалить непосредственно структуру Message(является транспортной структурой брокера, в которую враппается сериализованное содержимое объекта и заголовки), по сути этот кодек константен.

Брокер используются для асинхронной коммуникации между сервисами. Существует два варианта использования брокера в micro. Высокоуровневый и низкоуровневый.

Низкоуровневый вариант заключается в использовании непосредственно broker методов. В этом случае Publish использует *broker.Message сообщение, вся работа по маршалингу сообщения ложится на разработчика. Сообщение в виде массива байт должны быть в поле Body структуры broker.Message. Опционально нужно заполнить заголовки, для передачи метаданных, например идентификатора трейсинга, или контент-тип. Микро ожидает, что все сообщения будут иметь тип *broker.Message. В форке добавлена поддержка прямого получения массива байт из брокера для kafka (segmentio) в этом случае заголовки сообщения будут пустыми, в все сообщение из брокера будет записано в поле Body как есть. Для этого необходимо передать опцию BodyOnly при подписке. Для публикации только тела сообщения следует использовать *codec.Frame тип сообщения. Все кодеки микро поддерживают данный тип и просто записывают байты. Низкоуровневый вариант позволяет вручную вызывать Ack() метод и вручную оперировать телом сообщения.

Высокоуровневый вариант заключается в использовании micro.RegisterSubscriber функции и сервера микро. В этом случае нет возможности вручную вызывать метод Ack(), сервер автоматически вызывает его, если хендлер не вернул ошибку обработки. Плюсом данного подхода является то, что не нужно вручную выполнять анмаршалинг тела сообщения в структуру. Хендлер уже получает в контексте все метаданных из заголовка сообщения и заполненную структуру из тела сообщения. Несмотря на высокоуровневый подход был сделан вариант получения всего сообщении в сыром виде посредством использования в качестве типа в хендлере *codec.Frame. В этом случае брокер игнорирует анмаршалинг и передает сообщение как есть.

В описанных выше вариантах используется микро Codec. Его задача маршалинг-анмаршалинг сообщения. Кодек используется как в брокере, так и в сервере.

При паблишинге через клиента кодек в клиенте маршалит структуру в массив байт. После этого заполняет *broker.Message поля и отдает брокеру. Брокер в свою очередь с помощью своего кодека маршалит сообщение в массив байт и передает непосредственно в брокер. При паблишинге непосредственно через брокер из схемы уходит использование клиента и маршалинг в байты ложится на плечи разработчика.

При консуминге кодек в брокере используется для анмаршалинга массива байт в структуру broker.Message. Далее если используется сабскрайбинг брокера то полученная структура отдается в хендлер в виде интерфейса Event. Если используется для сабскрайбинга сервер, то появляется еще один этап в котором сервер заполняет контекст данными из заголовка сообщения и использования серверного кодека для анмаршалинга тела сообщения в нужную структуру хендлера. Как только хендлер завершает свою работу на основе возвращаемого значения решается, нужно ли выполнить Ack() над сообщением.