Чего вы не знаете о Dubbo Cluster.

Java
Чего вы не знаете о Dubbo Cluster.

Это 33-я оригинальная статья о том, почему технологии

Эта неделя — неделя работы из дома, а на картинке выше — моя рабочая станция дома.

Если рабочий хочет хорошо работать, он должен сначала заточить свои инструменты. Работаю из дома, я серьезно.

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

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

(Разве этот поворот не немного тупой....)

Итак, возьмите эту статью для подробного анализа кластера Dubbo Cluster и стратегии отказоустойчивого кластера (автоматическое переключение при отказе).

Если в этой статье нет специального описания, исходный код последней версии 2.7.5.

Несколько вопросов перед чтением:

1. Какова роль кластера Dubbo?

2. Можете ли вы назвать несколько из 10 классов реализации Dubbo Cluster и какие из них являются отказоустойчивыми методами кластера?

3. Каков класс реализации кластера по умолчанию?

4. После сбоя вызова отказоустойчивого кластера, сколько раз он будет автоматически повторяться?

5. Что такое липкое соединение Даббо?

6. Как используется липкое соединение в кластере?

7. Сколько раз Кластер выбирает доступного Инвокера?

8. Какие есть варианты несколько раз?

Примечание. Из 8 приведенных выше вопросов первые 3 являются очень распространенными вопросами интервью. Ниже приведены ответы на вопросы, которые вы можете узнать после прочтения этой статьи.Это не часто встречается в интервью, но последние вопросы могут быть синтезированы вОчень частый вопрос на интервью: Вы видели какой-нибудь исходный код, можете рассказать мне о нем?

Эта статья объяснит вышеуказанные вопросы один за другим и подробно. В конце статьи будет краткое изложение вопросов и ответов.

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

Какова роль кластера Dubbo?

В производственной среде мы часто запускаем одно и то же приложение на нескольких серверах.Одна из целей этого — избежать единой точки отказа.

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

Таким образом, количество поставщиков услуг в одной среде будет больше одного. Для потребителей услуг несколько поставщиков услуг появляются в одной среде.

На этом этапе возникает несколько проблем:По запросу, к какому поставщику мне звонить как потребителю? Что делать, если вызов службы не удался? повторить? Выбрасывается ли исключение? Или просто распечатать исключение?

Чтобы справиться с этими проблемами,Dubbo определяет интерфейс кластера Cluster и Cluster Invoker.

Целью кластера является объединение нескольких поставщиков услуг в Cluster Invoker и предоставление этого Invoker потребителям услуг.

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

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

Каковы 10 классов реализации Dubbo Cluster?

В соответствии с конфигурацией можно узнать, что интерфейс кластера Dubbo Cluster имеет 10 следующих методов реализации:

Следует отметить, что среди десяти методов реализации толькоШесть типов аварийного переключения, отказоустойчивого, отказоустойчивого, отказоустойчивого, разветвленного и широковещательного относятся к категории отказоустойчивости кластера.. Другие реализации имеют другие сценарии применения.

Давайте сначала поговорим о шести методах реализации отказоустойчивости кластера:

Отказоустойчивый кластер:

failover=org.apache.dubbo.rpc.cluster.support.FailoverCluster

Не удается автоматически переключиться, при сбое вызова, не удается автоматически переключиться, при сбое повторить попытку других серверов. Обычно используется для операций чтения, но повторные попытки вызывают более длительные задержки. Количество повторных попыток (исключая первый раз) можно установить с помощью retries="2".

Отказоустойчивый кластер:

failfast=org.apache.dubbo.rpc.cluster.support.FailfastCluster

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

Отказоустойчивый кластер:

failsafe=org.apache.dubbo.rpc.cluster.support.FailsafeCluster

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

Отказоустойчивый кластер:

failback=org.apache.dubbo.rpc.cluster.support.FailbackCluster

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

Разветвляющийся кластер:

forking=org.apache.dubbo.rpc.cluster.support.ForkingCluster

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

Кластер вещания:

broadcast=org.apache.dubbo.rpc.cluster.support.BroadcastCluster

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

Итак, вы можете ответить на этот вопрос:Какие из 10 классов реализации являются реализациями кластерного отказоустойчивого метода?

Далее поговорим об остальных четырех классах реализации:

Доступный кластер:

available=org.apache.dubbo.rpc.cluster.support.AvailableCluster

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

Объединяемый кластер:

mergeable=org.apache.dubbo.rpc.cluster.support.MergeableCluster

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

Макетный кластер:

mock=org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper

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

Кластер с поддержкой зоны:

zone-aware=org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster

Соответствующие описания вышеуказанных кластерных стратегий можно найти на официальном веб-сайте, но эта зонально-ориентированная в настоящее время не представлена ​​на официальном веб-сайте, поскольку она поддерживается только версией 2.7.5, выпущенной некоторое время назад, как показано на следующий рисунок:

Итак, позвольте мне сказать несколько слов о стратегии с учетом зон.. Подробности см. в следующей проблеме:https://github.com/apache/dubbo/issues/5399

Сценарии применения Zone-Aware следующие.

Предполагается, что бизнес-развертывание представляет собой двойной реестр:

Для стороны потребителя сначала выберите один из центров регистрации, а затем выберите адрес выбранного центра регистрации:

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

Реализация балансировки нагрузки между кластерами реестра: Zone-aware Cluster.

Для стратегии выбора места между несколькими регистрационными центрами, согласно аннотации к классу, видно, что в настоящее время разработаны следующие четыре:

1. Укажите приоритет:

Адрес из предпочтительного = "истинного" регистрационного центра будет выбран первым, и только когда у центра нет свободного адреса, он переключится на другие регистрационные центры.

<dubbo:registry address="zookeeper://${zookeeper.address1}" preferred="true" />

2. Та же зона имеет приоритет:

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

<dubbo:registry address="zookeeper://${zookeeper.address1}" zone="beijing" />

3. Весовой опрос:

Адреса из пекинского и шанхайского кластеров будут распределять трафик в соотношении 10:1.

<dubbo:registry id="beijing" address="zookeeper://${zookeeper.address1}" weight="100" />

<dubbo:registry id="shanghai" address="zookeeper://${zookeeper.address2}" weight="10" />

4. Метод по умолчанию:

Просто выберите первый доступный.

Каков метод кластеризации по умолчанию?

Никаких секретов под исходным кодом. Ищем ответ из исходного кода:

Сначала мы видим, что Cluster — это интерфейс SPI. Его реализация по умолчанию — FailoverCluster.NAME, как показано в следующем исходном коде:

Таким образом, метод реализации по умолчанию:

org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker

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

Анализ исходного кода FailoverCluster doInvoke

Далее мы проанализируем исходный код метода doInvoke FailoverClusterInvoker.

Этот подраздел в основном отвечает на этот вопрос:Сколько раз Invoker будет автоматически переключаться на повторную попытку после сбоя вызова отказоустойчивого кластера?

Через исходный код мы можем узнатьКоличество попыток по умолчанию равно 2..

Кто-то спросил: почему в конце строки 61 стоит «+1»?

Ты думаешь об этом. Мы хотим повторить попытку n раз после сбоя вызова интерфейса, это n равно DEFAULT_RETRIES, значение по умолчанию равно 2. Тогда наше общее количество вызовов равно n+1 раз. Итак, этот «+1» выглядит вот так, крошечная точка.

Кроме того, место отмечено красной пятиконечной звездой ★, строки с 62 по 64. Тоже очень важное место. Для параметра retries описание на официальном сайте выглядит следующим образом:

Не нужно повторять попытку, установите значение 0.. Как мы анализировали ранее, когда для него установлено значение 0, он будет вызываться только один раз.

Но я также видел повторные попытки, настроенные как «-1». -1+1=0. Вызов 0 раз, очевидно, является неправильным значением. Но программа тоже работает нормально и вызывается только один раз.

Здесь отмечена красная пентаграмма ★.Защитное программирование. Даже если вы установите для него значение -10086, он будет вызван только один раз.

Далее я дам исчерпывающую интерпретацию метода doInvoke.Ниже приведен исходный код версии 2.7.5.Я в основном добавляю комментарии к каждой строке основного кода.Вы можете нажать на увеличенное изображение для просмотра:org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker#doInvoke

Как показано выше, основной рабочий процесс метода doInvoke FailoverClusterInvoker:

Во-первых, получить количество повторных попыток, а затем сделать вызов цикла в соответствии с количеством повторных попыток.В теле цикла, если это не удается, выполняется повторная попытка.

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

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

Весь процесс примерно такой, и понять его несложно.

Что такое липкая связь Даббо?

Далее мы рассмотримМетод select родительского класса AbstractClusterInvokerлогика. Но прежде чем рассматривать логику метода select, я должен заложить основу для знания функции липкого соединения Dubbo.

Объяснение на официальном сайте следующее:

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

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

Официальная документация говорит об этом очень четко. Я лишь кратко объясню первое предложение:Липкие соединения используются для служб с отслеживанием состояния.

Итак, что такое служба с отслеживанием состояния и служба без сохранения состояния?

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

Например, сеанс, который мы часто используем.

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

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

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

Решение по замене службы с отслеживанием состояния на службу без сохранения состояния также простое. Возьмем сессию в качестве примера.На данный момент наша распределенная сессия готова к выходу. Сохраните сеанс централизованно, например, в Redis, и получите уровень совместного использования сеансов, независимый от службы. Таким образом, служба с отслеживанием состояния может стать службой без сохранения состояния.

AbstractClusterInvoker выберите анализ исходного кода

Прочитав этот раздел,Вы также знаете, как в Cluster используются липкие соединения.

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

Фрагмент кода не длинный, логика относительно ясна, конкретный анализ кода выглядит следующим образом:

Согласно коду блок-схема метода select рисуется следующим образом:

Объедините код и блок-схему, а затем сделайте текстовое описание.

Давайте сначала представим четыре входных параметра select, а именно:

кредитный баланс: стратегия балансировки нагрузки.

вызов: он содержит переменные в процессе вызова, такие как имена методов, параметры и т. д.

вызывающие: список вызывающих здесь можно рассматривать как список выживших поставщиков услуг.

selected: коллекция вызывающих элементов, которые были выбраны.

Из исходного кода мы видим, чтоОсновная логика метода select сосредоточена на поддержке функции прилипающего соединения.

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

Почему его можно оставить пустым?

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

Далее, если в списке вызывающих есть stickyInvoker, значит, stickyInvoker еще жив, и требуется следующая проверка. Проверьте, содержит ли selected (список выбранных поставщиков услуг) stickyInvoker.

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

Если selected не содержит stickyInvoker, он также необходим в данный момент.Делайте проверки юзабилити, например обнаружение сетевого подключения поставщика услуг. Когда проверка доступности пройдена, stickyInvoker может быть возвращен.В противном случае вызовите метод doSelect, чтобы выбрать Invoker.

Если sticky имеет значение true, Invoker, выбранный методом doSelect, будет назначен stickyInvoker.

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

То есть липкие соединения закрыты по умолчанию. Проверки доступности выполняются по умолчанию, когда включены липкие соединения.

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

Анализ исходного кода AbstractClusterInvoker doSelect

Прочитав этот раздел, вы сможете ответить на эти два вопроса:

1. Сколько раз Кластер максимально выбирает доступного Invoker?

2. Какие есть варианты на несколько раз?

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

Отказоустойчивый кластер выбирает доступный Invoker для максимальной производительности.три варианта, что также является основной логикой doSelect.Три раза (места, отмеченные на рисунке ①②③):

①: Выберите Invoker через компонент балансировки нагрузки.

②: Если выбранный Invoker нестабилен или недоступен, вам необходимо вызвать метод повторного выбора для повторного выбора.

③: Invoker, выбранный повторным выбором, пуст.В это время найдите индекс позиции вызывающего в списке вызывающих, а затем получите вызывающего с индексом +1.

AbstractClusterInvoker повторный выбор анализа исходного кода

Давайте посмотрим на логику метода reselect.

Согласно исходному коду, блок-схема выглядит следующим образом:

Таким образом, метод reselect на самом деле делает четыре вещи:

Во-первых: найдите доступных вызывающих и добавьте их в коллекцию reselectInvokers. Вы можете понимать эту коллекцию reselectInvokers как то, что вы в нее помещаете.Разница между набором всех доступных вызывающих элементов и выбранным набором.

Второй: Если reselectInvokers не пуст после фильтрации, выберите его снова через компонент балансировки нагрузки и вернитесь.

Третье: Если reselectInvokers пуст после фильтрации, то выбираем всех доступных инвокеров из выбранного набора (того набора, который был вызван), помещаем их в reselectInvokers, выбираем и снова возвращаемся через компонент балансировки нагрузки.

Четвертое: если после вышеуказанных шагов не выбран подходящий вызывающий объект, reselectInvokers по-прежнему остается пустым, что указывает на то, что все вызывающие элементы недоступны, а возвращаемое значение равно null.

Ну вот мы и ответили на все 8 вопросов брошенных в начале, а потом подытожим вопросы и ответы.

Резюме вопросов и ответов

1. Какова роль кластера Dubbo?

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

2. Можете ли вы назвать несколько из 10 классов реализации Dubbo Cluster и какие из них являются отказоустойчивыми методами кластера?

В соответствии с конфигурацией можно узнать, что интерфейс кластера Dubbo Cluster имеет 10 следующих методов реализации:

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

3. Каков класс реализации кластера по умолчанию?

Не удалось автоматически переключиться:org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker

4. Сколько раз после сбоя вызова отказоустойчивого кластера Invoker будет автоматически переключаться на повторную попытку?

Автоматически выполняются 2 попытки, всего 3 вызова.

5. Что такое липкое соединение Даббо?

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

6. Как используется липкое соединение в кластере?

См. анализ исходного кода для выбора AbstractClusterInvoker. Основная логика метода select сосредоточена на поддержке функции прилипающего соединения.

7. Сколько раз Кластер выбирает доступного Инвокера?

Сделайте до трех вариантов.

8. Какие есть варианты несколько раз?

①: Выберите Invoker через компонент балансировки нагрузки. ②: Если выбранный Invoker нестабилен или недоступен, вам необходимо вызвать метод повторного выбора для повторного выбора. ③: Invoker, выбранный повторным выбором, пуст.В это время найдите индекс позиции вызывающего в списке вызывающих, а затем получите вызывающего с индексом +1.

Последнее слово (пожалуйста, обратите внимание)

Я уже писал несколько статей, связанных с Dubbo, если вам интересно, вы можете взглянуть:

«Оптимизация Dubbo 2.7.5 на модели потоков»

«Отказоустойчивый механизм и отказоустойчивый механизм»

"Достаточно сильный! Одна строка кода исправляет ошибку Dubbo, о которой я упоминал. 》

«Исходный код балансировки нагрузки взвешенного опроса Dubbo и ошибка, понятно?»

"Dubbo Consistent Hash Load Balancing Исходный код и ошибки, знаете? 》

«Одна статья объясняет алгоритм минимального активного количества балансировки нагрузки Dubbo»

«Небольшое размышление после участия в Dubbo Community Developer Day Chengdu Station. 》

«Асинхронное преобразование новых функций Dubbo 2.7»

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

Спасибо за чтение, оригинальность не так проста, пожалуйста, обратите внимание.

над.

Добро пожаловать в публичный аккаунт [почему технология] и настаивайте на выводе оригинальности. Пусть мы с тобой прогрессируем вместе.