Мой сценарий таков.
Я разрабатываю систему, предназначенную для получения данных от различных типов датчиков, а также для преобразования и последующего сохранения этих данных для последующего использования различными интерфейсными и аналитическими службами.
Я стараюсь сделать все сервисы максимально независимыми, но у меня возникли некоторые проблемы. Команда определилась с DTO, которое мы хотели бы использовать. Внешние службы (получатели данных датчиков) будут получать данные своим уникальным способом, затем преобразовывать их в объект JSON (DTO) и отправлять их в брокер сообщений. Потребители сообщений будут точно знать, как читать сообщения с данными датчика.
Проблема в том, что я использую один и тот же DTO в нескольких разных сервисах. Обновление должно быть реализовано в нескольких местах. Очевидно, мы разработали его таким образом, чтобы несколько дополнительных или отсутствующих полей в DTO здесь и там не представляли особой проблемы до тех пор, пока службы не будут обновлены, но это все еще вызывает у меня проблемы и заставляет меня чувствовать, что я ошибаться Это может легко превратиться в головную боль.
Я собираюсь неправильно спроектировать систему? Если нет, то каким образом можно обойти это или хотя бы ослабить мои заботы?
proto
файлом для gRPC илиavro
схемой для Kafka и сгенерировать DTO в обоих сервисах, но я не буду делить общую библиотеку между двумя проектами.Ответы:
Мой совет? Не разделяйте эти DTO между приложениями в какой-либо библиотеке. Или, по крайней мере, не делай этого прямо сейчас.
Я знаю, кажется очень нелогичным. Вы дублируете код, верно? Но это не бизнес-правило, поэтому вы можете быть более гибкими.
Служба, которая отправляет DTO, должна быть жесткой в своем контракте сообщений, как Rest API. Служба не может изменить DTO таким образом, чтобы это могло нарушить работу других служб, которые уже потребляют информацию из DTO.
Когда добавляется новое поле, выполняйте DTO, вы обновляете только другие службы, использующие этот DTO, если им нужно новое поле. В противном случае забудь об этом. Используя JSON в качестве типа контента, вы можете создавать и отправлять новые атрибуты без прерывания кода сервисов, которые не отображают эти новые поля в его реальных версиях DTO.
Но если эта ситуация действительно беспокоит вас, вы можете следовать правилу трех :
Итак, попробуйте немного подождать, прежде чем делиться этим DTO между сервисами.
источник
Когда дело доходит до микросервисов, жизненные циклы разработки сервисов тоже должны быть независимыми. *
Разные SLDC и разные команды разработчиков
в реальной системе MS может быть несколько команд, участвующих в разработке экосистемы, каждая из которых отвечает за один или несколько сервисов. В свою очередь, эти команды могут быть расположены в разных офисах, городах, странах, планах ... Возможно, они даже не знают друг друга, что делает обмен знаниями или кодом очень сложным (если это возможно). Но это может быть очень удобно, потому что совместно используемый код также подразумевает своего рода рассуждение о разделении, и важно помнить, что независимо от того, что имеет смысл для конкретной команды, не обязательно делать это для другой команды. Например, учитывая клиента DTO , он может отличаться в зависимости от действующей услуги, поскольку клиенты интерпретируются (или рассматриваются) по-разному для каждой услуги.
Разные потребности, разные технологии
Изолированные SLDC также позволяют командам выбирать стек, который наилучшим образом соответствует их потребностям. Внедрение DTO, реализованных в определенной технологии, ограничивает возможности команд выбирать.
DTO не являются ни бизнес-правилами, ни контрактами на обслуживание
Что такое DTO? Простые объекты без какой-либо другой цели, кроме перемещения данных с одной стороны на другую. Сумки добытчиков и сеттеров. Это не тот вид «знания», который стоит использовать повторно, потому что знаний вообще нет. Их волатильность также делает их плохими кандидатами на связывание.
Вопреки тому, что сказал Дерик, у службы должна быть возможность изменять свои DTO без необходимости одновременного изменения других служб. Услуги должны быть терпимыми читателями, терпимыми авторами и отказоустойчивыми . В противном случае они вызывают соединение таким образом, что лишает смысла архитектуру сервиса. Еще раз, и вопреки ответу Дерика, если три службы нуждаются в одинаковых DTO, вероятно, что-то пошло не так во время декомпозиции служб.
Разное дело, разные интерпретации
Хотя между сервисами могут быть (и будут) сквозные концепции, это не означает, что нам нужно навязывать каноническую модель, чтобы заставить все сервисы интерпретировать их одинаково.
Тематическое исследование
Скажем , наша компания имеет три отдела, обслуживание клиентов , продажи и доставку . Скажите каждому из этих выпусков одну или несколько услуг.
Служба поддержки клиентов, благодаря своему доменному языку , реализует услуги, основанные на концепции клиентов, где клиенты - это лица . Например, клиенты моделируются как имя , фамилия , возраст , пол , адрес электронной почты , телефон и т. Д.
Теперь, скажем, отдел продаж и доставки моделирует свои услуги также в соответствии с языками их доменов. На этих языках концепт- клиент тоже появляется, но с небольшим отличием. Для них клиенты не являются (обязательно) лицами . Для продаж , клиенты являются номер документа кредитной карты и платежный адрес , для Доставки в полное имя и адрес доставки тоже.
Если заставить продаж и доставки принять каноническую модель данных обслуживания клиентов , мы заставляя их бороться с ненужными данными , которые могли бы в конечном итоге введение ненужной сложности , если они должны поддерживать все представление и сохранить клиента данные в синхронизации с клиентами ,
Ссылки по теме
* Вот в чем сильные стороны этой архитектуры
источник
Вы должны публиковать события . События - это определенный тип сообщений, которые представляют собой достоверный факт о том, что произошло в определенный момент времени.
Каждая служба должна иметь четко определенную ответственность и должна публиковать события, связанные с этой ответственностью.
Кроме того, вы хотите, чтобы ваши события представляли связанные с бизнесом события, а не технические события. Например, предпочитаю
OrderCancelled
событиеOrderUpdated
сstatus: "CANCELLED"
.Таким образом, когда службе нужно реагировать на отмененный заказ, ей просто нужно прослушать тот конкретный тип сообщения, который содержит только данные, относящиеся к этому событию. Например,
OrderCancelled
вероятно, просто нужноorder_id
. Какой бы сервис ни реагировал на это, он уже сохранил все, что ему нужно знать о заказе, в своем собственном хранилище данных.Но если у службы есть только
OrderUpdated
события, которые нужно прослушивать, то ей нужно будет интерпретировать поток событий, и теперь он зависит от правильного заключения заказа на доставку, когда заказ был отменен.В вашем случае, однако, как ваши публикуют данные датчика, это может иметь смысл иметь службы, слушать события и публиковать новый поток «бизнес - события», например
TemperatureThresholdExceeded
,TemperatureStabilised
.И будьте осторожны, создавая слишком много микросервисов. Микросервисы могут быть отличным способом инкапсулирования сложности, но если вы не обнаружите подходящие границы сервиса, ваша сложность заключается в интеграции сервиса. И это кошмар для поддержания.
Лучше иметь слишком мало, слишком большие услуги, чем иметь слишком много, слишком маленькие услуги.
источник