В мире микросервисов несколько сервисов обычно распространяются в среде PaaS. Неизменяемая инфраструктура, например, предоставляемая контейнерами или неизменяемыми образами виртуальных машин. Услуги могут увеличиваться и уменьшаться на основе определенных предварительно определенных показателей. Точный адрес службы может быть неизвестен, пока служба не развернута и не готова к использованию.
Эта динамическая природа адреса конечной точки службы обрабатывается регистрацией и обнаружением службы. При этом каждая служба регистрируется у брокера и предоставляет более подробную информацию о себе, например адрес конечной точки. Другие потребительские сервисы затем запрашивают брокера, чтобы узнать местоположение сервиса и вызвать его. Существует несколько способов регистрации и запроса сервисов, таких как ZooKeeper, etcd, consul, Kubernetes, Netflix Eureka и других.
Рефакторинг от монолитного до микросервисного обслуживания показал, как выполнить рефакторинг существующего монолита в приложение на основе микросервиса. URI пользователя, каталога и сервиса заказа были определены статически. Этот блог покажет, как регистрировать и обнаруживать микросервисы с помощью ZooKeeper .
Большое спасибо Иоаннису Канеллосу ( @iocanel ) за все взломы ZooKeeper!
Что такое ZooKeeper?
ZooKeeper является проектом Apache и предоставляет распределенное, в конечном итоге согласованное хранилище иерархической конфигурации.
ZooKeeper — это централизованный сервис для поддержки информации о конфигурации, наименования, предоставления распределенной синхронизации и предоставления групповых услуг. Все эти виды услуг в той или иной форме используются распределенными приложениями.
Таким образом, служба может зарегистрироваться в ZooKeeper с использованием логического имени, а информация о конфигурации может содержать конечную точку URI. Он может состоять и из других деталей, таких как QoS.

Куратор n ˈkyoor͝ˌātər: хранитель или хранитель музея или другой коллекции — Хранитель ZooKeeper.
Apache Curator имеет несколько компонентов, и этот блог будет использовать Framework :
Curator Framework — это высокоуровневый API, который значительно упрощает использование ZooKeeper. Он добавляет множество функций, основанных на ZooKeeper, и обрабатывает сложность управления соединениями с кластером ZooKeeper и повторных операций.
ZooKeeper Concepts
Обзор ZooKeeper предоставляет отличный обзор основных концепций. Вот некоторые из соответствующих:
- Znodes : ZooKeeper хранит данные в общем иерархическом пространстве имен, которое организовано как стандартная файловая система. Пространство имен состоит из регистров данных — называемых znodes , на языке ZooKeeper — и они похожи на файлы и каталоги.
- Имя узла : каждый узел в пространстве имен ZooKeeper идентифицируется путем. Точное имя узла — это последовательность элементов пути, разделенных косой чертой (/).
- Клиент / сервер : клиенты подключаются к одному серверу ZooKeeper. Клиент поддерживает TCP-соединение, через которое он отправляет запросы, получает ответы, получает события наблюдения и отправляет удары сердца. Если TCP-соединение с сервером разрывается, клиент подключится к другому серверу.
- Данные конфигурации : с каждым узлом в пространстве имен ZooKeeper могут быть связаны как данные, так и дочерние элементы. Изначально ZooKeeper был разработан для хранения координационных данных, поэтому данные, хранящиеся на каждом узле, обычно невелики (в диапазоне менее КБ).
- Ансамбль : сам ZooKeeper предназначен для репликации на наборы хостов, называемых ансамблем. Серверы, которые составляют сервис ZooKeeper, должны знать друг о друге.
- Часы : ZooKeeper поддерживает концепцию часов . Клиенты могут установить часы на znode. Часы будут срабатывать и удаляться при изменении znode.
ZooKeeper является системой CP относительно теоремы CAP. Это означает, что в случае сбоя раздела он будет согласованным, но недоступным. Это может привести к проблемам, которые объясняются в Eureka! Почему вы не должны использовать ZooKeeper для обнаружения сервисов .
Тем не менее, ZooKeeper — один из самых популярных механизмов обнаружения услуг, используемых в мире микросервисов.
Давайте начнем!
Запустить ZooKeeper
- Запустите экземпляр ZooKeeper в контейнере Docker:
1
docker run -d -p2181:2181fabric8/zookeeper - Проверьте экземпляр ZooKeeper, используя
telnetкак:1telnet $(docker-machine ip dockerhost)Введите команду «ruok», чтобы убедиться, что сервер работает без ошибок. Сервер ответит «imok», если он работает:
12345Trying192.168.99.103...Connected to dockerhost.Escape character is'^]'.ruokimokConnection closed by foreign host.В противном случае он не будет отвечать вообще. ZooKeeper имеет другие похожие четырехбуквенные команды.
Служба регистрации и обнаружения
Каждый сервис, Пользователь, Каталог и Заказ в нашем случае, имеет нетерпеливо инициализированный компонент, который регистрирует и отменяет регистрацию сервиса как часть методов инициализации жизненного цикла, как. Вот код из CatalogService :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@Inject @ZooKeeperRegistry ServiceRegistry services;private static final String serviceName = "catalog";@PostConstructpublic void registerService() { services.registerService(serviceName, endpointURI);}@PreDestroypublic void unregisterService() { services.unregisterService(serviceName, endpointURI);} |
Код довольно прост, он внедряет класс @ZooKeeperRegistry квалификатором @ZooKeeperRegistry . Затем он используется для регистрации и отмены регистрации службы. Несколько URI, по одному для службы без сохранения состояния, могут быть зарегистрированы под одним логическим именем.
В это время квалификатор приходит из другого модуля maven. Более @ZooKeeperRegistry способ Java EE — переместить @ZooKeeperRegistry в расширение CDI ( # 20 ). И когда этот спецификатор при указании на любой конечной точке REST зарегистрирует сервис с ZooKeeper ( # 22 ). На данный момент URI конечной точки службы также жестко задан ( # 24 ).
Как выглядит класс ZooKeeper ?
- Класс
ZooKeeperиспользует инжектор конструктора иZooKeeperIP-адреса и порта ( # 23 ):01020304050607080910111213141516171819202122@ApplicationScopedpublicclassZooKeeperimplementsServiceRegistry {privatefinalCuratorFramework curatorFramework;privatefinalConcurrentHashMap<String, String> uriToZnodePath;@InjectpublicZooKeeper() {try{Properties props =newProperties();props.load(this.getClass().getResourceAsStream("/zookeeper.properties"));curatorFramework = CuratorFrameworkFactory.newClient(props.getProperty("host")+":"+ props.getProperty("port"),newRetryNTimes(5,1000));curatorFramework.start();uriToZnodePath =newConcurrentHashMap<>();}catch(IOException ex) {thrownewRuntimeException(ex.getLocalizedMessage());}}Он выполняет следующие задачи:
- Загружает хост / порт ZooKeeper из файла свойств
- Инициализирует фреймворк куратора и запускает его
- Инициализирует хэш-карту для сохранения имени URI в сопоставлении zNode. Этот узел удаляется позже, чтобы отменить регистрацию службы.
- Регистрация сервиса осуществляется с помощью метода
registerService:010203040506070809101112String znode ="/services/"+ name;if(curatorFramework.checkExists().forPath(znode) ==null) {curatorFramework.create().creatingParentsIfNeeded().forPath(znode);}String znodePath = curatorFramework.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(znode+"/_", uri.getBytes());uriToZnodePath.put(uri, znodePath);Код довольно прост:
- Создайте родительский zNode, если это необходимо
- Создать эфемерный и последовательный узел
- Добавить метаданные, включая URI, к этому узлу
- Обнаружение службы выполняется методом
discoverкак:1234String znode ="/services/"+ name;List<String> uris = curatorFramework.getChildren().forPath(znode);returnnewString(curatorFramework.getData().forPath(ZKPaths.makePath(znode, uris.get(0))));Опять же, простой код:
- Найти всех детей по пути, зарегистрированному для службы
- Получить метаданные, связанные с этим узлом, в нашем случае URI, и return. Первый такой узел возвращается в этом случае. Различные параметры QoS могут быть присоединены к данным конфигурации. Это позволит вернуть соответствующую конечную точку сервиса.
Читайте ZooKeeper Javadocs для API.
Часы ZooKeeper можно настроить для информирования клиента о жизненном цикле службы ( # 27 ). Кэши путей ZooKeeper могут обеспечить оптимизированную реализацию дочерних узлов ( # 28 ).
Несколько реализаций обнаружения сервисов
Наше приложение для корзины покупок имеет две реализации для обнаружения служб — ServiceDisccoveryStatic и ServiceDiscoveryZooKeeper . В первом все статические URI определены статически, а во втором они извлекаются из ZooKeeper.
Другие способы регистрации и обнаружения могут быть легко добавлены путем создания нового пакета в модуле services и реализации интерфейса ServiceRegistry . Например, Snoop , etcd , Consul и Kubernetes . Не стесняйтесь отправить PR для любого из них.
Запустить приложение
- Убедитесь, что образ ZooKeeper работает, как описано ранее.
- Скачайте и запустите WildFly:
1
./bin/standalone.sh - Разверните приложение:
12
cd microservicemvn install - Доступ к приложению на локальном хосте: 8080 / everest-web / . Узнайте больше о приложении и различных компонентах в статье Рефакторинг от монолитных до микросервисов для приложений Java EE .
Наслаждайтесь!
| Ссылка: | ZooKeeper для регистрации и обнаружения микросервисов от нашего партнера по JCG Аруна Гупта в блоге Miles to go 2.0… . |

