Анализ исходного кода Dubbo — охват конфигурации dubbo

искусственный интеллект Apache Debug Dubbo
Анализ исходного кода Dubbo — охват конфигурации dubbo

предисловие

Кто-то спрашивал в сообществе раньше, почемуproviderконечное применениеnetty4в видеtransportсвойства, ноconsumerТерминал не запустился, не тоproviderконфигурация перезаписываетсяconsumerконец?

Это требование на самом деле очень нормальное.Если мы хотим обновить кластер dubbo для использованияnetty4В качестве метода передачи, если вы можете настроить наложение, просто изменитеproviderВот так, удобнее. Но на самом деле прозрачная передача не будет настроена.

Конфигурации, которые можно передавать прозрачно, перечислены в руководстве пользователя dubbo, например:timeoutиretriesПодождите, причина прозрачной передачи также указана в документе: возьмем в качестве примера тайм-аут, сторона провайдера знает время выполнения лучше, чем сторона потребителя. В основном, некоторые параметры используются на уровне метода. должны знать о том,protocolЭто также будет прозрачным.consumerТерминал может принимать только пассивно, в отличие от других элементов конфигурации,protocolбудет охватыватьconsumerконечная конфигурацияprotocolиз.

Debug

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

Прежде чем смотреть на код + отладку, сначала проясните концепцию, хотя даббо рекомендуетproviderнастроить тайм-аут, ноproviderЕсли оба иconsumerнастроитьtimeout, то будет использоватьconsumerНастроил, вот вычитаю картинку из документа для поясненияtimeoutПриоритет конфигурации:

В документации четко указано, что еслиconsumerконец настроенtimeout, то он будет использоватьconsumerнастроен на терминале, если нет, перейдите кproviderконец найти.

Давайте сначала проверим это и посмотрим на внутренний приоритет,ConsumerКонфигурация:

Здесь я обвел триtimeoutКонфигурация.

Если следовать порядку на схеме, следует использовать элемент конфигурации 1500. Давайте посмотрим на фактический эффект, здесь я использую протокол dubbo, вызов rpc будет отправлен наDubboInvoker#doInvoke, то есть здесь задается таймаут.

Давайте посмотрим на эффект отладки:

Действительно, как мы видели раньше,timeoutза1500.

видишь ли, еслиProviderиConsumerсосуществоватьtimeoutобстоятельства ситуации.

C (далее CConsumer, Р означаетProvider)Конфигурация:

<dubbo:reference timeout="2000" id="demoService" check="false" interface="org.apache.dubbo.demo.DemoService"/>

Конфигурация П:

<dubbo:service timeout="2500" interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>

Эффект:

Это действительно конфигурация C, которая имеет приоритет над конфигурацией P.

Давайте посмотрим, настроен ли Cprotocolзаrmiпротокол, в то время как P настроенprotocolзаdubboЧто случается:

Точка останова все еще сработалаDubboInvokerвнутри. Это показывает, что наш протокол RMI не вступил в силу, и C может только принудительно принять конфигурацию P.protocol.

Код

ПосмотримDubboКак добиться охвата конфигурации. На самом деле, я сказал это в своей предыдущей статье,Inovkerфактически поддерживается вDirectoryв структуре.DubboInvokerНапример,timeoutвынесено в код:int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);,Constants.DEFAULT_TIMEOUTравно 1000, то есть если нигде ничего не настроеноtimeout, составляет 1 с.

getUrlпросто верни этоDubboInvokerсоответствующий URL-адрес. этоUrlКогда он был установлен?Мы уже догадались,и он прозрачно передается через zk. Здесь мы можем примерно определить, т.ConsumerСоздается при запускеInvoker, URL-адрес (время ожидания) установлен. посмотриDirectory#refreshInvokerметод, который основан наProviderизUrlгенерироватьInvokerиз. Среди них есть эта фраза:Map<String, Invoker<T>> newUrlInvokerMap = toInvokers(invokerUrls);

Продолжайте преследовать:

// sth...
for (URL providerUrl : urls) {

// sth...
// 合并url
URL url = mergeUrl(providerUrl);

// sth...

if (invoker == null) {
try {
boolean enabled = true;
// 这里根据上面的那个合并之后的url创建invoker
if (enabled) {
invoker = new InvokerDelegate<T>(protocol.refer(serviceType, url), url, providerUrl);
}
} catch (Throwable t) {
//sth ...
}
}
}
// sth...
return newUrlInvokerMap;

Здесь мы можем увидеть это первымmergeUrlМетод, глядя на название, вероятно, знает, что локальный url и удаленный url объединены, что и должно быть выполнено здесь.timeoutкрышка, потому чтоconsumerиproviderв конфигурации с двумяtimeout.

Затем он генерируется в соответствии с синтезированным URL-адресом.Invoker, здесь будетmergeПосле размещения URLInvokerВ будущем, когда вызов rpc действительно будет выполнен,timeoutиз этогоurlполучен из.

посмотриmergeUrlметод, первая строкаmergeработать:

providerUrl = ClusterUtils.mergeUrl(providerUrl, queryMap);

здесьqueryMap,Да:this.queryMap = StringUtils.parseQueryString(url.getParameterAndDecoded(Constants.REFER_KEY));Полученный, который содержит некоторые локально заданные свойства, такие какtimeout, даю каштан, конфигурация С:<dubbo:reference timeout="2000" id="demoService" check="false" interface="org.apache.dubbo.demo.DemoService"/>когда,queryMapСодержание:

Мы видим, что на стороне C настроено время ожидания.

Тогда слияние фактически объединяет эти параметры на стороне P (такие какtimeout) и параметры стороны C объединяются для создания окончательного URL-адреса.

ПосмотримClusterUtils#mergeUrlметод:

Map<String, String> map = new HashMap<String, String>();
Map<String, String> remoteMap = remoteUrl.getParameters();

// map中先放remoteMap
if (remoteMap != null && remoteMap.size() > 0) {
map.putAll(remoteMap);
// do sth...
}

// sth...
if (localMap != null && localMap.size() > 0) {
map.putAll(localMap);
}
// sth...
return remoteUrl.clearParameters().addParameters(map);

mapбудущееUrlнекоторые параметры конфигурацииtimeoutпрямо внутри.remoteMapЭто параметр, настраиваемый на стороне P. localMap — это локально настраиваемый параметр, который настраивается на стороне C.

В коде поставить первымremoteMap, поставить послеlocalMap, та же самая клавиша закрыта, поэтому появится сторона Ctimeoutбудет покрывать сторону Ptimeoutявление ~ но еслиlocalMapнетtimeout, буду использоватьremoteMapизtimeoutи настроен с помощью Ptimeout.

постскриптум

Dubbo возобновил техническое обслуживание, и будет добавлено много новых функций.Я надеюсь, что все будут участвовать в построении сообщества dubbo, активно задавать вопросы на github и предлагать новые идеи~

# настроить Компиляция заметок OPENJDK