Если кто-то спросит вас, как работает реестр в Dubbo, дайте ему эту статью

Java

Роль реестра

В первую очередь хочу подумать над вопросом, может ли Dubbo продолжать играть без регистрационного центра?

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

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

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

Основные функции регистрационного центра:

  1. При динамическом присоединении поставщик услуг динамически раскрывает себя потребителям через реестр, при этом потребителям не нужно обновлять файлы конфигурации один за другим.
  2. Динамическое обнаружение сервисов, потребители могут динамически обнаруживать новые сервисы без перезапуска.
  3. Унифицированная конфигурация, чтобы избежать несогласованной конфигурации каждой службы, вызванной локальной конфигурацией.
  4. Динамическая настройка, центр регистрации поддерживает динамическую настройку параметров, а новые параметры автоматически обновляются на всех соответствующих сервисных узлах.
  5. Унифицированное управление, основанное на данных реестра, позволяет управлять узлами обслуживания и настраивать их унифицированным образом.

Рабочий процесс реестра

Общий рабочий процесс регистрационного центра относительно прост, и его блок-схема примерно выглядит следующим образом:

dubbo注册中心.png

Основной рабочий процесс можно разделить на следующие этапы:

  1. После запуска поставщика услуг он регистрирует службу в реестре.
  2. После запуска потребитель активно подписывается на службу провайдера в реестре, чтобы получить все доступные в настоящее время службы, оставив при этом функцию обратного вызова.
  3. Если поставщик услуг добавлен или отключен, реестр уведомит потребителя с помощью функции обратного вызова, зарегистрированной на втором этапе.
  4. dubbo-admin (центр управления услугами) подпишется на поставщиков и потребителей услуг, чтобы всеми поставщиками и потребителями услуг можно было управлять в консоли.

Предыдущая версия Dubbo в основном может использовать ZooKeeper и Redis в качестве реестра.Постоянное обновление версии Dubbo также поддерживает nacos, consul и т. д. в качестве реестра.

Исходный код ядра реестра Dubbo

ps: следующий исходный код основан на версии dubbo 2.7.3.

Реестр реализует шаблонный режим, исходный код находится в модуле dubbo-registry, а отношение классов следующее:

image.png

самый верхнийRegistryServiceИнтерфейс определяет основные методы, а именно регистрацию, отмену регистрации, подписку, отмену подписки и запрос.

image.png

Абстрактный класс среднего уровня в основном реализует общую логику, например:AbstractRegistryреализовать механизм кэширования,FailbackRegistryРеализовать функцию повторной попытки отказа.

Нижний слойZookeeperRegistryEtc. — это конкретный класс реализации, реализующий логику взаимодействия с центрами регистрации, такими как ZooKeeper.

Далее подробно разбираемAbstractRegistryиFailbackRegistryлогика.

AbstractRegistryПринцип реализации кэша

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

Во-вторых, реестру нужны несильные зависимости, и его простои не могут повлиять на обычные вызовы службы.

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

Кэш службы в памяти

Кэш службы памяти хорошо изучен и его проще всего реализовать.AbstractRegistryиспользоватьConcurrentMapСохраните соответствующую информацию.

 private final ConcurrentMap<URL, Map<String, List<URL>>> notified = new ConcurrentHashMap<>();

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

кеш файлов на диске

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

Расположение кэша файлов по умолчанию находится в${user.home}/.dubbo/папка с именем файлаdubbo-registry-${application.name}-${register_address}.cache. можно установитьdubbo.registry.fileИнформация о конфигурации для изменения конфигурации по умолчанию, исходный код реализации выглядит следующим образом:

String filename = url.getParameter(Constants.FILE_KEY, System.getProperty("user.home") + "/.dubbo/dubbo-registry-" + url.getParameter(Constants.APPLICATION_KEY) + "-" + url.getAddress() + ".cache");

ps: {application.name} 取自 `dubbo.application.name` 信息,{register_address} принимает информацию об адресе регистрационного центра. Полное имя файла кэша:C:\Users\xxx/.dubbo/dubbo-registry-dubbo-auto-configure-consumer-sample-127.0.0.1:2181.cache

Использование содержимого файла кэшаpropertiesформат файла конфигурации, т.е.key=valueФормат. Ключ — это имя интерфейса службы, а значение — список служб, так как служб может быть несколько, они будут разделены пробелами.

Загрузка кэшированных файлов

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

Исходный код инициализации кеша выглядит следующим образом.

loadProperties.png

Сохранение и обновление файлов кеша

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

notifyИсходный код метода выглядит следующим образом:

notify.png

В методе кэширования файла сохранения сначала объединяются данные, полученные из URL-адреса, в строку, а затем записывается вышеупомянутыйpropertiesобъект и, наконец, вывод в файл.

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

savePropertiesИсходный код метода выглядит следующим образом:

saveProperties.png

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

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

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

ps: До dubbo 2.7.2 максимальное количество повторов не устанавливалось.Если у файла нет разрешения на сохранение, сохранение всегда будет неудачным, а асинхронный поток попадет в бесконечный цикл.

doSavePropertiesИсходный код метода выглядит следующим образом:

doSaveProperties.png

FailbackRegistryмеханизм повторной попытки

FailbackRegistryнаследоватьAbstractRegistry, выполненоregister,subscribeи других норм общего права, и добавитьdoRegister,doSubscribeи другие шаблонные методы, которые реализуются подклассами.

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

FailbackRegistryНеудачные наборы повторных попыток:

retrytaskmap.png

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

FailbackRegistry#subscribeИсходный код метода:

subscribe.png

существуетaddFailedSubscribedБудет создана новая запланированная задача, которая затем будет передана таймеру для выполнения. Максимальное количество попыток по умолчанию для запланированных задач — 3, а интервал вызова по умолчанию — 5 с.

addFailedSubscribedИсходный код выглядит следующим образом:

addFailedSubscribed.png

Другие неудачные повторные попытки аналогичны, все они унаследованы отAbstractRetryTaskРодительский класс, отношения классов показаны ниже.

image.png

Суммировать

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

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

справочные книги

«Глубокое понимание Apache Dubbo и реальных боевых действий»

其他平台.png