Статьи

Микросервисы для разработчиков Java: настройка, обнаружение служб и балансировка нагрузки

1. Конфигурация, обнаружение службы и балансировка нагрузки — Введение

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

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

2. Конфигурация

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

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

Приложение с двенадцатью факторами хранит конфигурацию в переменных среды (часто сокращается до env vars или env ). Env vars легко переключать между развертываниями без изменения кода; в отличие от конфигурационных файлов, существует небольшая вероятность того, что они случайно попадут в репозиторий; и в отличие от пользовательских файлов конфигурации или других механизмов конфигурации, таких как Java System Properties, они являются независимым от языка и ОС стандартом. https://12factor.net/config

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

2.1. Динамическая Конфигурация

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

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

Механизм динамической конфигурации действительно зависит от того, какой подход к управлению конфигурацией вы используете ( Consul , Zookeeper , Spring Cloud Config и т. Д.), Однако некоторые фреймворки, например Spring Cloud , снимают большую часть этого бремени с Разработчики.

2.2. Флаги

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

В экосистеме Java FF4J является, вероятно, самой популярной реализацией шаблона флагов функций . Другой библиотекой является Togglz, однако в настоящее время она не поддерживается активно . Если мы пойдем дальше, чем просто Java, стоит взглянуть на Unleash , готовая к работе функция, которая переключает сервис. Он имеет впечатляющий список SDK, доступных для многих языков программирования, включая Java .

2,3. Spring Cloud Config

Если ваши микросервисы построены на платформе Spring , то Spring Cloud Config — это один из самых доступных вариантов управления конфигурацией, с которого можно начать. Он обеспечивает поддержку как на стороне сервера, так и на стороне клиента (связь основана на протоколе HTTP ), исключительно прост в интеграции и даже встраивании в существующие сервисы.

Поскольку платформе JCG Car Rentals требуется сервис управления конфигурацией, давайте посмотрим, насколько просто его настроить с помощью Spring Cloud Config при поддержке Git .

01
02
03
04
05
06
07
08
09
10
11
server:
  port: 20100
   
spring:
  cloud:
    config:
      server:
        git:
          uri: file://${rentals.home}/rentals-config
  application:
    name: config-server

Для запуска экземпляра встроенного сервера конфигурации следует использовать идиоматический подход, основанный на аннотациях Spring Boot .

1
2
3
4
5
6
7
@SpringBootApplication
@EnableConfigServer
public class ConfigServerRunner {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerRunner.class, args);
    }
}

Хотя Spring Cloud Config имеет встроенную поддержку шифрования и дешифрования, вы также можете использовать ее вместе с HashiCorp Vault для управления конфиденциальными свойствами конфигурации и секретами .

2,4. Archaius

В пространстве универсальной библиотеки для управления конфигурацией, вероятно, Archaius из Netflix был бы самым известным (в случае платформы JVM). Он поддерживает динамические свойства конфигурации, сложные составные иерархии конфигурации, имеет встроенную поддержку Scala и может использоваться вместе с бэкэндом Zookeeper .

3. Обнаружение службы

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

Можно утверждать, что выполнимо передать список пар хост / порт всех запущенных экземпляров Inventory Service в Reservation Service, используя переменные среды, но это не совсем устойчиво. Что если служба инвентаризации была расширена или уменьшена? Или что, если некоторые экземпляры Inventory Service станут недоступными из-за сбоев в работе сети или просто выйдут из строя? Это действительно динамические, оперативные данные и должны рассматриваться как таковые.

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

3.1. JGroups

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

3.2. Atomix

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

3.3. эврика

Eureka , разработанная в Netflix , представляет собой сервис на основе REST , предназначенный для использования в основном в целях обнаружения сервисов (с акцентом на поддержку AWS ). Он написан исключительно на Java и включает в себя серверные и клиентские компоненты.

Это действительно не зависит от каких-либо рамок. Однако Spring Cloud Netflix обеспечивает превосходную интеграцию приложений и сервисов Spring Boot с рядом компонентов Netflix , включая абстракции над серверами и клиентами Eureka . Давайте посмотрим, как Eureka может извлечь выгоду из платформы JCG Car Rentals .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
server:
  port: 20200
   
eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false
    healthcheck:
      enabled: true
    serviceUrl:
      defaultZone: http://localhost:20201/eureka/
  server:
    enable-self-preservation: false
    wait-time-in-ms-when-sync-empty: 0
  instance:
    appname: eureka-server
    preferIpAddress: true

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

1
2
3
4
5
6
7
spring:
  application:
    name: eureka-server
  cloud:
    config:
      uri:
      - http://localhost:20100

Как и в примере с Spring Cloud Config , для запуска встроенного экземпляра сервера Eureka требуется только один аннотированный класс.

1
2
3
4
5
6
7
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerRunner {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerRunner.class, args);
    }
}

Что касается сервисов, клиент Eureka должен быть подключен и настроен для связи с сервером Eureka, который мы только что внедрили. Поскольку служба резервирования построена на основе Spring Boot , интеграция действительно проста и лаконична благодаря Spring Cloud Netflix .

01
02
03
04
05
06
07
08
09
10
11
eureka:
  instance:
    appname: reservation-service
    preferIpAddress: true
  client:
    register-with-eureka: true
    fetch-registry: true
    healthcheck:
      enabled: true
    service-url:
      defaultZone: http://localhost:20200/eureka/

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

Eureka Server Console
Eureka Server Console

Если вы ищете автономное обнаружение службы, Eureka может быть очень хорошим вариантом. Мы еще не сделали ничего сложного, но Eureka предлагает множество функций и параметров конфигурации.

3.4. Работник зоопарка

Apache ZooKeeper — это централизованный, высокодоступный сервис для управления конфигурацией и распределенной координации. Он является одним из пионеров распределенных координаторов с открытым исходным кодом, проверен годами в бою и служит надежной основой для многих других проектов.

Для приложений на основе JVM экосистема клиентских библиотек для работы с Apache ZooKeeper довольно богата. Apache Curator , изначально созданный в Netflix , предоставляет высокоуровневые абстракции, которые делают использование Apache ZooKeeper намного проще и надежнее. Важно отметить, что Apache Curator также включает набор рецептов для распространенных случаев использования и расширений, таких как обнаружение служб.

Еще больше хороших новостей для приложений на базе Spring, поскольку Spring Cloud Zookeeper предназначен исключительно для обеспечения интеграции Apache Zookeeper для приложений и сервисов Spring Boot . Подобно Apache Curator , он поставляется с общими шаблонами, включая обнаружение и настройку служб.

3.5. Etcd

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

3,6. консул

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

Консул API исключительно на основе HTTP, поэтому для работы с ним не требуется специальный клиент. Тем не менее, есть пара специализированных библиотек JVM, которые еще больше упрощают интеграцию с Consul , включая проект Spring Cloud Consul для приложений и сервисов Spring Boot .

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

4. Балансировка нагрузки

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

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

Как вы можете ожидать, балансировщики нагрузки могут находиться на разных уровнях OSI и должны поддерживать разные протоколы связи (например, TCP , UDP , HTTP , HTTP / 2 , gRPC ,…). С точки зрения реализации микросервисов наличие проверок работоспособности является необходимым операционным требованием, чтобы балансировщик нагрузки мог поддерживать актуальный набор живых экземпляров. Действительно интересно наблюдать за возобновлением усилий, связанных с формализацией проверок работоспособности , а именно форматом проверки работоспособности для HTTP API и протоколом проверки работоспособности GRPC .

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

4.1. Nginx

nginx — это программное обеспечение с открытым исходным кодом для веб-обслуживания, обратного прокси-сервера , кэширования, балансировки нагрузки трафика TCP / HTTP / UDP (в том числе HTTP / 2 и gRPC ), потокового мультимедиа и многого другого. Что делает nginx чрезвычайно популярным выбором, так это то, что его возможности выходят далеко за рамки простого распределения нагрузки, и он работает очень, очень хорошо.

4.2. HAProxy

HAProxy — это бесплатный, очень быстрый, надежный и высокопроизводительный балансировщик нагрузки TCP / HTTP (включая HTTP / 2 и gRPC ). Вместе с nginx он стал де-факто стандартным балансировщиком нагрузки с открытым исходным кодом, подходящим для большинства типов сред развертывания и рабочих нагрузок.

4,3. синапс

Synapse — это система для обнаружения сервисов, разработанная и открытая компанией Airbnb . Он является частью инфраструктуры SmartStack и построен на основе проверенного в бою Zookeeper , HAProxy (или nginx ).

4.4. Traefik

Traefik — очень популярный обратный прокси-сервер с открытым исходным кодом и балансировщик нагрузки . Он исключительно хорошо интегрируется с существующими компонентами инфраструктуры и поддерживает HTTP , Websocket и HTTP / 2 и gRPC . Одна из самых сильных сторон Traefik — его удобство в работе, поскольку он предоставляет метрики, журналы доступа, связывает веб-интерфейс пользователя и веб-API REST (ful) (помимо кластеризации, повторных попыток и прерывания цепи).

4,5. посланник

Envoy — представитель нового поколения пограничных и сервисных прокси. Он поддерживает расширенные функции балансировки нагрузки (включая повторные попытки, разрыв цепи, ограничение скорости, затенение запросов, локальную балансировку нагрузки зоны и т. Д.) И имеет первоклассную поддержку HTTP / 2 и gRPC . Кроме того, одна из уникальных функций Envoy — прозрачное проксирование HTTP / 1.1 в HTTP / 2 .

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

4,6. лента

До сих пор мы видели только серверные балансировщики нагрузки или вспомогательные машины, но пришло время представить Ribbon с открытым исходным кодом от Netflix , библиотеку IPC на стороне клиента со встроенным программным балансировщиком нагрузки . Он поддерживает протоколы TCP , UDP и HTTP и очень хорошо интегрируется с Eureka .

Spring Cloud Netflix также поддерживает Ribbon, поэтому его интеграция в приложения и сервисы Spring Boot действительно проста.

5. Облако

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

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

6. Выводы

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

7. Что дальше

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