Автономные микросервисы, очереди событий и обнаружение сервисов


15

В последнее время я много читал о микро-услугах, и вот некоторые из выводов, которые я сделал до сих пор (пожалуйста, исправьте меня, если я ошибаюсь в любой момент).

  1. Архитектура микросервисов хорошо сочетается с дизайном, управляемым доменом. Обычно одна MS представляет один ограниченный контекст.
  2. Если микро-сервис A требует функциональности, которая находится в микро-сервисе B , моя модель, вероятно, ошибочна, и A и B должны фактически быть одним микро-сервисом / BC.
  3. Синхронная связь между микро-сервисами (прямые HTTP-запросы) является плохой, потому что она не соответствует назначению микро-сервисов и вводит связь между компонентами.
  4. Асинхронная связь между службами желательна. Службы должны публиковать события в очереди сообщений, чтобы другие службы могли подписаться и обработать свою часть события или использовать ее для репликации части данных, необходимых для их контекста. Таким образом, сервисы могут обрабатывать запросы, даже если другие сервисы не работают, что было бы невозможно при синхронной связи.
  5. Если микросервис A публикует событие, микросервис B подписывается на это событие и создает новое событие в качестве результата, микросервис A не должен быть тем, который обрабатывает вновь созданное событие, потому что это будет циклическая зависимость. В этом случае мы должны ввести третий микросервис или объединить A и B в микросервис AB .
  6. Микро-сервис на самом деле вводит в заблуждение термин. Мы должны стремиться к маленькому контексту, но это не обязательно так. Термин не должен быть «микро-сервис», но « достаточно большим, чтобы сделать работу сервис ».
  7. Микро-сервисы позволяют нам вводить новые функции с большей легкостью и не опасаясь, что мы сломаем всю систему. Это можно сделать, введя новый сервис или реорганизовав один из существующих.
  8. Каждый микросервис должен иметь свое собственное хранилище данных. Репликация / дублирование данных является желательным поведением в этой архитектуре.

Помимо подтверждения моего понимания этой архитектуры, моя другая часть вопроса в основном связана с обнаружением сервисов. Если сервисы взаимодействуют асинхронно и используют центральную очередь событий, такую ​​как amazon SQS, означает ли это, что обнаружение сервисов не имеет своего места в подобной архитектуре?

Службы не должны иметь никаких знаний о других службах в системе. Они знают только свой контекст и события, которые они должны опубликовать или подписаться?

Ответы:


4

Ваши выводы кажутся в основном обоснованными и очень хорошо подводят итог пути для микросервисов.

Однако я бы не полностью поддержал 2, 5 и 8:

  • 2) Простая зависимость не должна автоматически приводить к слиянию. Вы должны учитывать частоту таких зависимых звонков, а также частоту звонков из других служб.

    Таким образом, если микросервис A требует очень частых функций в микросервисе B, а микросервис B редко требуется для других микросервисов, вам следует бросить вызов предполагаемой структуре и спросить, не будет ли более подходящим объединить оба микросервиса.

  • 5) Конечно, вам нужно избегать бесконечных циклов обработки сообщений.

    Но добавление посредника не помешает этому: A может запустить сообщение, обработанное C, который запускает сообщение, обработанное B, который запускает сообщение, обработанное A, и здесь вы попадаете в цикл.

    Проблема не может быть оценена только с учетом уровня микросервиса: вопрос на самом деле о типе сообщения и его содержании, которое может привести к циклу. Поэтому график, который моделирует распределение и обработку сообщений по службам, должен быть проанализирован в целом (на самом деле это может быть сложно, так что вы можете представить себе микросервис мониторинга, который обнаруживает такие циклы и прерывает их).

  • 8) да, каждый микросервис должен иметь свое специальное хранилище / базу данных.

    Требуется минимум репликации, чтобы службы могли быть независимыми. Однако я бы не сказал, что репликация желательна: она должна быть сведена к минимуму, чтобы избежать скрытой связи через процессы репликации.

    Микросервисы о слабой связи. Иногда это может быть более эффективно достигнуто путем вызова другого микросервиса для получения связанных данных вместо репликации данных.

Два последних ненумерованных утверждения слишком широки, чтобы дать твердый ответ здесь. Я думаю, что ваше предложение является хорошей отправной точкой, но оно действительно зависит от архитектурных требований и ограничений.


«Иногда это может быть более эффективно достигнуто путем вызова другого микросервиса для получения связанных данных вместо репликации данных». Итак, нет ничего плохого в небольшом количестве синхронной связи и прямых вызовов (через HTTP) для извлечения некоторой части данных, как пока этот запрос не представляет распределенную транзакцию / команду, в противном случае мы не можем гарантировать атомарность этой команды?
Роберт

1
Здесь нет идеального решения: это слабая связь и инкапсуляция ( microservices.io/patterns/data/database-per-service.html ) для баланса между простотой и избыточностью ( microservices.io/patterns/data/event-driven-architecture .html ) в контексте общей картины ( microservices.io/patterns/microservices.html )
Кристоф

3

Микро-сервисы - это разделение разных функциональных областей. Каждый сервис может быть разработан в разном темпе, другой командой, с использованием разных технологий. Это создает организационную гибкость. Компромисс заключается в сложности работы, когда каждая дополнительная услуга создает еще одну вещь, которой необходимо управлять в операционной среде. Таким образом, фундаментальный компромисс между монолитом и микросервисом заключается не в том, чтобы избегать зависимостей, а в том, чтобы избежать разработки и развертывания с поэтапной блокировкой, при которой все должно быть отправлено сразу, а за счет того, что придется отправлять чаще, поскольку больше движущихся частей.

Службы не должны иметь никаких знаний о других службах в системе. Они знают только свой контекст и события, которые они должны опубликовать или подписаться?

Проблема предотвращения зависимости - красная сельдь. У вас всегда будут зависимости между частями вашего продукта, и то, находятся ли они в отдельном сервисе или в одном и том же коде, не меняет того факта, что зависимости могут сломаться. Они могут сломаться на операционном уровне, потому что ключевой сервер выходит из строя, и вы управляете этим с помощью оперативной избыточности и отработки отказа. Они также могут сломаться на уровне интеграции, потому что детали изменяются несовместимыми способами, которые вы обнаруживаете при тестировании интеграции. Перестановка кода между сервисами не решает проблему потенциально нарушенных зависимостей. Решения для избежания нарушения зависимостей - это эксплуатационная избыточность и интеграционное тестирование, которые не имеют никакого отношения к размеру ваших сервисов.

Если сервисы взаимодействуют асинхронно и используют центральную очередь событий, такую ​​как amazon SQS, означает ли это, что обнаружение сервисов не имеет своего места в подобной архитектуре?

Чтобы ответить на этот вопрос, сначала ответьте на этот вопрос: почему вы хотите общаться асинхронно? Это облегчить самостоятельную разработку отдельных компонентов? Это улучшить эксплуатационную готовность для системы 24/7? Допустим, это последнее, и вы хотите использовать очереди для репликации данных в локальные базы данных. Что ж, теперь ваши данные могут устареть. В какой-то момент это будет слишком несвежим. Как вы справляетесь с этим? Более того, как вы обеспечиваете оперативную доступность очереди, которая является еще одним компонентом времени выполнения? И как вы обеспечиваете доступность этих локальных баз данных? Вместо того, чтобы управлять одним кластером базы данных, теперь у вас есть несколько. Может ли ваша оперативная команда справиться с этой нагрузкой? И действительно, стоит ли сложность, когда, возможно, ваши пользователи будут более счастливы с большим количеством функций и несколькими часами простоя каждый месяц, если вы построите простой монолит?

Я думаю, вы понимаете мою точку зрения. Проектирование системы не о правильном и неправильном, а о выборе из широкого спектра компромиссов. Все, что неправильно, может быть правильным, и наоборот, если вы только видите это в правильном контексте. Ваш контекст является уникальным для вас, так что в то время как мы можем дать вам в ответ, это не будет ответом. Помните, кто ваша аудитория, каковы их потребности, и правильный дизайн покажет себя.


2
  1. Архитектура микросервисов хорошо сочетается с дизайном, управляемым доменом. Обычно одна MS представляет один ограниченный контекст.

Не согласен. ДДД имеет тенденцию быть очень ОО. заказ доставлен? Order.Deliver (), тогда как Микро-сервисы будут иметь DeliveryService.Deliver (заказ)

  1. Если микро-сервис A требует функциональности, которая находится в микро-сервисе B, моя модель, вероятно, ошибочна, и A и B должны фактически быть одним микро-сервисом / BC.

Не согласен, вы должны стараться держать микро услуги микро. разделите их еще меньше!

  1. Синхронная связь между микро-сервисами (прямые HTTP-запросы) является плохой, потому что она не соответствует назначению микро-сервисов и вводит связь между компонентами.

Не согласен. сервисы не должны заботиться о том, кто их вызывает, а абоненты не должны заботиться о том, чтобы логика была реализована в микросервисе.

  1. Асинхронная связь между службами желательна. Службы должны публиковать события в очереди сообщений, чтобы другие службы могли подписаться и обработать свою часть события или использовать ее для репликации части данных, необходимых для их контекста. Таким образом, сервисы могут обрабатывать запросы, даже если другие сервисы не работают, что было бы невозможно при синхронной связи.

Очереди хорошие. Но ваши рассуждения неверны. единственное различие между ответами на синхронизацию и асинхронностью состоит в том, что вы ожидаете ответа на синхронизацию. Вы можете реализовать вызовы в стиле RPC с очередями и несколькими рабочими без проблем.

  1. Если микросервис A публикует событие, микросервис B подписывается на это событие и создает новое событие в качестве результата, микросервис A не должен быть тем, который обрабатывает вновь созданное событие, потому что это будет циклическая зависимость. В этом случае мы должны ввести третий микросервис или объединить A и B в микросервис AB.

Не согласен. Это не круговая зависимость, потому что ваши микро-сервисы не связаны. Также вы хотите обслуживать отправку сообщений Senarios, SendEmail, EmailFailed, SendAgain не требуется 3 микро-сервисов

  1. Микро-сервис на самом деле вводит в заблуждение термин. Мы должны стремиться к маленькому контексту, но это не обязательно так. Термин не должен быть «микро-сервис», но «достаточно большим, чтобы сделать работу сервис».

Не согласен. Проверьте нано-услуги.

  1. Микро-сервисы позволяют нам вводить новые функции с большей легкостью и не опасаясь, что мы сломаем всю систему. Это можно сделать, введя новый сервис или реорганизовав один из существующих.

Не согласен. Да, вы получаете разъединение, но оркестровка микросервисов может быть столь же сложной, как любой монолитный проект

  1. Каждый микросервис должен иметь свое собственное хранилище данных. Репликация / дублирование данных является желательным поведением в этой архитектуре.

Не согласен. Хотя вы не должны совместно использовать хранилище, ваши микросервисы должны стараться оставаться без состояния, где это возможно. не дублируйте данные, если они не находятся в полете


1

Ваши выводы - хорошие эмпирические правила, но не универсальные. Будут случаи, когда лучшим вариантом является нарушение этих правил даже в новом проекте. В некоторых случаях синхронное общение является лучшим вариантом. В некоторых случаях нецелесообразно объединять две службы в одну, даже если они связаны синхронной связью.

И к вашему другому вопросу, обнаружение сервиса не требуется для связи на основе очереди.


0

Хм, вы просто говорите об объектно-ориентированном программировании. Или, по крайней мере, то, что изначально задумывалось: независимые части исполняемого кода, взаимодействующие друг с другом с помощью сообщений.

Алан Кей задумал ООП как смоделированный по образцу биологических систем, где клетки относительно независимы друг от друга и просто обмениваются сообщениями, которые подключаются к внешним интерфейсам других клеток.

Так почему же мы перестаем думать об этом как об ООП только потому, что все объекты не работают на одном компьютере? Во всяком случае, это даже более объектно-ориентировано, чем если бы они находились на одном компьютере и являлись частью одного и того же приложения, потому что, если все объекты находятся в одном приложении, разработчики часто ломали ООП, используя глобальные переменные, общие для всех классов и включая одинаковые заголовки в каждом файле и т. д. Когда все объекты зависят от одного и того же материала, они не настолько инкапсулированы, как если бы они были полностью независимы друг от друга, и инкапсуляция - это весь смысл ООП.

Например, почти все, что сказано в других ответах, является утверждениями из учебника об ООП.


0

Поскольку я часто сталкиваюсь с неправильным пониманием такого важного понятия, как ограниченный контекст и основной домен, я бы хотел немного подробнее остановиться на нем.

Я считаю чрезвычайно выгодным думать о поддоменах как о бизнес-возможностях. Бизнес-возможности - это то, что делает ваша организация. Это одна из его бизнес-функций. Поскольку нашей целью является согласование бизнес-ИТ , я определенно хочу, чтобы они имели отношение 1: 1 к моим техническим услугам .

Итак, этот процесс сводится к следующему. Во-первых, я определяю бизнес-возможности более высокого уровня. Это должно принять форму существительного и глагола (или некоторой производной формы). Обычно существует менее 10 бизнес-возможностей. Затем я углубляюсь глубже, выявляя вложенные возможности. И так далее, пока нечего расколоть. Возможности, к которым вы пришли, используя этот подход, отражают реальную область, реальную работу вашей организации. Эти возможности будут изначально слабо связаны, поэтому, если вы сопоставите свои технические услуги с этими возможностями, они будут автономными и управляемыми событиями. Этот процесс называется сопоставлением бизнес-возможностей , но существуют и другие способы поиска ваших услуг, наиболее известным из которых, вероятно, является анализ цепочки создания ценности .

Вот пример определения границ сервиса с использованием этого подхода.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.