В мире микросервисов несколько сервисов обычно распространяются в среде PaaS. Неизменяемая инфраструктура, например, предоставляемая контейнерами или неизменяемыми образами виртуальных машин. Услуги могут увеличиваться и уменьшаться на основе определенных предварительно определенных показателей. Точный адрес службы может быть неизвестен, пока служба не развернута и не готова к использованию.
Эта динамическая природа адреса конечной точки службы обрабатывается регистрацией и обнаружением службы. При этом каждая служба регистрируется у брокера и предоставляет более подробную информацию о себе, например адрес конечной точки. Другие потребительские сервисы затем запрашивают брокера, чтобы узнать местоположение сервиса и вызвать его. Существует несколько способов регистрации и запроса сервисов, таких как ZooKeeper, etcd, consul, Kubernetes, Netflix Eureka и других.
Рефакторинг от монолитного до микросервисного обслуживания показал, как выполнить рефакторинг существующего монолита в приложение на основе микросервиса. URI пользователя, каталога и сервиса заказа были определены статически. Этот блог покажет, как регистрировать и обнаруживать микросервисы с помощью ZooKeeper .
Большое спасибо Иоаннису Канеллосу ( @iocanel ) за все взломы ZooKeeper!
Что такое ZooKeeper?
ZooKeeper является проектом Apache и предоставляет распределенное, в конечном итоге согласованное хранилище иерархической конфигурации.
ZooKeeper — это централизованный сервис для поддержки информации о конфигурации, наименования, предоставления распределенной синхронизации и предоставления групповых услуг. Все эти виды услуг в той или иной форме используются распределенными приложениями.
Таким образом, служба может зарегистрироваться в ZooKeeper с использованием логического имени, а информация о конфигурации может содержать конечную точку URI. Он может состоять и из других деталей, таких как QoS.
У ZooKeeper есть крутая кривая обучения, как описано в Apache ZooKeeper Made Simpler with Curator . Таким образом, вместо непосредственного использования ZooKeeper в этом блоге будет использоваться Apache Curator .
Куратор 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 -p
2181
:
2181
fabric8/zookeeper
- Проверьте экземпляр ZooKeeper, используя
telnet
как:1telnet $(docker-machine ip dockerhost)
Введите команду «ruok», чтобы убедиться, что сервер работает без ошибок. Сервер ответит «imok», если он работает:
12345Trying
192.168
.
99.103
...
Connected to dockerhost.
Escape character is
'^]'
.
ruok
imokConnection 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" ; @PostConstruct public void registerService() { services.registerService(serviceName, endpointURI); } @PreDestroy public void unregisterService() { services.unregisterService(serviceName, endpointURI); } |
Код довольно прост, он внедряет класс @ZooKeeperRegistry
квалификатором @ZooKeeperRegistry
. Затем он используется для регистрации и отмены регистрации службы. Несколько URI, по одному для службы без сохранения состояния, могут быть зарегистрированы под одним логическим именем.
В это время квалификатор приходит из другого модуля maven. Более @ZooKeeperRegistry
способ Java EE — переместить @ZooKeeperRegistry
в расширение CDI ( # 20 ). И когда этот спецификатор при указании на любой конечной точке REST зарегистрирует сервис с ZooKeeper ( # 22 ). На данный момент URI конечной точки службы также жестко задан ( # 24 ).
Как выглядит класс ZooKeeper
?
- Класс
ZooKeeper
использует инжектор конструктора иZooKeeper
IP-адреса и порта ( # 23 ):01020304050607080910111213141516171819202122@ApplicationScoped
public
class
ZooKeeper
implements
ServiceRegistry {
private
final
CuratorFramework curatorFramework;
private
final
ConcurrentHashMap<String, String> uriToZnodePath;
@Inject
public
ZooKeeper() {
try
{
Properties props =
new
Properties();
props.load(
this
.getClass().getResourceAsStream(
"/zookeeper.properties"
));
curatorFramework = CuratorFrameworkFactory
.newClient(props.getProperty(
"host"
)
+
":"
+ props.getProperty(
"port"
),
new
RetryNTimes(
5
,
1000
));
curatorFramework.start();
uriToZnodePath =
new
ConcurrentHashMap<>();
}
catch
(IOException ex) {
throw
new
RuntimeException(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);
return
new
String(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 microservice
mvn install
- Доступ к приложению на локальном хосте: 8080 / everest-web / . Узнайте больше о приложении и различных компонентах в статье Рефакторинг от монолитных до микросервисов для приложений Java EE .
Наслаждайтесь!
Ссылка: | ZooKeeper для регистрации и обнаружения микросервисов от нашего партнера по JCG Аруна Гупта в блоге Miles to go 2.0… . |