Фреймворк RPC Dubbo: от понимания к использованию (1)

Dubbo
Фреймворк RPC Dubbo: от понимания к использованию (1)

Эволюция технологической архитектуры

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

архитектура единого приложения

Это популярное приложение «Монолит» — это объединение всех функций приложения в независимый блок. Когда трафик веб-сайта невелик, одновременно развертывается только одно приложение, чтобы уменьшить количество узлов развертывания и затраты.

Функции

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

преимущество:

  • легко разработать: в одной среде IDE можно быстро создать одно приложение;

  • легко поделиться: единый архив содержит все функции для удобного обмена между командами и между разными этапами развертывания;

  • Легко проверить: после развертывания монолитного приложения становятся доступными все сервисы или функции, что упрощает процесс тестирования, так как отсутствуют дополнительные зависимости, и каждый тест может запускаться сразу после развертывания;

  • легко развернуть: Весь проект - военный пакет.После установки Tomcat приложение можно закинуть. Групповое развертывание также очень просто: несколько Tomcat + один Nginx можно выполнить за считанные минуты.

недостаток:

  • препятствовать непрерывной доставке: со временем монолитное приложение может стать больше, и время сборки и развертывания будет соответственно увеличено, что не способствует частому развертыванию и препятствует непрерывной доставке. При разработке мобильных приложений эта проблема будет особенно серьезной;
  • недостаточно гибкий: По мере того, как проект становится больше, время всего процесса разработки станет очень долгим, даже если будет изменена только одна строка кода, разработчику программного обеспечения необходимо потратить десятки минут или даже больше часа на все коды. , а затем потратить много времени на повторное развертывание только что созданной рабочей среды, чтобы убедиться, что ваши изменения верны. Если над разработкой приложения работают вместе несколько разработчиков, подождите, пока другие разработчики завершат свою разработку. Это снижает гибкость команды и частоту предоставления функций;
  • Ограничено стеком технологий: Пункт становится все больше, в то же время приложение технологии, которые мы используем, станут все больше и больше. Некоторые из этих технологий несовместимы, вроде на широкий ассортимент смешанного использования C ++ и Java в проекте практически невозможно. В этом случае нам нужно отказаться от использования определенных технологий, несовместимы, но не так выбирают подходящую технологию для достижения конкретных функций.
  • низкая надежность: в определенной ссылке происходит бесконечный цикл, что приводит к переполнению памяти, что приведет к зависанию всего проекта.
  • Плохая масштабируемость: Расширение системы может быть выполнено только для приложения, и не может быть расширено для определенной функции.После расширения это неизбежно приведет к проблеме растраты ресурсов.
  • технический долг: Допустим, у меня беспорядочная структура модуля в моей кодовой базе. На данный момент мне нужно добавить новую функцию. Если бы структура модуля была понятна, возможно, мне нужно было всего 2 дня, чтобы добавить эту функцию, но сейчас структура этого модуля очень беспорядочна, поэтому мне нужно 4 дня. Дополнительные два дня — это проценты по долгу. Со временем и кадровыми изменениями технический долг неизбежно будет увеличиваться.

Вертикальная архитектура приложений

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

Функции

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

преимущество

  • Низкая стоимость разработки и простая архитектура;

  • Избегайте бесконечного расширения монолитных приложений;

  • Разделение системы реализует разделение трафика и решает проблему параллелизма;

  • Его можно расширять и оптимизировать для разных систем;

  • Упрощение горизонтального расширения, балансировки нагрузки и повышения отказоустойчивости;

  • В разных проектах могут использоваться разные технологии;

  • Системы независимы друг от друга.

недостаток

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

Сервис-ориентированная архитектура SOA

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

P.S. С точки зрения дизайна программного обеспечения ESB представляет собой абстрактный уровень косвенности, который извлекает некоторые общие моменты динамического взаимодействия между вызывающим и вызываемым в процессе вызова службы, уменьшая нагрузку на вызывающую службу. Это упоминается в мысли программирования на Java: «Все проблемы разработки программного обеспечения могут быть решены или упрощены путем добавления слоя абстрактной косвенности!» Короче говоря, ESB — это канал, используемый для соединения различных сервисных узлов. Чтобы интегрировать службы разных систем и разных протоколов, ESB выполняет преобразование, интерпретацию и маршрутизацию сообщений, чтобы можно было соединить разные службы.

Функции

  • Архитектурная идея, основанная на SOA, выделяет повторяющиеся и общие функции в компоненты и предоставляет услуги каждой системе в виде сервисов.
  • Связь между проектами (системами) и сервисами осуществляется посредством WebService, RPC и т.п.
  • Используйте корпоративную служебную шину ESB в качестве моста для связи между проектами и службами.

преимущество

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

недостаток

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

Микросервисная архитектура

Функции

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

преимущество

  • Независимая команда: каждый сервис является независимой командой разработчиков, эта небольшая команда может состоять из 2-5 разработчиков;
  • Технологическая независимость: принятие идеи децентрализации, использование RESTful и других облегченных протоколов для связи между сервисами, использование какой технологии и языка для разработки, другим не нужно вмешиваться;
  • Разделение интерфейсной и серверной частей: интерфейсная и серверная части разделены и разработаны для обеспечения унифицированного интерфейса Rest, а серверной части больше не нужно разрабатывать разные интерфейсы для ПК и мобильных терминалов;
  • Разделение базы данных: каждая микрослужба имеет собственные возможности хранения и может иметь собственную базу данных. Также может быть объединенная база данных;
  • Детализация разделения услуг более тонкая, что способствует повторному использованию ресурсов и повышает эффективность разработки;
  • Новые члены команды могут быстрее приступить к работе;
  • Микросервисы легко понять, модифицировать и обслуживать один разработчик, поэтому небольшие группы могут больше сосредоточиться на своей работе. Ценность может быть реализована без сотрудничества;
  • Схему оптимизации (например, расширение) каждой службы можно сформулировать более точно, чтобы улучшить ремонтопригодность системы;
  • Применительно к эпохе Интернета цикл итерации продукта короче.

недостаток

  • Чрезмерные микросервисы, высокая стоимость услуг управления не способствует обслуживанию системы;
  • Техническая стоимость разработки распределенной системы высока (проблемы сети, проблемы отказоустойчивости, взаимосвязь вызовов, распределенные транзакции и т. д.), что ставит большие задачи перед командой;
  • Микросервисы изменяют исходные функциональные вызовы на служебные вызовы, независимо от того, используют ли они RPC или HTTP rest, что увеличивает общую задержку системы. Это неизбежно и требует от нас замены исходного последовательного программирования параллельным или даже асинхронным программированием, что увеличивает технический порог;
  • Сложность мультисервисной эксплуатации и обслуживания, с увеличением количества услуг, также увеличивается нагрузка на эксплуатацию и техническое обслуживание;
  • Сложность теста увеличилась. Взаимодействие между сервисами и сервисами происходит через интерфейсы.При изменении интерфейса это повлияет на всех звонящих.В это время очень актуально автоматизированное тестирование.Если нужно вручную протестировать каждый интерфейс, то работы Объем слишком велик, поэтому управление документами API особенно важно.

Суммировать

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

История 1:

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

Мартин рад начать продвигать SOA как внутри компании, так и за ее пределами. В результате люди продолжали задавать вопросы и бросать ему вызов.

Вы не SOA, не так ли? SOA должен быть таким здесь. Да, вот мое понимание SOA. Видите ли, в этой книге SOA говорится совсем не то, что вы говорите. гранулярность? SOA не говорит об этом, вы не SOA. Многоуровневость не имеет ничего общего с SOA, почему вы так говорите? …

Мартин Ни в коем случае, Синьи Хен, называйте это SOA Мартина. Я изобретение слова, это высший авторитет, имеет окончательное толкование. Кто отказывается принимать?

Коллеги увидели, что он сам по себе очень хорош, достоин продвижения, но не слишком называется SOA-продуктом Мартина, верно? Или получить немного лучшее имя, но также иметь лучшую SOA с намеком на наследие. Просто микросервисы называются ну и новые, но и содержащиеся в них сервисы.

Мартин сердито принял это предложение, подумав про себя: Блин, это SOA, и куча ** настаивала на том, чтобы заставить меня выбрать новое имя.

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

Это история микросервисов, Agile, Lean Enterprise, Continuous Integration, Continuous Delivery.

После создания существительного право на интерпретацию имени со временем будет ослабевать (например, Persona, изобретенная Купером, была неправильно использована бесчисленным множеством дизайнеров). Agile уже немного прогнил, а когда микросервисы протухнут, мы будем изобретать новые слова.

Ни в коем случае, они все вынуждены.

История вторая:

Говорят, что в 1979 году была еще одна весна.У Даниу, босоногий врач из сельской местности Путяня, был так взволнован весенним ветром реформ, что сделал то, что сказал. круг.

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

После десяти лет напряженной работы пришло время 1989 года, и это еще одна весна.Бывший холостяк У ​​Даниу стал известной фигурой в Шили Басян.Не говоря уже о том, что его невестка вышла замуж, он также добавил в семью пару сыновей-близнецов.Небольшие бунгало на первом этаже тоже очень стильные. Но есть и неприятности.Хотя сельская поликлиника разрослась до двух, и невестка может изредка выручать, но врач все равно один. У Данью думал об этом день и ночь, и действительно придумал для него хитрость, как это сделать, расширить масштаб и набрать еще несколько врачей для совместной работы. Если раньше У Данью лечил только головные боли, лихорадку мозга и синяки, то теперь для лечения простуды и лихорадки наняли нового выпускника медицинского университета Лю Сяомина, а старого врача Ли Ахуа пригласили из соседнее село для лечения гинекологических заболеваний.Сейчас обычная небольшая клиника превратилась в небольшую больницу с тремя самостоятельными отделениями и общественной аптекой (заведует ею жена Ву Данью). Когда люди пребывают в хорошем настроении по радостным событиям, декан Дэниел пригласил известных каллиграфов округа написать табличку для новой больницы - «Больница Бо Ай» и выбрал благоприятный день, чтобы официально ее повесить.

Десять лет спустя наступила другая весна. Больница Боай в У Даниу превратилась в шесть отделений внутренней медицины, хирургии, гинекологии, ЛОР, ортопедии, репродуктивного отделения, и в каждом отделении работает от 3 до 5 врачей. купить анализы крови В-УЗИ и другое передовое оборудование, декан Даниэль давно ушел с медицинской передовой и стал штатным менеджером, но все в больнице ищут его по крупным и мелким делам, и он выматывается каждый день. день с этими тридцатью сотрудниками.Расширение масштаба действительно бессильно. Чтобы сказать, что студенты колледжа все еще на уровне, старый подчиненный Лю Сяомин предложил декану Дэниелу план разделить каждый отдел и позволить директору каждого отдела управлять им самому.Декан Даниэль заботится только о координации между отделами и развитии Таким образом, разве не было бы чудесно не только мобилизовать энтузиазм широких масс, но и дать возможность Дэниэлу Дину расширить производство и сосредоточиться на больших делах? Таким образом, новый раунд реформы больницы Пок Ой был запущен энергично.

Еще одно десятилетие и еще одна весна, Дин Даниэль стал известным местным предпринимателем, а больница Пок Ой разрослась до сотен сотрудников в 23 отделениях, и в процессе развития возникли новые проблемы.Из-за независимости каждого отделения. выставление счетов и тестирование, одни отделения заняты целыми днями с хорошими льготами, а другие относительно посредственно.Даже различные назначенные контрольно-измерительные приборы не могут работать на полную мощность, и вся больница содержит множество бездельников. В это время видение декана Даниэля также расширилось, и для проведения проектирования на высшем уровне были приглашены специалисты по управлению.Все непрофильные службы, которые изначально были разбросаны по разным отделам, были централизованы и управляемы, а первоначальные 23 окна регистрации были интегрированы в 10. Двадцать три зарядных окна объединены в восемь, и они централизованно расположены в вестибюле на первом этаже, чтобы обслуживать всю больницу.Инструменты контроля, разбросанные по различным отделам, также централизованы для создания независимого отдела контроля, который также обслуживает вся больница, чтобы каждый мог жить.Ну, возможности обслуживания всей больницы вышли на новый уровень.После этого раунда реформ больница Боай прошла оценку различных отделений и стала известной больницей третичного уровня. Ву Даниу также стал генеральным директором и председателем Boai Group.Следующий шаг Подготовка к IPO.

Здесь все могут немного запутаться, какое отношение это имеет к микросервисам? Стадия 1.0 Daniel Clinic эквивалентна монолитной структуре разработки программного обеспечения, программисту трудно стать больше и сильнее. Этап 2.0 Daniel Clinic эквивалентен вертикальной структуре разработки программного обеспечения: каждый отдел разделен по бизнесу, и его легко расширять по горизонтали. Стадия 1.0 больницы Боай эквивалентна SOA-структуре разработки программного обеспечения.За исключением аптеки (базы данных), каждая услуга предоставляется независимо (отвечает директор отделения), но она должна координироваться Даниэлем (шина ESB) . Стадия 2.0 больницы Боай эквивалентна микросервисной структуре разработки программного обеспечения.Государственная служба разделена внутри больницы, а управленческая функция директора отделения ослаблена (только для дела врача).Преимуществом является что удобно расширять мощности.Высокая скорость, высокая эффективность персонала и оборудования.

Микросервис состоит в том, чтобы разделить приложение монолитной архитектуры на независимые работающие программы в качестве сервисов в соответствии с бизнесом и обмениваться данными между ними через протокол HTTP (для связи также можно использовать очереди сообщений, такие как RabbitMQ, Kafka и т. д.), вы можно использовать. Разные языки программирования используют разные технологии хранения, а автоматизированное развертывание (например, Jenkins) снижает человеческий контроль и снижает вероятность ошибок. Чем больше количество сервисов, тем сложнее ими управлять, поэтому применяется централизованное управление. Например, Eureka, Zookeeper и т. д. являются относительно распространенными платформами централизованного управления службами.

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

Резюме одним предложением: микросервисы — это продукт разработки SOA, и это относительно современная, мелкозернистая реализация SOA.

способ общения

С развитием Интернета приложения перешли от автономных к распределенным, и способы связи также претерпели множество изменений.

TCP/UDP

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

Резюме одним предложением: самый старый и самый эффективный, никогда не устаревающий и дорогой в изучении. Все методы связи сводятся к TCP/UDP.

WebService

Технология WebService (SOA, SOAP, WSDL, UDDI, XML) позволяет различным приложениям, работающим на разных машинах, обмениваться данными или интегрироваться друг с другом без необходимости в дополнительном специализированном программном или аппаратном обеспечении сторонних производителей. Приложения, реализованные в соответствии со спецификацией WebService, могут обмениваться данными друг с другом независимо от используемого ими языка, платформы или внутреннего протокола.

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

Одним предложением: стандартизированный веб-API на основе HTTP + XML.

RESTful

Representational State Transfer, передача состояния уровня представления. Протокол связи через Интернет Протокол HTTP является протоколом без сохранения состояния. Это означает, что все состояние сохраняется на стороне сервера. Следовательно, если клиент хочет управлять сервером, он должен использовать некоторые средства для осуществления «передачи состояния» на стороне сервера. И это преобразование основано на уровне представления, так что это «передача состояния уровня представления».

Средством, используемым клиентом, может быть только протокол HTTP. В частности, в протоколе HTTP есть четыре глагола, которые выражают режим работы: GET, POST, PUT, DELETE. Они соответствуют четырем основным операциям: GET используется для получения ресурсов, POST используется для создания новых ресурсов (а также может использоваться для обновления ресурсов), PUT используется для обновления ресурсов и DELETE используется для удаления ресурсов.

  • Протокол HTTP без сохранения состояния имеет присущие ему преимущества, масштабируемость очень сильна. Например, требуется безопасность, у существующих зрелых программ доступен HTTPS.
  • Сериализация сообщений JSON, легкая и простая, читаемая как людьми, так и машинами, низкая стоимость обучения и дружественная поисковая система.
  • Независимо от языка, все популярные языки предоставляют зрелые фреймворки Restful API.

Резюме одним предложением: стандартизированный веб-API на основе HTTP + JSON.

RMI

Удаленный вызов метода, удаленный вызов метода. Протокол распределенной связи, реализованный на Java, который значительно расширяет возможности Java для разработки распределенных приложений. С помощью технологии RMI локальная JVM может вызывать объектный метод, существующий в другой JVM, как если бы она вызывала только метод объекта в локальной JVM.

Одно предложение предложений: распределенный протокол связи на основе языка Java.

JMS

Служба сообщений Java, прикладной программный интерфейс службы сообщений Java, представляет собой API для ориентированного на сообщения промежуточного программного обеспечения на платформе Java, которое используется для отправки сообщений между двумя приложениями или распределенными системами для асинхронной связи. Большинство MQ поддерживают JMS, например RabbitMQ, ActiveMQ, Kafka, RocketMQ и Redis.

Резюме в одном предложении: Стандарт платформы сообщений JavaEE.

RPC

Remont Proceduce Call, удаленный вызов процедуры. Это идея запроса услуг от удаленной компьютерной программы по сети без знания базовой сетевой технологии. RPC — это просто концепция, это не протокол и не фреймворк.

Конкретная реализация RPC может использовать RMI или RESTful и т. д., но обычно не используется, потому что RMI не может работать с разными языками, а RESTful слишком неэффективен.

RPC в основном используется для внутренней связи кластеров серверов, поэтому для повышения эффективности часто используется более эффективный и компактный режим передачи. Существует множество RPC-фреймворков: Apache Thrift, Apache Dubbo, Google Grpc и т. д.

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

Зачем вам РПК?

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

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

Принцип реализации RPC

Полный процесс вызова RPC включает в себя четыре основные части:Client,Server,Client Stubтак же какServer StubЭта заглушка может понять, что она заглушка. Расскажите эти части отдельно:

Клиент (клиент): вызывающий абонент службы.

Сервер (Сервер): поставщик услуги.

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

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

  1. Клиент (Client) вызывает службу в режиме локального вызова (то есть в режиме интерфейса);
  2. После того, как клиентская заглушка получает вызов, она отвечает за сборку методов, параметров и т. д. в тело сообщения, которое может быть передано по сети (сериализация объекта тела сообщения в двоичный файл);
  3. Клиент отправляет сообщение на сервер через Socket;
  4. Серверная заглушка декодирует (десериализует объект сообщения) после получения сообщения;
  5. Заглушка сервера вызывает локальную службу в соответствии с результатом декодирования;
  6. Локальная служба выполняет обработку бизнес-логики;
  7. Локальный сервис возвращает результат обработки бизнес-логики серверу-заглушке;
  8. Заглушка сервера упаковывает возвращенный результат в сообщение (сериализует объект сообщения результата);
  9. Сервер (Server) отправляет сообщение клиенту через Socket;
  10. Клиентская заглушка получает сообщение результата и декодирует его (десериализует сообщение результата);
  11. Клиент (Клиент) получает окончательный результат.

Цель RPC — инкапсулировать шаги 2, 3, 4, 5, 7, 8, 9 и 10.

установить связь

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

сервисная адресация

Как приложение на сервере A сообщает базовой структуре RPC, как подключиться к серверу B (например, к хосту или IP-адресу) и конкретному порту, а также как называется метод, чтобы вызов мог быть завершен. . Например, для RPC, основанного на стеке протоколов веб-сервиса, необходимо указать URI конечной точки или найти его в сервисах UDDI (служба каталогов, через которую осуществляется регистрация и поиск сервисов). Если это вызов RMI, реестр RMI также требуется для регистрации адреса услуги.

передача по сети

Сериализация

Когда приложение на сервере A инициирует удаленный вызов процедуры, параметры метода необходимо передать на сервер B через базовый сетевой протокол, такой как TCP.Поскольку сетевой протокол основан на двоичном коде, значения параметры в памяти должны быть сериализованы в двоичную форму, то есть Serialize или marshal, отправить сериализованный двоичный файл на сервер B посредством адресации и передачи.

десериализовать

После того, как сервер B получит запрос, ему необходимо десериализовать параметры (операция, обратная сериализации), восстановить их до выражения в памяти, а затем найти соответствующий метод (часть адресации) для выполнения локального вызова (обычно путем создание прокси-сервера для вызова, обычно это динамический прокси-сервер JDK, динамический прокси-сервер CGLIB, технология генерации байт-кода Javassist и т. д.), а затем получить возвращаемое значение вызова.

служебный вызов

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

Простая реализация RPC на основе RMI

Создание сводного проекта Maven

Родительский проект rmi-demo

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>rmi-demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>rmi-api</module>
        <module>rmi-server</module>
        <module>rmi-client</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

</project>

Подпроект rmi-api

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

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi-api</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
    </dependencies>

</project>

класс сущности

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

package org.example.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private static final long serialVersionUID = 2159427410483687648L;
    private Integer id;
    private String username;

}

сервисный интерфейс

Сервисный интерфейс, предоставляемый с помощью JavaRMI, должен наследоватьjava.rmi.Remote.Remoteкласс, метод должен броситьjava.rmi.RemoteExceptionаномальный.

package org.example.service;

import org.example.pojo.User;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * 用户管理服务
 */
public interface UserService extends Remote {

    User selectUserById(Integer userId) throws RemoteException;

}

Подпроект rmi-сервер

В основном он обеспечивает реализацию сервисного интерфейса и сервисную конфигурацию RMI.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi-server</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>rmi-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

реализация услуги

Реализации интерфейса службы должны наследоватьjava.rmi.server.UnicastRemoteObjectДобрый.

package org.example.service.impl;

import org.example.pojo.User;
import org.example.service.UserService;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
 * 用户管理服务
 */
public class UserServiceImpl extends UnicastRemoteObject implements UserService {

    public UserServiceImpl() throws RemoteException {
    }

    @Override
    public User selectUserById(Integer userId) throws RemoteException {
        System.out.println("用户管理服务接收到客户端请求,请求参数 userId = " + userId);
        // 模拟假数据返回
        return new User(userId, "张三");
    }

}

служба публикации

Опубликовать сервис на указанном IP+порту.

package org.example;

import org.example.service.UserService;
import org.example.service.impl.UserServiceImpl;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

/**
 * 发布服务
 */
public class Publish {

    public static void main(String[] args) throws RemoteException {
        UserService userService = new UserServiceImpl();
        try {
            // 对外暴露的服务端口
            LocateRegistry.createRegistry(8888);
            // 对外暴露的服务地址
            Naming.bind("rmi://localhost:8888/userService", userService);
            System.out.println("服务发布成功!");
        } catch (AlreadyBoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

}

Подпроект rmi-клиент

Как локальный клиент реализует вызов удаленного интерфейса.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi-client</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>rmi-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

удаленный сервисный вызов

Выполните удаленный сервисный вызов через указанный IP + порт.

package org.example.controller;

import org.example.pojo.User;
import org.example.service.UserService;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class UserController {

    public static void main(String[] args) {
        try {
            UserService userService = (UserService) Naming.lookup("rmi://localhost:8888/userService");
            User user = userService.selectUserById(1);
            System.out.println("远程服务调用成功,返回值信息为:" + user);
        } catch (NotBoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

}

тестовое задание

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

Фреймворк RPC

Типичный сценарий использования инфраструктуры RPC включает в себя такие компоненты, как регистрация и обнаружение службы (центр реестра), балансировка нагрузки, отказоустойчивость, передача по сети и сериализация, среди которых «протоколы, связанные с RPC», определяют, как программы выполняют передачу по сети и сериализацию. Существует множество RPC-фреймворков: Apache Thrift, Apache Dubbo, Google Grpc и т. д. На следующем рисунке показана полная схема архитектуры инфраструктуры RPC:

Представляем Даббо

Официальный сайт:dubbo.apache.org/zh-cn/

Гитхаб:GitHub.com/Apache/Belly Daddy…

15 февраля 2018 года структура управления услугами Alibaba dubbo прошла голосование и успешно стала инкубационным проектом Apache Foundation.

Apache Dubbo — это высокопроизводительная облегченная платформа Java RPC с открытым исходным кодом, которая обеспечивает три основные возможности:面向接口的远程方法调用,智能容错和负载均衡,так же как服务自动注册和发现.

Даббо Архитектура

Dubbo предоставляет три основные функции:面向接口的远程方法调用,智能容错和负载均衡,так же как服务自动注册和发现. Фреймворк Dubbo широко используется в Alibaba, а также в Dangdang, Qunar, Netease Koala, Didi и т. д.

Узел роль Описание

узел Описание роли
Provider Поставщик услуг, предоставляющий услугу
Consumer Потребитель службы, вызывающий удаленную службу
Registry Реестр для регистрации и обнаружения служб
Monitor Центр мониторинга, который подсчитывает сервисные вызовы и время вызова
Container Запустите контейнерные услуги

Описание отношения вызова

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

Начало работы с Дуббо

Далее мы интегрируем Dubbo на основе среды SpringBoot, чтобы завершить вводный кейс.

Создание сводного проекта Maven

Родительский проект dubbo-demo

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>dubbo-demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>dubbo-api</module>
        <module>dubbo-provider</module>
        <module>dubbo-consumer</module>
    </modules>

    <!-- 继承 spring-boot-starter-parent 依赖 -->
    <!-- 使用继承方式,实现复用,符合继承的都可以被使用 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.4.1</version>
        </dependency>
    </dependencies>

</project>

Подпроект dubbo-api

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

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-api</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

класс сущности

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

package org.example.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private static final long serialVersionUID = 2159427410483687648L;
    private Integer id;
    private String username;

}

сервисный интерфейс

package org.example.service;

import org.example.pojo.User;

/**
 * 用户管理服务
 */
public interface UserService {

    User selectUserById(Integer userId);

}

Подпроект даббо-провайдер

В основном он обеспечивает реализацию интерфейса службы и конфигурацию службы поставщика услуг.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-provider</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

конфигурационный файл

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

server:
  port: 7070 # 端口

# Dubbo 配置
dubbo:
  # 提供方应用信息,用于计算依赖关系
  application:
    name: product-service
  # 配置注册中心
  registry:
    address: multicast://224.5.6.7:1234 # 使用 Multicast 注册中心暴露服务地址
  # 用 dubbo 协议在 20880 端口暴露服务
  protocol:
    name: dubbo # 协议名称
    port: 20880 # 协议端口
  # 扫描需要暴露的服务
  scan:
    base-packages: org.example.service

Реализация услуги (поставщик услуг)

package org.example.service.impl;

import org.example.pojo.User;
import org.example.service.UserService;
import org.apache.dubbo.config.annotation.Service;

/**
 * 用户管理服务
 * 		timeout 调用该服务的超时时间
 * 		version 为版本号
 * 		group 为分组
 * 	    interface、group、version 三者可确定一个服务
 * 	    parameters = {"unicast", "false"}
 * 	        建议服务提供者和服务消费者在不同机器上运行,
 * 	        如果在同一机器上,需设置 unicast = false 禁用单播订阅,只有 multicast 注册中心有此问题。
 */
@Service(timeout = 5000, version = "1.0", group = "user-provider", parameters = {"unicast", "false"})
public class UserServiceImpl implements UserService {

    @Override
    public User selectUserById(Integer userId) {
        System.out.println("用户管理服务接收到客户端请求,请求参数 userId = " + userId);
        // 模拟假数据返回
        return new User(userId, "张三");
    }

}

Уведомление:parameters = {"unicast", "false"}: рекомендуется, чтобы поставщик услуг и потребитель услуг работали на разных машинах. Если они находятся на одной машине, установите unicast = false, чтобы отключить подписку на одноадресную рассылку. Эта проблема возникает только в реестре многоадресной рассылки.

стартовый класс

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 扫描需要暴露的服务,如果配置文件中已声明则无需添加该注解
// @EnableDubbo(scanBasePackages = "org.example.service")
@SpringBootApplication
public class DubboProviderApplication {

	public static void main(String[] args) {
		SpringApplication.run(DubboProviderApplication.class, args);
	}

}

Подпроект даббо-потребитель

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-demo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-consumer</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

конфигурационный файл

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

server:
  port: 9090 # 端口

# Dubbo 配置
dubbo:
  # 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样
  application:
    name: dubbo-consumer
  # 配置注册中心
  registry:
    address: multicast://224.5.6.7:1234 # 发现 Multicast 注册中心暴露的服务

удаленный сервисный вызов

package org.example.controller;

import org.apache.dubbo.config.annotation.Reference;
import org.example.pojo.User;
import org.example.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/consumer")
public class ConsumerController {

    // dubbo 提供了 @Reference 注解,可替换 @Autowired 注解,用于引入远程服务
    // 如果注册服务时设置了版本及分组信息,调用远程服务时也要设置对应的版本及分组信息
    @Reference(timeout = 5000, version = "1.0", group = "user-provider", parameters = {"unicast", "false"})
    private UserService userService;

    @GetMapping("/{id}")
    public User selectUserById(@PathVariable("id") Integer id) {
        return userService.selectUserById(id);
    }

}

стартовый класс

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DubboConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(DubboConsumerApplication.class, args);
    }

}

тестовое задание

Запустите поставщика услуг и потребителя услуг для доступа:http://localhost:9090/consumer/1Результат выглядит следующим образом:

Общие теги Даббо

  • dubbo:application: Имя приложения
  • dubbo:registry: Подключиться к информации реестра (настроить реестр)
  • dubbo:protocol: протокол, используемый поставщиком услуг для регистрации услуги.
    • Протокол Дуббо, по умолчанию
    • протокол RMI
    • Гессенский протокол
    • HTTP-протокол
    • Протокол веб-службы
    • Бережливый протокол
    • Протокол Memcached
    • Протокол Redis
    • Протокол отдыха (RESTful)
    • протокол Grpc
    • Для получения дополнительной информации о протоколе см.:Хироши Ватанабэ.apache.org/this-capable/docs/…
  • dubbo:service: объявить сервисный интерфейс, который необходимо открыть
  • dubbo:reference: Настройка подписных сервисов (создание прокси-серверов удаленных сервисов)

Для получения дополнительной информации о конфигурации см.:Хироши Ватанабэ.apache.org/this-capable/docs/…

В следующей статье мы объясним реестр, поддерживаемый Dubbo, стратегию балансировки нагрузки Dubbo и установку консоли Dubbo. Не забудьте обратить внимание~

Этот документ принимает知识共享「署名-非商业性使用-禁止演绎 4.0 国际」许可协议.

Каждый может пройти分类увидеть больше оDubboстатья.

🤗 твой点赞а также转发моя самая большая поддержка.

📢 Отсканируйте код, чтобы следовать哈喽沃德先生Каждая статья «Документ+Видео» снабжена специальным видео-пояснением, облегчающим обучение~