Микросервисы были очень горячей темой в последние несколько лет (Приложение 1). Что такое «микросервисное безумие», например:
Ни для кого не секрет, что Netflix неплохо справляется с DevOps. Netflix может делать микросервисы. Итак: если я буду заниматься микросервисами, я также буду очень хорош в DevOps.
Во многих случаях мы вслепую прилагаем огромные усилия для доступа к модели микросервисов, но часто мы редко задумываемся о том, могут ли стоимость и преимущества доступа эффективно помочь нам решить болевые точки, с которыми мы сталкиваемся в настоящее время.
Ниже я подробно опишу, что такое микросервисы, почему эта модель так привлекательна, и, наконец, расскажу о некоторых ключевых проблемах, с которыми сталкиваются микросервисы.
Если вы думаете, подходят ли вам микросервисы, могут ли они помочь вам решить ваши текущие проблемы? Тогда читайте дальше, и я буду использовать ряд простых вопросов, чтобы помочь вам выйти из замешательства. Эта серия «вопросов» находится в конце статьи.
Что такое микросервисы и почему они так популярны?
Приходи и приезжай, старый водитель возьмет тебя с азов. Пример: На следующем рисунке показана воображаемая реализация платформы для обмена видео. Левая часть реализована «общим сервисом», а правая часть реализована в виде нескольких микросервисов:
Разница между двумя конструкциями систем заключается в том, что левая сторона представляет собой в целом большой и всеобъемлющий сервис. Справа группа небольших, но многих, но каждая из них представляет собой конкретную службу, каждая со своей определенной ролью.
При рисовании диаграмм на уровне детализации системы легко увидеть множество потенциальных преимуществ микросервисов.Вот несколько простых аспектов:
Независимая разработка: небольшие независимые компоненты могут создаваться небольшими независимыми командами. Группа может изменить услугу «Загрузка», не мешая службе «Перекодировать», даже не зная об этой услуге. Время на понимание компонентов значительно сокращается, и легче разрабатывать новые функции.
Независимое развертывание: каждый отдельный компонент может быть развернут независимо. Это позволяет выпускать новые функции быстрее и с меньшим риском. Например: исправления или функции компонента «Потоковая передача» могут быть развернуты без развертывания других компонентов.
Независимая масштабируемость: каждый компонент можно масштабировать независимо друг от друга. Когда существует много параллелизма и необходимо выпустить новую версию, компонент «Загрузка» можно масштабировать для обработки возросшей нагрузки без необходимости масштабирования каждого компонента, что делает гибкое масштабирование более осуществимым и снижает затраты.
Возможность повторного использования: компонент реализует небольшую специфическую функцию. Это означает, что их легче адаптировать к другим системам, услугам или продуктам. Компонент «Транскодирование» может использоваться другими бизнес-подразделениями или даже стать новым бизнесом или предоставлять услуги транскодирования другим группам.
На уровне детализации преимущества микросервисной модели по сравнению с монолитной очевидны. Но здесь возникает вопрос: если это так, то почему модель микросервисов прижилась только в последние несколько лет? Я почти закончил свою жизнь (неловко, кажется, показывает мой возраст), это только появилось?
Если этот микросервис такой хороший, почему никто не сделал его раньше?
На этот вопрос есть два ответа. Во-первых, он в значительной степени зависит от наших лучших технологических возможностей, а во-вторых, последние технологические достижения позволяют нам вывести его на новый уровень.
Когда я начал писать мягкую статью, чтобы ответить на этот вопрос, я обнаружил, что это будет длинное описание, поэтому с практической точки зрения я разделю его на две статьи и опубликую 2 позже. В первой статье я пропущу такие вещи, как переход от одной программы к нескольким программам, игнорирование ESB и сервис-ориентированной архитектуры, дизайн компонентов и ограниченные контексты и т. д.
Заинтересованные друзья могут прочитать больше о путешествии позже. Хотя во многих отношениях мы занимаемся этим некоторое время, с недавним распространением контейнерных технологий (особенно Docker) и технологий оркестрации (таких как Kubernetes, Mesos, Consul и т. д.), с технической точки зрения, шаблон микросервисов становится более осуществимым.
Поэтому, если мы хотим внедрить микросервисы, нам лучше хорошенько подумать, действительно ли они нам нужны. Мы видели «теоретические преимущества» величия, но стоит упомянуть, каковы неизвестные проблемы?
Что не так с микросервисами?
Микросервисы настолько мощны и совершенны, где могут быть проблемы? Это, безусловно, самая большая проблема, которую я видел.
Повышенная сложность разработки
Разработчикам будет сложнее. В тех случаях, когда разработчики хотят работать удаленно или функции, которые могут охватывать множество служб, разработчики должны запускать их на своих компьютерах или подключаться к ним. Обычно это сложнее, чем просто запустить одну программу.
Эту проблему можно частично решить с помощью инструментов (Приложение 3), но по мере увеличения количества служб, составляющих систему, разработчикам становится сложнее запускать всю систему.
Повышенная сложность эксплуатации
Потенциальная сложность является большой проблемой для команд, которые не разрабатывают сервисы, а поддерживают их. Вместо управления несколькими работающими службами они управляют десятками, сотнями или тысячами работающих служб. Чем больше сервисов, чем больше коммуникаций, тем выше потенциальный риск сбоя.
Повышенная сложность DevOps
Прочитав два приведенных выше пункта, вы можете обнаружить, что операции и разработка обрабатываются отдельно, особенно учитывая популярность DevOps как практики (я настоящий фанат DevOps). Разве DevOps не может облегчить эту боль?
Проблема сейчас заключается в том, что многие организации по-прежнему полагаются на отдельные группы разработки и эксплуатации, в то время как некоторые более склонны внедрять микросервисы.
Это все еще сложно для организаций, которые уже внедрили DevOps. Быть и разработчиком, и оператором уже сложно (но это важно для создания хорошего программного обеспечения), но нужно также понимать нюансы систем оркестрации контейнеров, особенно быстроразвивающихся систем. Это подводит меня к следующему пункту.
Нет профессиональных знаний? Не играйте с микросервисами
Когда многое делается профессионалами, конечный результат тоже будет превосходным. Но представьте, что агентство или организация не всегда работают гладко с единой монолитной системой. Итак, что можно сделать, чтобы улучшить и сделать эти вещи лучше? За счет увеличения количества системных служб? Но это также увеличивает сложность операции.
По общему признанию, все это можно улучшить с помощью эффективной автоматизации, мониторинга и оркестровки и т. д. Но проблема редко заключается в самой технологии — настоящая проблема заключается в поиске людей, которые могут эффективно ее использовать. Именно эти навыки сейчас очень востребованы, и может быть сложно найти человека, который соответствует вашим потребностям.
Реальные системы часто плохо определены
Во всех примерах, которые мы использовали для описания преимуществ микросервисов, мы говорили о независимых компонентах. Но во многих случаях компоненты не являются полностью независимыми. Как говорится, «вы знаете, что делаете на бумаге, и никогда не знаете, что делать». чем вы могли ожидать.
Здесь все становится действительно сложно. На самом деле, что произойдет, если ваши границы четко не определены? Несмотря на то, что службы теоретически могут быть развернуты по отдельности, вы обнаружите, что вам придется развертывать ряд микрослужб как групповую службу из-за взаимозависимостей между службами.
Это означает, что вам нужно управлять версиями, которые работают вместе, и эти версии сервисов проверяются и тестируются, когда они совместно отлаживаются, у вас действительно нет системы, которую можно развернуть независимо, потому что для развертывания новых функций вам нужно для тщательной организации множества служб одновременно.
Сложность состояния часто упускается из виду
В предыдущем примере я упомянул, что для развертывания функции может потребоваться одновременное развертывание нескольких версий многих сервисов. Предполагается, что это можно смягчить с помощью разумных методов развертывания, таких как сине-зеленое развертывание (которое большинство платформ оркестрации служб редко поддерживают изначально) или параллельный запуск нескольких версий службы и выбор версии потребительского канала для использования.
Эти методы могут облегчить ряд проблем, если служба не имеет состояния. Но безграничный сервис очень откровенен и с ним легко иметь дело. На самом деле, если у вас есть сервисы без сохранения состояния, я бы предпочел отказаться от микросервисов и рассмотреть модель без сервера.
На самом деле многие сервисы нуждаются в управлении. Примером нашей платформы для обмена видео может быть служба подписки. Новые версии служб подписки могут хранить данные в базах данных подписки в различных формах. Если вы запускаете обе службы одновременно, запускайте систему сразу в обоих режимах. Если у вас синее/зеленое развертывание и другие службы зависят от данных в новой форме, вы должны обновить эти данные одновременно, а также может потребоваться использовать каскадные откаты, если развертывание службы подписки завершается сбоем и откатывается.
Опять же, вы можете сказать, что в базе данных NoSQL эти проблемы со схемой исчезают, но это не так. База данных, которая не использует схему, не может подключиться к системе без схемы — это означает, что схема, как правило, управляется на уровне приложения, а не на уровне базы данных. Фундаментальная проблема понимания структуры данных и того, как они передаются, не может быть устранена.
Сложность общения часто упускается из виду
Когда вы строите большую сеть взаимозависимых сервисов, может быть много межсервисного взаимодействия. Это приводит к некоторым проблемам. Во-первых, есть много вещей, которые могут выйти из строя. Мы должны предположить, что сетевые вызовы могут завершаться ошибкой, а это означает, что когда одна служба вызывает другую, ей необходимо повторить попытку хотя бы несколько раз. Теперь, когда служба может вызывать много служб, мы получаем более сложную ситуацию.
Пользователь загружает видео из службы обмена видео. Нам может потребоваться запустить службу загрузки, передать данные в службу транскодирования, обновить подписки, рекомендации по обновлению и т. д. Все эти вызовы требуют определенного уровня координации, и если какая-либо часть процесса дает сбой, нам нужно повторить попытку.
Этой логикой повторных попыток может быть трудно управлять. Попытка делать что-то синхронно часто приводит к неубедительному, слишком большому количеству точек отказа. В этом случае более надежным решением является использование асинхронного режима для обработки связи. Проблема здесь в том, что сам асинхронный шаблон имеет тенденцию делать систему с отслеживанием состояния. Как упоминалось ранее, с системами с распределенным состоянием и системами с состоянием трудно иметь дело.
Когда система микрослужб использует очереди сообщений для взаимодействия внутри службы, вам в основном требуется большая база данных (очереди сообщений или брокеры), чтобы сгруппировать эти службы вместе. Опять же, хотя поначалу это может показаться несложным, вы знаете — рано или поздно это окупается. Служба в версии X может написать сообщение в определенном формате, и когда отправляющая служба изменяет детали отправленного сообщения, службы, которые зависят от этого сообщения, также должны быть обновлены.
Конечно, может быть много разных форматов служб обработки сообщений, но этим сложно управлять. Теперь при развертывании новой версии службы у вас могут быть две разные версии службы, пытающиеся обрабатывать сообщения из одной и той же очереди, или даже сообщения, отправленные разными версиями отправляющей службы. Это может привести к сложным пограничным случаям. Чтобы избежать этих крайних случаев, может быть проще разрешить существование только определенных версий сообщений, а это означает, что вам необходимо развернуть версии набора служб в целом, чтобы обеспечить правильную маскировку сообщений из предыдущих версий.
Это еще раз подчеркивает, что идея автономного развертывания может пойти не так гладко, как ожидалось.
Контроль версий может быть затруднен
Чтобы облегчить вышеупомянутые проблемы, необходимо очень тщательно управлять контролем версий. Опять же, кажется, что есть тенденция - предполагая, что следование стандарту, подобному Semver [4], может решить эту проблему. Однако это не совсем так. Хотя использование Semver является разумным соглашением, вам все равно необходимо отслеживать версии сервисов и API, которые работают вместе.
Это может сделать вещи очень сложными, и часто это может сбить вас с толку в том, какие версии службы хорошо работают вместе.
Управлять зависимостями в программной системе очень сложно, будь то модули узла, модули Java, библиотеки C или что-то еще. Трудно справиться с проблемой, когда сущность потребляет конфликты между независимыми компонентами.
С этими проблемами трудно справиться, когда зависимости статичны. В то время как исправление, обновление, редактирование и т. д. могут быть выполнены, если сами зависимости являются действующими службами, вы вообще не сможете их обновить — вам может потребоваться запустить много версий (проблемы были описаны выше) или пока вся система не будет исправлена.
Распределенная транзакция
Микросервисы могут быть занозой в заднице, где требуется целостность транзакций между операциями. Распределенное состояние трудно обрабатывать, и у многих небольших подразделений могут возникнуть трудности с организацией транзакций.
Попытка избежать этой проблемы, сделав операции идемпотентными, обеспечив механизм повторных попыток и т. д., может показаться заманчивой, и во многих случаях это действительно может сработать. Но могут быть некоторые сценарии, когда вам просто нужно, чтобы транзакция завершилась неудачно или успешно, и вы не хотите, чтобы она находилась в промежуточном состоянии. Решение этой проблемы или ее реализация в модели микросервиса может обойтись очень дорого.
Микросервисы могут быть замаскированными бегемотами
Очевидно, что отдельные сервисы и компоненты могут быть развернуты изолированно, но в большинстве случаев вам придется запускать какую-то платформу для оркестровки, например Kubernetes. Если вы используете управляемую службу, такую как Google GKE 5 или Amazon EKS 6, многие сложности управления вашим кластером ложатся на вас.
Однако если вы управляете кластером самостоятельно, вы управляете большой и сложной критически важной системой. Хотя один сервис может иметь все преимущества, описанные ранее, вам необходимо очень осторожно управлять кластером. Развертывание этой системы может быть затруднено, обновление может быть затруднено, аварийное переключение может быть затруднено и так далее.
Во многих случаях общее преимущество остается, но важно не недооценивать и не недооценивать дополнительную сложность управления другой большой и сложной системой. Управляемые сервисы могут помочь, но во многих случаях эти сервисы появляются и нестабильны (например, Amazon EKS не был анонсирован до конца 2017 года) — кто знает.
Безумная смерть микросервисов!
Безумие микросервисов для микросервисов можно избежать только путем тщательного рассмотрения. Чтобы помочь с этим, я подумал о некоторых вопросах, которые вы, возможно, захотите задать себе, и возможных ответах:
Вы можете скачать копию в формате PDF здесь: https://github.com/dwmkerr/blog/raw/master/2018/microservice-madness/images/microservice-questions.pdf
Заключительные мысли: не путайте микросервисы и архитектуру
Я намеренно избегал слова "а" в этом посте. Однако мой друг Золтан сделал правильное замечание, вычитывая эту статью.
Нет микросервисной архитектуры. Микросервисы — это просто еще один шаблон или реализация компонентов, и ничего больше. Присутствует ли он в системе, не означает, что архитектура системы разрешена.
Микросервисы во многом связаны с техническим процессом упаковки и эксплуатации, а не с неотъемлемым дизайном системы. Надлежащие границы для компонентов остаются одной из самых важных проблем в инженерных системах.
Независимо от того, находится ли ваша служба в контейнере Docker или нет, вам всегда нужно тщательно продумывать, как вы собираете свою систему. Однозначного ответа нет, только больше вариантов.
Надеюсь, вам понравилось читать эту статью! Как всегда, если у вас есть какие-либо вопросы или мысли, просто оставьте комментарий ниже.
Приложение: дополнительная литература
Следующие ссылки могут быть полезны:
- Мартин Фаулер — Ограниченный контекст — статья Мартина великолепна, и я очень рекомендую эту.
- Мартин Фаулер — Микросервисы. Эта статья посвящена шаблонам для микросервисов.
- Микросервисы — хорошо или плохо? – Прочтите эту статью, и вы поймете, что Бьорн Францен думает о микросервисах.
- Когда не делать микросервисы - отличный пост из темы Кристиана Поста
- Дэйв Керр — Целостная архитектура микросервисов — Практические советы по CI/CD и DevOps в мире микросервисов — представлено на недавней конференции devops, посвященной микросервисам.
Если хотите, поделитесь чем-нибудь по теме, что, по вашему мнению, стоит прочитать или посмотреть!
Ссылаться на
- https://trends.google.com/tren… сервис
- Если вы не хотите пропустить эту статью, вы можете подписаться на RSS-канал или подписаться на меня в LinkedIn или Twitter.
- Docker Compose — отличное решение, Fuge очень умен, а в случае с MiniKube также есть возможность запускать оркестрацию локально.
- https://semver.org/
- Google Kubernetes Engine, управляемая служба Kubernetes, созданная на основе Google Cloud Platform: https://cloud.google.com/kubernetes-engine/
- Amazon Elastic Container Service (Kubernetes уже поддерживается), управляемый Kubernetes сервис, рожденный Amazon Web Services: https://aws.amazon.com/eks/