Skip to content

Latest commit

 

History

History
138 lines (74 loc) · 23.4 KB

File metadata and controls

138 lines (74 loc) · 23.4 KB

От монолитной архитектуры к микросервисам

Как мы с нуля переделывали нашу архитектуру.

Перевод статьи Poki Engineering: From Monolith to Microservices

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

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

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

Вместо этого мы расскажем, что нам конкретно нравится в микросервисах.

Микросервисы предназначены для изменений

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

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

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

Микросервисы позволяют небольшим, кросс-функциональным командам отвечать за продукт

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

В компании Amazon говорят: "Вы это разрабатываете, вы это и запускаете". Они объясняют это так:

Обычно вы разделяете разработку и администрирование программного обеспечения и после разработки забываете о нем. Но не в компании Amazon. Вы занимаетесь разработкой и администрированием. Это позволяет разработчикам понимать как происходит работа с их сервисом. Это также заставляет их постоянно контактировать с клиентами. Этот цикл обратной связи с клиентом необходим для повышения качества обслуживания. - Вернер Фогельс (CTO @ Amazon)

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

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

Микросервисы позволяют нам зеркально отобразить нашу организационную культуру

Закон Конвея говорит нам, что "любая организация, которая разрабатывает систему, создаст проект, структура которого является копией структуры коммуникаций в этой организации".

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

Spotify отлично справляется с этими принципами в своей инженерной культуре.

Микросервисы помогают нам масштабироваться

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

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

Эти преимущества масштабирования микросервисов окажут положительное влияние на скорость, простоту развертывания и стоимость инфраструктуры.

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

Оркестрирование наших сервисов

На данный момент наш монолит все еще находится в производстве как один большой сервис, который живет в специализированных экземплярах на Amazon Web Services (AWS). Однако в нашем окружении микросервиса мы хотим, чтобы несколько сервисов могли эффективно работать в одном экземпляре.

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

Сначала мы попробовали AWS ECS, полностью управляемую службу управления контейнерами Amazon. Несмотря на отсутствие симпатичного интерфейса, AWS ECS работал очаровательно. У нас было логирование, мониторинг и горизонтальное автоматическое масштабирование как для контейнеров, так и для машин. Автоматическое масштабирование машины «из коробки» в частности было самым важным преймуществом по сравнению с Kubernetes, работающей на AWS. Однако из-за отсутствия документации и открытого сообщества, а также завязанности на AWS, мы еще не были уверены.

Затем мы изучили Mesosphere Marathon (DC/OS), который представляет собой набор связанных с контейнерами технологий Apache. Мы глубоко погрузились в сообщество и документацию и пришли к выводу, что, учитывая альтернативы, DC/OS нам не подходит. Нам понравился интерфейс, но общее ощущение заключалось в том, что DC/OS больше подходит для управления своими выделенными серверами где-то в стойке. Мы не собираемся покидать облако в ближайшее время, и мы поняли, что для нашего случая было бы слишком много накладных расходов.

Последним вариантом, который мы пробовали и изучали, был Kubernetes: менеджер контейнеров с открытым исходным кодом, первоначально разработанный Google. Kubernetes появился в Borg, внутренней системы распределения ресурсов Google, и, по словам Wired, "один из главных секретов быстрой эволюции Google в качестве доминирующей силы в Интернете".

Что нам понравилось в Kubernetes:

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

Похоже, что в нашем случае Kubernetes был правильным выбором и мы решили использовать его.

Если вы не поняли что-то из того, что написано выше, советуем вам посмотреть это видео.

Независимость от облачных технологий

Сначала мы попробовали развернуть Kubernetes на AWS, где в настоящее время работает наш монолит. Чтобы начать работу, мы настроили его с помощью команды kube-up.sh. Все казалось прекрасным, пока однажды наш кластер не сломался - получается, что записи логов на небольшие диски AWS EBS в конечном итоге нарушат работу системы.

Мы извлекли урок из этого: на AWS вам действительно нужно управлять кластером Kubernetes, и для этого вам понадобится выделенное время на DevOps работы.

Кроме того, поскольку Kubernetes не интегрирован с AWS, нам приходилось использовать CloudWatch/Lambda/Elasticsearch решения для автоматического масштабирования.

Примерно в это же время мы решили, что не хотим быть завязаны на одну платформу. Мы удалили упавший кластер на AWS и запустили тестовый кластер на Google Cloud Platform(GCP).

Теперь у нас появилась возможность масштабироваться горизонтально с точки зрения серверов, и наши логи автоматически очищались и централизовались в Stackdriver Logging. Google Container Engine (GKE) дает нам кластер по одному щелчку мыши, что сильно упростило нам жизнь.

Итак, мы теперь завязаны на GCP? На самом деле автоматическое горизонтальное масштабирование на GCP - отличный бонус, но это не значит, что мы завязаны на Google. Мы все еще можем решить отделить наш кластер от GCP, поскольку Kubernetes может жить где угодно. Конечно, придется приложить немного больше усилий, чтобы сохранить автоматическое масштабирование узлов и контейнеров, но это определенно возможно. И при появлении Cluster Federation в скором времени можно будет запустить Kubernetes над несколькими облачными архитектурами. Поэтому, когда Kubernetes подтолкнул нас в сторону GCP, мы перестали быть завязанными на облачные технологии.

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

Коммуникация между сервисами

Наша первая реализация микросервисов была с использованием REST через HTTP. Это привело к значительным накладным расходам. Чтобы улучшить скорость и пользовательский интерфейс мы отошли от вызовов REST и вместо этого стали использовать вызовы удаленных процедур (RPC). Мы используем gRPC для выполнения вызовов, Protocol Buffers для сериализации и HTTP/2, чтобы убедиться, что у нас есть постоянные и мультиплексируемые соединения.

Дополнительным преимуществом использования protobuf является то, что связь между службами четко определена, что снижает риск проблем с совместимостью. Связь между фронтендом и бэкендом осуществляется через шлюз, который действует как обратный прокси, перевод RESTful JSON в вызовы gRPC.

Одна из проблем, которая у нас была: Go имеет регрессию в 1.7, заставляя использовать HTTP/2, если вы хотите использовать SSL. Для выполнения этой работы потребовалось некоторое управление сертификатами и немного обмана. Мы использовали Kube Cert Manager Kelsey Hightower для автоматизации поиска и обновления сертификатов от Let's Encrypt, что сделало поистине простым управление SSL-сертификатами.

Логирование и мониторинг

В настоящее время мы используем Stackdriver Logging для логирования. Он работает из коробки и удовлетворяет наши потребности, но если мы когда-нибудь столкнемся с проблемами, мы, вероятно, вернемся к Elasticsearch и Kibana, которые мы использовали в прошлом.

Stackdriver также предоставляет решение для контроля за экземплярами и контейнерами. Однако мы выбрали Prometheus и Grafana, что позволяет нам дополнительно контролировать сервисы.

Все сервисы отображают их соответствующие показатели: использование центрального процессора, детали сбора мусора, вызовы gRPC со временем отклика и т. д. Для сбора этой информации мы используем Prometheus. Затем мы используем Grafana для создания обзорных панелей для наших офисных дисплеев и более глубоких информационных панелей, чтобы быстро выявлять проблемы.

У нас пока нет специализированного дистрибутивного программного обеспечения, такого как Zipkin. На данный момент у нас есть только один уровень сервисов, обменивающихся друг с другом в нашем MVP, поэтому у нас нет длинных цепочек связи. Мы не хотим усложнять архитектуру, но если общение между сервисами становится более сложным, мы добавим трассировку.

Контроль версий и развертывание

Для контроля версий мы переключились с GitHub на GitLab, поскольку они бесплатно предоставляют GitLab CI, что устраняет необходимость использования дополнительной системы CI, такой как Jenkins или Wercker.

У нас есть собственная специализированная машина, которая подключается к GitLab, используя их пакет GitLab CI. Эта машина имеет доступ к нашему кластеру Kubernetes с помощью инструмента командной строки gcloud от Google. Поскольку Kubernetes сохраняет свою конфигурацию в .yml-файлах, мы сохраняем их все в отдельном репозитории конфигурации и извлекаем их во время развертывания, поэтому у нас всегда есть последняя конфигурация кластера, доступная в нашем CI.

Мы считаем, что GitLab очень хорош - он бесплатный, а CI является мощным инструментом - единственный недостаток, который мы видим - это медленный веб-сайт. Тем не менее, мы довольны своим решением для plug and play, поэтому мы не жалуемся.

В заключение

Это все про нашу архитектуру. Мы заинтересованы в пожеланиях и предложениях, поэтому не стесняйтесь писать нам.

Этот пост лишь часть из серии постов:

  • Наша веб-платформа (часть 0)
    Объяснение изменений в стеке и целей для нашей новой архитектуры
  • Наш Back-end (часть 2)
    В этом посте мы расскажем какие архитектурные решения привели нас к переходу с PHP на Go.
  • Наш интерфейс (часть 3)
    React/Redux и последствия перехода на него.

Слушайте наш подкаст в iTunes и SoundCloud, читайте нас на Medium, контрибьютьте на GitHub, общайтесь в группе Telegram, следите в Twitter и канале Telegram, рекомендуйте в VK и Facebook.