Традиционные автономные приложения не очень динамичны, редко обновляются и переиздаются и редко автоматически масштабируются. Однако с популяризацией распределенных интернет-систем требования к масштабируемости и масштабируемости между сервисами также возрастают. Чтобы соответствовать вертикальному и горизонтальному расширению служб, в прошлом для настройки служб обычно использовались предварительно определенные порты.Когда новые службы должны быть подключены к сети или текущие службы нуждаются в избыточном расширении, нам необходимо статически «зарегистрировать» соответствующий IP-адрес. и информацию о порте в В одном месте информация синхронизируется через штатный метод "обновления" между программами, но с этим методом много проблем.Например когда нам нужно подключиться к мастеру Кафки, если меняется служебная информация , клиенту трудно узнать. Одним из простых и грубых способов является настройка файла hosts и использование предопределенного «доменного имени» в качестве основы для подключения к сервису, но это тоже хлопотно.При изменении сервиса файл hosts приходится менять вручную. относительно много услуг на сервере Down, сумма обслуживания просто ужас.
По сути, одним предложением: больше сервисов, больше проблем
Обнаружение службы не является панацеей. Если поставщик службы задач зависает, на самом деле сложно уведомить вызывающего абонента на 100% в режиме реального времени. Тем не менее необходимо повысить доступность службы в целом с помощью разумной архитектуры или методов аварийного восстановления.
В условиях тенденции микросервисов, чтобы максимизировать гибкость расширения и сокращения, такие методы, как служба имен и обнаружение служб, становятся все более и более популярными.
В настоящее время основными компонентами обнаружения службы являются: consul, etcd, zookeeper, различия здесь не объясняются, и те, кто заинтересован, могут прочитать официальное введение консула:«Консул против ZooKeeper, doozerd и т. д.»
Основная цель этой статьи — изучить принципы консула, построить кластерное решение и реализовать функции регистрации и обнаружения сервисов, чтобы у нас было четкое представление о сервисе имен микросервисной архитектуры.
Архитектура Consul Service и основные концепции
На следующем рисунке показана архитектурная схема консула в измерении центра обработки данных.СЕРВЕР на рисунке — это кластер высокой доступности сервера консула, а КЛИЕНТ — это клиент консула. Клиент-консул не сохраняет данные, а клиент пересылает полученный запрос отвечающему серверу. Согласованность данных достигается между серверами через локальную или глобальную сеть. Каждый сервер или клиент является агентом-консулом, или сервер и клиент — это просто разные роли, которые играет агент.
(картинка взята с официального сайта)
Как видно из рисунка выше, консул использует протокол сплетен для управления членством и широковещательной рассылкой сообщений всему кластеру.
Консул использует два разных пула сплетен. Мы называем их LAN Gossip Pool или WAN Gossip Pool соответственно. Каждый центр обработки данных Consul (Datacenter) имеет пул сплетен в локальной сети, который содержит всех участников (сервер и клиент).
LAN Pool имеет следующие цели:
-
Членство позволяет клиентам автоматически обнаруживать серверные узлы, уменьшая объем требуемой конфигурации.
-
Распределенное обнаружение отказов позволяет выполнять работу по обнаружению отказов в нескольких точках сервера, а не централизованно на всех узлах всего кластера.
-
сплетни позволяют надежно и быстро транслировать события, такие как выборы лидеров
Пул WAN глобально уникален, независимо от того, к какому центру обработки данных он принадлежит, все серверы должны быть добавлены в пул WAN. Информация о членстве предоставляется пулом WAN, чтобы серверные узлы могли выполнять запросы между центрами обработки данных. Другими словами, этот пул отличается от пула LAN, и его цель — позволить центрам обработки данных обнаруживать друг друга с минимальным вмешательством. Когда сервер в центре обработки данных получает запрос из другого центра обработки данных, он может перенаправить запрос ведущему в центре обработки данных.
В каждом центре обработки данных клиенты и серверы смешаны. Обычно рекомендуется иметь 3-5 серверов. Это основано на компромиссе между доступностью и производительностью в случае сбоя, поскольку чем больше машин подключается, тем медленнее достигается консенсус. Однако количество клиентов не ограничено, их можно легко масштабировать до тысяч или десятков тысяч.
Консул кластерное здание
Подготовка окружающей среды
Чтобы изучить сервисы, предоставляемые Consul, для реализации регистрации и обнаружения сервисов, нам нужно установить тестовое кластерное решение для Consul Cluster.На самом деле создать кластер очень просто.Каждому серверу нужно только запустить команду консул агент, а потом разделить сервер и клиент по их ролям. Здесь наш план тестового развертывания представляет собой архитектуру с 3 серверами и 1 клиентом в центре обработки данных.
Чтобы продемонстрировать построение кластера, мы готовим четыре тестовых задания:
окрестности | IP-адрес сервера | имя узла | Роль |
---|---|---|---|
centos 7.2 | 172.17.0.3 | s1 | server |
centos 7.2 | 172.17.0.4 | s2 | server |
centos 7.2 | 172.17.0.5 | s3 | server |
centos 7.2 | 172.17.0.6 | c1 | client |
Скачайте пакет консула на каждый сервер отдельно:
Консул, используемый в этом примере, имеет версию 1.1.0.
wget https://releases.hashicorp.com/consul/1.1.0/consul_1.1.0_linux_amd64.zip
unzip consul_1.1.0_linux_amd64.zip
После распаковки видно, что бинарный файл консула всего один, перемещаем его в директорию /usr/local/bin:
cp consul /usr/local/bin/
Затем проверьте, успешно ли установлен консул, выполнив команду:
consul -h
Usage: consul [--version] [--help] <command> [<args>]
Available commands are:
agent Runs a Consul agent
catalog Interact with the catalog
event Fire a new event
exec Executes a command on Consul nodes
force-leave Forces a member of the cluster to enter the "left" state
info Provides debugging information for operators.
join Tell Consul agent to join cluster
keygen Generates a new encryption key
keyring Manages gossip layer encryption keys
kv Interact with the key-value store
leave Gracefully leaves the Consul cluster and shuts down
lock Execute a command holding a lock
maint Controls node or service maintenance mode
members Lists the members of a Consul cluster
monitor Stream logs from a Consul agent
operator Provides cluster-level tools for Consul operators
reload Triggers the agent to reload configuration files
rtt Estimates network round trip time between nodes
snapshot Saves, restores and inspects snapshots of Consul server state
validate Validate config files/directories
version Prints the Consul version
watch Watch for changes in Consul
После установки консула на каждый тестовый сервер кластера мы можем начать сборку кластера.
s1 запускает службу консула:
Команда выполнения консула выглядит следующим образом:
consul agent -server -bootstrap-expect 1 -data-dir /data/consul/ -node=s1 -bind=172.17.0.3 -rejoin -config-dir=/etc/consul.d/ -client 0.0.0.0
В приведенной выше команде мы будем использовать несколько важных параметров:
-
сервер: укажите, что агент работает в режиме сервера, если это режим клиента, вам не нужно добавлять этот параметр.
-
bootstrap-expect: ожидаемое количество серверных узлов в центре обработки данных. Когда указано это значение, консул не будет загружать (запускать) весь кластер до тех пор, пока не будет достигнуто указанное количество серверов. Для тестовой демонстрации мы используем 1 здесь.
-
bind: Этот адрес используется для связи внутри кластера. Все узлы в кластере должны быть доступны по этому адресу. По умолчанию 0.0.0.0
-
node: имя узла в кластере, должно быть уникальным в кластере, по умолчанию используется имя хоста узла
-
rejoin: заставить консула игнорировать предыдущую процедуру выхода и по-прежнему пытаться присоединиться к кластеру после повторного запуска агента. То есть, если этот параметр не добавлен, после выхода текущего узла он не будет автоматически добавлен в кластер после следующего перезапуска, если он не будет запущен вручную.
consul join xxxx
, поэтому, чтобы уменьшить влияние на собственный сервис после перезапуска, здесь единообразно используется параметр -rejoin. -
config-dir: Каталог файлов конфигурации.Файлы в нем единообразно оговорены, что файлы, оканчивающиеся на .json, будут автоматически загружаться и считывать регистрационную информацию службы.
-
клиент: адрес прослушивания службы консула.Узел агента консула в режиме клиента относительно прост и не имеет состояния и отвечает только за пересылку запросов на узел агента сервера.
Когда служба запускается, фоновый вывод похож на следующую информацию журнала:
$ consul agent -server -bootstrap-expect 1 -data-dir /data/consul/ -node=s1 -bind=172.17.0.3 -rejoin -config-dir=/etc/consul.d/ -client 0.0.0.0
BootstrapExpect is set to 1; this is the same as Bootstrap mode.
bootstrap = true: do not enable unless necessary
==> Starting Consul agent...
==> Consul agent running!
Version: 'v1.1.0'
Node ID: 'cccf0fec-2fd9-30d0-9105-8dd2ae6480d6'
Node name: 's1'
Datacenter: 'dc1' (Segment: '<all>')
Server: true (Bootstrap: true)
Client Addr: [0.0.0.0] (HTTP: 8500, HTTPS: -1, DNS: 8600)
Cluster Addr: 172.17.0.3 (LAN: 8301, WAN: 8302)
Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false
==> Log data will now stream in as it occurs:
2018/05/31 03:54:36 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:cccf0fec-2fd9-30d0-9105-8dd2ae6480d6 Address:172.17.0.3:8300}]
2018/05/31 03:54:36 [INFO] raft: Node at 172.17.0.3:8300 [Follower] entering Follower state (Leader: "")
2018/05/31 03:54:36 [INFO] serf: EventMemberJoin: s1.dc1 172.17.0.3
2018/05/31 03:54:36 [WARN] serf: Failed to re-join any previously known node
2018/05/31 03:54:36 [INFO] serf: EventMemberJoin: s1 172.17.0.3
2018/05/31 03:54:36 [WARN] serf: Failed to re-join any previously known node
2018/05/31 03:54:36 [INFO] consul: Adding LAN server s1 (Addr: tcp/172.17.0.3:8300) (DC: dc1)
2018/05/31 03:54:36 [INFO] consul: Handled member-join event for server "s1.dc1" in area "wan"
2018/05/31 03:54:36 [INFO] agent: Started DNS server 0.0.0.0:8600 (udp)
2018/05/31 03:54:36 [INFO] agent: Started DNS server 0.0.0.0:8600 (tcp)
2018/05/31 03:54:36 [INFO] agent: Started HTTP server on [::]:8500 (tcp)
2018/05/31 03:54:36 [INFO] agent: started state syncer
2018/05/31 03:54:43 [ERR] agent: failed to sync remote state: No cluster leader
2018/05/31 03:54:45 [WARN] raft: Heartbeat timeout from "" reached, starting election
2018/05/31 03:54:45 [INFO] raft: Node at 172.17.0.3:8300 [Candidate] entering Candidate state in term 3
2018/05/31 03:54:45 [INFO] raft: Election won. Tally: 1
2018/05/31 03:54:45 [INFO] raft: Node at 172.17.0.3:8300 [Leader] entering Leader state
2018/05/31 03:54:45 [INFO] consul: cluster leadership acquired
2018/05/31 03:54:45 [INFO] consul: New leader elected: s1
2018/05/31 03:54:45 [INFO] agent: Synced node info
Давайте проверим информацию о составе членов кластера:
$ consul members
[root@f147f8eb5593 /]# consul members
Node Address Status Type Build Protocol DC Segment
s1 172.17.0.3:8301 alive server 1.1.0 2 dc1 <all>
В выходных данных команды видно, что в текущем кластере есть только участник с именем s1, и его статус активен, что означает, что он работает нормально. dc1 — это имя центра обработки данных по умолчанию; Тип перечисляет роли участников, текущий сервер; в поле Адрес8301
Этот порт является LAN-портом агента по умолчанию (WAN-порт по умолчанию 8300), протокол предназначен только для совместимости разных версий агента в консул-кластере, разные версии агента и протокола могут иметь разные значения, поэтому не будем это.
Давайте сначала вернемся к рабочему журналу, и мы найдем это предложение:
New leader elected: s1
Это показывает, что после запуска текущего кластера выборы также будут происходить, когда есть только один член, и s1 выбирается автоматически.
Для подтверждения мы можем использовать consul API для запроса информации о лидере для подтверждения:
curl http://localhost:8500/v1/status/leader
"172.17.0.3:8300"
Кромеconsul members
В дополнение к команде вы также можете запросить информацию об участнике в кластере через официальный API (в настоящее время только один участник):
curl http://localhost:8500/v1/status/peers
["172.17.0.3:8300"]
Более подробную информацию о работе узла можно просмотреть с помощью команды consul info
После вышеописанной работы первый член нашего кластера считается развернутым, не останавливаемся, продолжаем добавлять в кластер разных участников :)
s2 запускает службу консула:
Подобно s1, команда выполнения консула s2 выглядит следующим образом:
consul agent -server -data-dir /data/consul/ -node=s2 -bind=172.17.0.4 -rejoin -config-dir=/etc/consul.d/ -client 0.0.0.0
Когда мы закончим выполнение вышеуказанной команды, мы просмотрим информацию о кластере на машине s2:
//172.17.0.4 s2
$ consul members
Node Address Status Type Build Protocol DC Segment
s2 172.17.0.4:8301 alive server 1.1.0 2 dc1 <all>
В это время он показывает, что кластер, в котором находится s2, имеет только себя и не нашел s1, который мы запускали ранее.
Вернемся к s1, чтобы увидеть информацию об участнике:
//172.17.0.3 s1
$ consul members
Node Address Status Type Build Protocol DC Segment
s1 172.17.0.3:8301 alive server 1.1.0 2 dc1 <all>
Из вышеприведенного явления мы можем узнать, что после запуска s2 он автоматически не присоединяется к предыдущему кластеру.В настоящее время нам нужно вручную добавить консульский агент s2:
//172.17.0.4 s2
$ consul join 172.17.0.3
successfully joined cluster by contacting 1 nodes.
Таким образом, независимо от того, является ли это s1 или s2, когда мы снова проверяем информацию об участнике, обе стороны находят друг друга по отдельности.
$ consul members
Node Address Status Type Build Protocol DC Segment
s1 172.17.0.3:8301 alive server 1.1.0 2 dc1 <all>
s2 172.17.0.4:8301 alive server 1.1.0 2 dc1 <all>
Помните параметр -rejoin нашей команды? Давайте посчитаем, будет ли он автоматически присоединяться к предыдущему кластеру, когда мы остановим и перезапустим s2
Мы выполняем следующие команды в s2:
//172.17.0.4 s2
$ consul leave
Graceful leave complete
Обратите внимание на информацию о члене s1:
$ consul members
Node Address Status Type Build Protocol DC Segment
s1 172.17.0.3:8301 alive server 1.1.0 2 dc1 <all>
s2 172.17.0.4:8301 left server 1.1.0 2 dc1 <all>
В это время состояние s2 уже оффлайн (левый), и после того, как мы его перепишем "подтянем", лог s2 показывает:
2018/05/31 05:48:03 [INFO] serf: Attempting re-join to previously known node: s1.dc1: 172.17.0.3:8302
2018/05/31 05:48:03 [INFO] agent: Started DNS server 0.0.0.0:8600 (udp)
2018/05/31 05:48:03 [INFO] serf: Attempting re-join to previously known node: s1: 172.17.0.3:8301
2018/05/31 05:48:03 [INFO] consul: Adding LAN server s2 (Addr: tcp/172.17.0.4:8300) (DC: dc1)
2018/05/31 05:48:03 [INFO] agent: Started DNS server 0.0.0.0:8600 (tcp)
2018/05/31 05:48:03 [INFO] agent: Started HTTP server on [::]:8500 (tcp)
2018/05/31 05:48:03 [INFO] agent: started state syncer
2018/05/31 05:48:03 [INFO] serf: EventMemberJoin: s1.dc1 172.17.0.3
2018/05/31 05:48:03 [INFO] serf: Re-joined to previously known node: s1.dc1: 172.17.0.3:8302
2018/05/31 05:48:03 [INFO] serf: EventMemberJoin: s1 172.17.0.3
2018/05/31 05:48:03 [INFO] serf: Re-joined to previously known node: s1: 172.17.0.3:8301
2018/05/31 05:48:03 [INFO] consul: Adding LAN server s1 (Addr: tcp/172.17.0.3:8300) (DC: dc1)
2018/05/31 05:48:03 [INFO] consul: New leader elected: s1
... ...
После перезагрузки вы можете увидеть журнал ключей:
Re-joined to previously known node: s1: 172.17.0.3:8301
На первый взгляд узел может автоматически вернуться в предыдущий кластер.Далее давайте посмотрим на информацию об участнике:
$ consul members
Node Address Status Type Build Protocol DC Segment
s1 172.17.0.3:8301 alive server 1.1.0 2 dc1 <all>
s2 172.17.0.4:8301 alive server 1.1.0 2 dc1 <all>
S2 действительно снова вернется в кластер, и эффект повторного присоединения будет достигнут.
s3 запускает службу консула:
Команда выполнения консула выглядит следующим образом:
consul agent -server -data-dir /data/consul/ -node=s3 -bind=172.17.0.5 -rejoin -config-dir=/etc/consul.d/ -client 0.0.0.0
Как и s2, при первом запуске не забудьте присоединиться к кластеру:
consul join 172.17.0.3
Подтвердить информацию об участнике:
$ consul members
Node Address Status Type Build Protocol DC Segment
s1 172.17.0.3:8301 alive server 1.1.0 2 dc1 <all>
s2 172.17.0.4:8301 alive server 1.1.0 2 dc1 <all>
s3 172.17.0.5:8301 alive server 1.1.0 2 dc1 <all>
На данный момент мы успешно запустили и запустили 3 сервера консула в нашем кластере.Далее давайте попробуем разные узлы роли.Мы пытаемся добавить клиентскую роль агента консула.
c1 запускает службу консула:
Команда выполнения консула выглядит следующим образом:
consul agent -data-dir /data/consul/ -node=c1 -bind=172.17.0.6 -rejoin -config-dir=/etc/consul.d/ -client 0.0.0.0
Как и в случае с s2 и s3, при первом запуске не забудьте присоединиться к кластеру:
consul join 172.17.0.3
Просмотр информации о кластере:
$ consul members
Node Address Status Type Build Protocol DC Segment
s1 172.17.0.3:8301 alive server 1.1.0 2 dc1 <all>
s2 172.17.0.4:8301 alive server 1.1.0 2 dc1 <all>
s3 172.17.0.5:8301 alive server 1.1.0 2 dc1 <all>
c1 172.17.0.6:8301 alive client 1.1.0 2 dc1 <default>
Поскольку в команде запуска c1 нет параметра -server, по умолчанию он будет работать в роли клиента.
Для полного теста попробуем еще раз протестировать консул-сервис, который отключает лидера (s1), а потом наблюдаем за запросом выборов
memberlist: Suspect s1 has failed, no acks received
2018/05/31 10:17:53 [INFO] memberlist: Suspect s1 has failed, no acks received
2018/05/31 10:17:54 [INFO] memberlist: Marking s1 as failed, suspect timeout reached (2 peer confirmations)
2018/05/31 10:17:54 [INFO] serf: EventMemberFailed: s1 172.17.0.3
2018/05/31 10:17:54 [INFO] consul: removing server s1 (Addr: tcp/172.17.0.3:8300) (DC: dc1)
2018/05/31 10:18:04 [INFO] consul: New leader elected: s3
2018/05/31 10:18:37 [INFO] serf: attempting reconnect to s1 172.17.0.3:8301
2018/05/31 10:19:07 [INFO] serf: attempting reconnect to s1 172.17.0.3:8301
curl http://localhost:8500/v1/status/leader
"172.17.0.5:8300"
Из приведенных выше журналов и информации возврата API после зависания s1 кластер выберет нового лидера как s3.
Таким образом, наше развертывание узла кластера и основная работа по тестированию в основном в порядке, и создать кластер с помощью consul довольно легко.
Пример обнаружения службы
Зарегистрировать тестовый сервис в консуле
Целью создания Consul Cluster является реализация регистрации и обнаружения сервисов.
Консул поддерживает два способа регистрации сервиса:
-
Зарегистрируйте HTTP API через службу Consul, и служба сама вызывает API для регистрации после запуска.
-
Зарегистрируйтесь, указав службу в файле конфигурации.
Документация Consul рекомендует использовать последний метод для настройки службы и регистрации службы, и конфигурация очень проста.Просто перейдите в каталог, указанный --config-dir в команде запуска, чтобы создать новый файл регистрации в формате json, например, например :
Зарегистрировать (развернуть) сервис на s3
//172.17.0.5 s3
touch /etc/consul.d/web.json
Затем заполните следующую регистрационную информацию (должна быть в стандартном формате Json)
{
"service": {
"name": "web",
"tags": ["master"],
"address": "172.17.0.5",
"port": 9999,
"checks": [
{
"http": "http://localhost:9999/health",
"interval": "10s"
}
]
}
}
Эта конфигурация заключается в том, что мы настраиваем веб-службу на узле s3. В этой службе мы определяем имя, адрес, порт и т. д. службы, а также включаем конфигурацию проверок для проверки работоспособности. Приведенный выше пример будет выполняться каждый 10 секунд один разhttp://localhost:9999/healthзапросить как проверку работоспособности
Зарегистрировать (развернуть) сервис на c1
Аналогично регистрируем аналогичный веб-сервис и на c1:
//172.17.0.6 c1
touch /etc/consul.d/web.json
Заполните следующее
{
"service": {
"name": "web",
"tags": ["master"],
"address": "172.17.0.6",
"port": 9999,
"checks": [
{
"http": "http://localhost:9999/health",
"interval": "10s"
}
]
}
}
После того, как и s3, и c1 создали файлы определения службы, нам нужно перезапустить агенты-консулы обоих, чтобы добиться эффекта обновления службы.
При запуске агентов-консулов s3 и c1, наблюдая за лог-информацией, мы обнаруживаем, что оба они одновременно сообщают следующую информацию:
2018/05/31 06:50:02 [INFO] agent: Synced service "web"
2018/05/31 06:50:03 [WARN] agent: Check "service:web" HTTP request failed: Get http://localhost:9999/health: dial tcp 127.0.0.1:9999: connect: connection refused
2018/05/31 06:50:03 [INFO] serf: EventMemberLeave: c1 172.17.0.6
2018/05/31 06:50:03 [DEBUG] raft-net: 172.17.0.5:8300
accepted connection from: 172.17.0.3:45189
2018/05/31 06:50:08 [INFO] serf: EventMemberJoin: c1 172.17.0.6
2018/05/31 06:50:13 [WARN] agent: Check "service:web" HTTP request failed: Get http://localhost:9999/health: dial tcp 127.0.0.1:9999: connect: connection refused
Эти журналы ошибок легко понять, потому что наша служба определяет API запроса для проверки работоспособности, но мы еще не предоставили эту услугу, поэтому мы продолжаем сообщатьconnection refused
Написать программу мониторинга здоровья
Наш веб-сервис для удобства тестирования просто предоставляет два интерфейса: один для проверки работоспособности и один для тестирования вывода запроса.
Код Go выглядит следующим образом:
package main
import (
"fmt"
"net/http"
"os"
"log"
)
var hostname, _ = os.Hostname()
func handler(w http.ResponseWriter, r *http.Request) {
log.Println("receive a request")
fmt.Fprintf(w, "result from %s\n", hostname)
}
func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("health check")
}
func main() {
http.HandleFunc("/", handler)
http.HandleFunc("/health", healthCheckHandler)
http.ListenAndServe(":9999", nil)
}
После компиляции поместите его в любой каталог s3 и c1
go build -o hc
S3 и c1 соответственно запускают веб-службу в фоновом режиме:
chmod +x hc
nohup /apps/svr/healthcheck/hc > /apps/svr/healthcheck/log.out &
После запуска веб-сервиса логи s3 и c1 будут показывать:
2018/05/31 07:02:03 [INFO] agent: Synced check "service:web"
Для полного представления услуг, предоставляемых в кластере, доступны определенные API:
$ curl http://localhost:8500/v1/catalog/service/web\?pretty
[
{
"ID": "a6d4ea77-47f4-7b7f-480c-dce6f705f091",
"Node": "c1",
"Address": "172.17.0.6",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "172.17.0.6",
"wan": "172.17.0.6"
},
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceID": "web",
"ServiceName": "web",
"ServiceTags": [
"master"
],
"ServiceAddress": "172.17.0.6",
"ServiceMeta": {},
"ServicePort": 10000,
"ServiceEnableTagOverride": false,
"CreateIndex": 591,
"ModifyIndex": 591
},
{
"ID": "7e836265-b197-89fb-e96a-26912ce69954",
"Node": "s3",
"Address": "172.17.0.5",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "172.17.0.5",
"wan": "172.17.0.5"
},
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceID": "web",
"ServiceName": "web",
"ServiceTags": [
"master"
],
"ServiceAddress": "172.17.0.5",
"ServiceMeta": {},
"ServicePort": 10000,
"ServiceEnableTagOverride": false,
"CreateIndex": 587,
"ModifyIndex": 587
}
]
Из информации, возвращаемой API, мы знаем, что и s3, и c1 являются поставщиками веб-сервисов.В настоящее время мы должны начать думать об одном: теперь, когда у нас есть веб-сервисы, как вызывать их по имени вместо использования Традиционный способ прямого IP-подключения
На самом деле первой реакцией в вашей голове может быть мысль:DNS解析
Обнаружение службы на основе DNS
Посмотрим, кто лидирует в текущем кластере
curl http://localhost:8500/v1/status/leader
"172.17.0.3:8300"
Поскольку текущим лидером является s1, наш тест службы имен DNS основан на s1.
В s1 выполните команду dig
$ dig @127.0.0.1 -p 8600 web.service.consul SRV
; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> @127.0.0.1 -p 8600 web.service.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14484
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 5
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN SRV
;; ANSWER SECTION:
web.service.consul. 0 IN SRV 1 1 10000 s3.node.dc1.consul.
web.service.consul. 0 IN SRV 1 1 10000 c1.node.dc1.consul.
;; ADDITIONAL SECTION:
s3.node.dc1.consul. 0 IN A 172.17.0.5
s3.node.dc1.consul. 0 IN TXT "consul-network-segment="
c1.node.dc1.consul. 0 IN A 172.17.0.6
c1.node.dc1.consul. 0 IN TXT "consul-network-segment="
;; Query time: 1 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Thu May 31 07:11:29 UTC 2018
;; MSG SIZE rcvd: 227
Видно, что в РАЗДЕЛЕ ОТВЕТОВ мы получили два результата: есть веб-сервис на s3 и c1. В команде dig мы использовали флаг SRV, потому что в нужной нам служебной информации есть не только ip-адрес, но и номер порта
В это время мы пытаемся остановить веб-сервис на c1:
pkill hc
Перепишите и выполните команду dig
$ dig @127.0.0.1 -p 8600 web.service.consul SRV
; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> @127.0.0.1 -p 8600 web.service.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59668
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN SRV
;; ANSWER SECTION:
web.service.consul. 0 IN SRV 1 1 10000 s3.node.dc1.consul.
;; ADDITIONAL SECTION:
s3.node.dc1.consul. 0 IN A 172.17.0.5
s3.node.dc1.consul. 0 IN TXT "consul-network-segment="
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Thu May 31 07:13:30 UTC 2018
;; MSG SIZE rcvd: 137
Результат показывает, что на s3 доступен только этот веб-сервис. Когда мы снова восстановим веб-службу c1, служебная информация s1 будет немедленно обновлена:
web.service.consul. 0 IN SRV 1 1 10000 c1.node.dc1.consul.
web.service.consul. 0 IN SRV 1 1 10000 s3.node.dc1.consul.
Помните API для веб-сервисов на c1 и s3? Как правило, вы можете позвонитьhttp://ip:9999/Чтобы получить информацию об имени хоста сервера, поскольку веб-сервис уже может быть «обнаружен» на s1, мы пытаемся протестировать его с помощью следующего запроса:
curl http://web.service.consul:9999/
К сожалению, мы сразу получили сообщение об ошибке:
curl: (6) Could not resolve host: web.service.consul; Unknown error
В настоящее время, несмотря на то, что имя службы было зарегистрировано и обнаружено в консуле, программа на сервере все еще не может его распознать, поэтому нам нужны дополнительные средства для решения этой проблемы.
подписаться на dnsmasq
yum -y install dnsmasq
После выполнения убедитесь, что установка прошла успешно:
$ dnsmasq -v
Dnsmasq version 2.76 Copyright (c) 2000-2016 Simon Kelley
Затем измените /etc/dnsmasq.conf.
В основном изменить несколько ключевых конфигураций:
Следующие изменения конфигурации в основном предназначены для облегчения нашего собственного тестирования.Для более стандартизированной конфигурации рекомендуется обратиться к соответствующим документам dnsmasq для самостоятельной настройки.
resolv-file=/etc/resolv.conf
strict-order
server=/consul/172.17.0.3#8600
Затем вам нужно изменить несколько строк конфигурации в /etc/resolv.conf:
nameserver 127.0.0.1
nameserver 172.17.0.3
#nameserver 8.8.8.8
Затем запустите dnsmasq и снова копайте:
dig @127.0.0.1 -p 8600 web.service.consul SRV
; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> @127.0.0.1 -p 8600 web.service.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20604
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 5
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN SRV
;; ANSWER SECTION:
web.service.consul. 0 IN SRV 1 1 10000 s3.node.dc1.consul.
web.service.consul. 0 IN SRV 1 1 10000 c1.node.dc1.consul.
;; ADDITIONAL SECTION:
s3.node.dc1.consul. 0 IN A 172.17.0.5
s3.node.dc1.consul. 0 IN TXT "consul-network-segment="
c1.node.dc1.consul. 0 IN A 172.17.0.6
c1.node.dc1.consul. 0 IN TXT "consul-network-segment="
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Thu May 31 08:57:25 UTC 2018
;; MSG SIZE rcvd: 227
Затем непосредственно копайте web.service.consul, чтобы убедиться, что машина, наконец, распознает службу имен:
$ dig web.service.consul SRV
; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> web.service.consul SRV
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61000
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 5
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN SRV
;; ANSWER SECTION:
web.service.consul. 0 IN SRV 1 1 10000 s3.node.dc1.consul.
web.service.consul. 0 IN SRV 1 1 10000 c1.node.dc1.consul.
;; ADDITIONAL SECTION:
s3.node.dc1.consul. 0 IN A 172.17.0.5
s3.node.dc1.consul. 0 IN TXT "consul-network-segment="
c1.node.dc1.consul. 0 IN A 172.17.0.6
c1.node.dc1.consul. 0 IN TXT "consul-network-segment="
;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu May 31 08:58:25 UTC 2018
;; MSG SIZE rcvd: 227
Хорошо, синтаксический анализ DNS-запросов веб-службы имен в настоящее время выполняется успешно, и, наконец, мы пытаемся запросить веб-API, чтобы узнать, будет ли он правильно возвращать информацию:
$ curl http://web.service.consul:9999
result from 5cade4f672b6
$ curl http://web.service.consul:9999
result from 5cade4f672b6
$ curl http://web.service.consul:9999
result from 579c1deb914f
$ curl http://web.service.consul:9999
result from 5cade4f672b6
$ curl http://web.service.consul:9999
result from 5cade4f672b6
$ curl http://web.service.consul:9999
result from 579c1deb914f
Приведенный выше запрос знает, что s1 успешно разрешает имя web.service.consul, и может успешно вызывать веб-службы s3 и c1.
Пока что расслабляться нельзя, и остался последний шаг для тестирования.Далее закрываем сервис s3 и наблюдаем за вызовом парсинга:
//s3
pkill hc
В это время мы запрашиваем разрешение имени в Интернете:
$ dig web.service.consul SRV
; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> web.service.consul SRV
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 650
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 3
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN SRV
;; ANSWER SECTION:
web.service.consul. 0 IN SRV 1 1 10000 c1.node.dc1.consul.
;; ADDITIONAL SECTION:
c1.node.dc1.consul. 0 IN A 172.17.0.6
c1.node.dc1.consul. 0 IN TXT "consul-network-segment="
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu May 31 09:03:44 UTC 2018
;; MSG SIZE rcvd: 137
Мы получаем доступ к curl последовательноweb.service.consul:9999Когда вывод:
result from 5cade4f672b6 //c1
Видно, что s1 в настоящее время может анализировать/обнаруживать только сервисы c1, что означает, что мы достигли динамического «офлайн» сервиса.
Когда мы снова восстанавливаем s3:
$ dig web.service.consul SRV
; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7 <<>> web.service.consul SRV
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9970
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 5
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul. IN SRV
;; ANSWER SECTION:
web.service.consul. 0 IN SRV 1 1 10000 c1.node.dc1.consul.
web.service.consul. 0 IN SRV 1 1 10000 s3.node.dc1.consul.
;; ADDITIONAL SECTION:
c1.node.dc1.consul. 0 IN A 172.17.0.6
c1.node.dc1.consul. 0 IN TXT "consul-network-segment="
s3.node.dc1.consul. 0 IN A 172.17.0.5
s3.node.dc1.consul. 0 IN TXT "consul-network-segment="
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu May 31 09:06:47 UTC 2018
;; MSG SIZE rcvd: 227
Веб-служба s3 может быть автоматически зарегистрирована в кластере служб, и демонстрация этого примера завершена.
Суммировать
До сих пор мы в основном продемонстрировали регистрацию службы и обнаружение службы веб-служб.Хотя этот пример относительно прост, принцип службы в реальном проекте также такой же.В сочетании с соответствующим архитектурным дизайном мы можем построить бизнес. функции обнаружения и регистрации служб.
От построения кластера до предоставления услуги обнаружения, инструмент консул довольно прост в использовании, но все же, высокая доступность услуги является всесторонней.При запуске производственной среды необходимо обратить внимание на конфигурацию времени кэширования DNS, а также поддержку управления доменными именами DNS. Consul — это не волшебная палочка, когда мы проектируем архитектуру, мы должны учитывать разумное взаимодействие между сервисами и более конкретные отказоустойчивые решения. Однако нельзя отрицать, что консул — отличное решение с точки зрения регистрации и обнаружения сервисов.