Rpc control что это

Обновлено: 16.05.2024

В продолжение пятого урока по изучению азов RabbitMQ, публикую перевод шестого урока с официального сайта. Все примеры написаны на python (используется pika версии 0.9.8), но по-прежнему их можно реализовать на большинстве популярных ЯП.

Во втором уроке мы рассмотрели использование очередей задач для распределения ресурсоёмких задач между несколькими подписчиками.

Но что если мы захотим запустить функцию на удаленной машине и дождаться результата? Ну, это совсем другая история. Этот шаблон широко известен как Удаленный Вызов Процедур (Remote Procedure Call или RPC, далее в тексте RPC).

В этом руководстве мы построим, используя RabbitMQ, RPC систему, которая будет включать клиент и масштабируемый RPC сервер. Так как у нас нет реальной трудоемкой задачи требующей распределения, мы создадим простой RPC сервер, возвращающий числа Фибоначчи.

Интерфейс клиента

Для иллюстрации использования RPC службы, создадим простой клиентский класс. Этот класс будет содержать метод call, который будет отправлять RPC запросы и блокироваться до получения ответа:

Замечание о RPC

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

  • Убедитесь, что это очевидно, какая функция вызывается в каждом конкретном случае: локальная или удаленная;
  • Документируйте вашу систему. Делайте зависимости между компонентами явными;
  • Обрабатывайте ошибки. Как должен реагировать клиент, если RPC сервер не отвечает в течение длительного промежутка времени?
  • Если сомневаетесь — не используйте RPC. Если это возможно, используйте асинхронный конвейер вместо блокирующего RPC, когда результаты асинхронно передаются на следующий уровень обработки.
Очередь результатов

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

Correlation id
Итоги

image

Наш RPC будет работать следующим образом:

Собирая всё вместе

Код сервера rpc_server.py:

Серверный код довольно прост:

  • (4) Как обычно, мы устанавливаем соединение и объявляем очередь;
  • (11) Объявляем нашу функцию, возвращающую числа Фибоначчи, которая принимает в качестве аргумента только целые положительные числа(эта функция вряд ли будет работать с большими числами, вероятнее всего это самая медленная из возможных реализаций);
  • (19) Мы объявляем функцию обратного вызова on_request для basic_consume, которая и является ядром RPC сервера. Она исполняется когда запрос получен. Выполнив работу, функция отправляет результат обратно;
  • (32) Вероятно, мы захотим когда-нибудь запустить более одного сервера. Для равномерного распределения нагрузки между несколькими серверами мы устанавливаем prefetch_count.

Код клиента rpc_client.py:

Код Клиента несколько сложнее:

Наш RPC сервис готов. Мы можем запустить сервер:


Для получения чисел Фибоначчи запускаем Клиент:


Представленный вариант реализации RPC не является единственным возможным, но он имеет следующие преимущества:

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

Требования к среде выполнения

Библиотеки времени выполнения RPC входят в состав Windows. компоненты среды разработки RPC устанавливаются при установке пакета средств разработки Microsoft Windows Software development Kit (SDK). Дополнительные сведения см. в разделе Установка среды программирования RPC.

Как работает RPC

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

Архитектура RPC

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

  • Извлекает необходимые параметры из адресного пространства клиента.
  • Преобразует необходимые параметры в стандартный формат NDR для передачи по сети.
  • Вызывает функции в клиентской библиотеке времени выполнения RPC для отправки запроса и его параметров на сервер.

Для вызова удаленной процедуры сервер выполняет следующие действия.

  1. Функции библиотеки времени выполнения RPC сервера принимают запрос и вызывают процедуру заглушки сервера.
  2. Заглушка сервера извлекает параметры из сетевого буфера и преобразует их из формата передачи сети в формат, который требуется серверу.
  3. Заглушка сервера вызывает фактическую процедуру на сервере.

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

  1. Удаленная процедура возвращает свои данные в заглушку сервера.
  2. Заглушка сервера преобразует выходные параметры в формат, необходимый для передачи по сети, и возвращает их в функции библиотеки времени выполнения RPC.
  3. Функции библиотеки времени выполнения RPC сервера передают данные в сети клиентскому компьютеру.

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

  1. Библиотека времени выполнения RPC клиента получает возвращаемые из удаленной процедуры значения и возвращает их в клиентскую заглушку.
  2. Клиентская заглушка преобразует данные из отчета о недоставке в формат, используемый клиентским компьютером. Заглушка записывает данные в память клиента и возвращает результат вызывающей программе на клиенте.
  3. Вызывающая процедура продолжится, как если бы процедура была вызвана на том же компьютере.

Библиотеки времени выполнения предоставляются в двух частях: библиотеку импорта, которая связана с приложением и библиотекой времени выполнения RPC, которая реализована как библиотека динамической компоновки (DLL).

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

Вступление

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

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

Терминология

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

Я разделил терминологию на три области: RPC (Remote Procedure Call), Messaging и REST. Эти области имеют под собою исторические корни.

RPC

RPC технологии — наиболее старые технологии. Наиболее яркие представители RPC, это — CORBA и DCOM.

В те времена в основном приходилось связывать системы в быстрых и относительно надежных локальных сетях. Главная идея RPC была в том, чтобы сделать вызов удаленных систем очень похожим на вызов функций внутри программы. Вся механика удаленных вызовов пряталась от программиста. По крайней мере её пытались спрятать. Программисты во многих случаях вынуждены были работать на более глубоком уровне, где появлялись термины маршалинг (marshalling) и unmarshalling (как это по-русски?), что по сути означало сериализацию. Обычные вызовы функций внутри процессов обрабатывались на вызывающей стороне в Proxy, а на стороне системы, выполняющей функцию, в Dispatcher. В идеале ни вызывающая система, ни обрабатывающая система не занимались тонкостями передачи данных между системами. Все эти тонкости сосредотачивались в связке Proxy — Dispatcher, код которых генерировался автоматически.

Поэтому вы не заметите, не должны заметить, никакой разницы между вызовом локальной функции и вызовом удаленной функции.
Сейчас наблюдается своеобразный ренесанс RPC, наиболее яркие представители которого: Google ProtoBuf, Thrift, Avro.

Messaging

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

Появились технологии веб-сервисов. Мы стали говорить ABC: Address, Binding, Contract. Не совсем понятно, почему появились контракты, которые по сути являются Envelope (конвертами) для входных аргументов. Контракты чаще усложняют всю модель, чем упрощают ее. Но… неважно.

Теперь программист явным образом создавал сервис (Service) или клиента (Client), вызывающего сервис. Сервис представлял из себя набор операций (Operation), каждая из которых на входе принимала запрос (Request) и выдавала ответ (Response). Клиент явным образом посылал (Sent) запрос, сервис явным образом получал (Receive) его и отвечал (Sent), высылая ответ. Клиент получал (Receive) ответ и на этом вызов завершался.

Так же, как и в RPC, где-то здесь работали Proxy и Dispatcher. И как прежде их код генерировался автоматически и программисту не надо было в нем разбираться. Разве только что, клиент явным образом использовал классы из Proxy.

REST

В постоянной борьбе со сложностью кода, программисты сделали очередной шаг и создали REST.

EntityAddress ReadEntityAddress(string param1, string param2)

выразится в таком виде:

Удаленный вызов процедур

Удаленный вызов процедур (RPC) (Майкрософт) определяет мощную технологию для создания распределенных программ клиента/сервера. Заглушки и библиотеки времени выполнения RPC управляют большинством процессов, связанных с сетевыми протоколами и связью. Это позволяет сосредоточиться на деталях приложения, а не на деталях сети.

Заключение

Прежде, чем начинать дискуссию по распределенным системам или по интеграции, определитесь с терминологией. Если Proxy всегда будет означать одно и то же в разных контекстах, то, к примеру, request мало что будет значить в терминах RPC, а marshalling вызовет недоумение при обсуждении REST технологий.

RPC, Messaging, REST: Терминология

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

RPC, Messaging, REST- Terminology - RPC, Messaging, REST- Терминология

Аудитория разработчиков

RPC предназначен для использования программистами C/C++. Знакомство с язык MIDL (MIDL) и компилятором MIDL является обязательным.

Службы и RPC/TCP

начиная с Windows Vista диспетчер управления службами (SCM) поддерживает удаленные вызовы процедур по протоколу управления передачей (rpc/TCP) и именованным каналам (rpc/NP). Функции SCM на стороне клиента используют RPC/TCP по умолчанию.

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

Когда служба вызывает удаленную функцию SCM, клиентский модуль SCM сначала пытается использовать RPC/TCP для связи со службой SCM на стороне сервера. если сервер работает под управлением версии Windows, поддерживающей rpc/tcp и разрешающей трафик rpc/tcp, подключение rpc/ткпп будет выполняться. если сервер работает под управлением версии Windows, которая не поддерживает rpc/tcp, или поддерживает rpc/tcp, но работает за брандмауэром, который разрешает только именованный канал, истекает время ожидания подключения rpc/tcp, и SCM повторяет подключение к rpc/NP. В конечном итоге это будет выполнено, но может занять некоторое время (обычно более 20 секунд), в результате чего функция OpenSCManager будет заблокирована.

Протокол TCP не содержит учетные данные пользователя, указанные с помощью команды net use . Таким образом, если RPC/TCP включен и sc.exe используется для попытки доступа к указанной службе, команда может завершиться ошибкой с отказом в доступе. Отключение RPC/TCP на стороне клиента приводит к тому, что команда sc.exe использует именованный канал, который содержит учетные данные пользователя, поэтому команда будет выполнена. Сведения о sc.exe см. в разделе Управление службой с помощью SC.

Служба не должна предоставлять явные учетные данные команде net use , так как эти учетные данные могут быть случайно предоставлены за пределами границ службы. Вместо этого служба должна использовать олицетворение клиента для олицетворения пользователя.

Значения реестра RPC/TCP

Управление RPC/TCP осуществляется с помощью значений реестра скмапиконнектионпарам, дисаблерпковерткп и дисаблеремотескмендпоинтс , которые находятся в ключе управления " _ Локальная _ машина" в папке hKey \ \ CurrentControlSet \ . Все эти значения имеют _ тип данных reg DWORD. В следующих процедурах показано, как использовать эти значения реестра для управления RPC/TCP.

В следующей процедуре описывается, как отключить RPC/TCP на стороне клиента.

Отключение RPC/TCP на стороне клиента

  1. Объедините значение реестра скмапиконнектионпарам со значением маски 0x80000000.
  2. Перезапустите приложение, вызывающее функцию OpenSCManager .

В следующей процедуре описывается, как отключить TCP на стороне сервера.

Отключение протокола TCP на стороне сервера

  1. Присвойте параметру реестра дисаблерпковерткп значение 1.
  2. Перезапустите сервер.

В следующей процедуре описывается, как отключить RPC/TCP и RPC/NP на сервере (например, чтобы уменьшить поверхность атаки).

Отключение RPC/TCP и RPC/NP на сервере

  1. Присвойте параметру реестра дисаблеремотескмендпоинтс значение 1.
  2. Перезапустите сервер.

Значение реестра скмапиконнектионпарам можно также использовать для указания интервала времени ожидания RPC/TCP в миллисекундах. Например, значение 30 000 указывает интервал времени ожидания 30 секунд. Значение по умолчанию — 21 000 (21 секунда).

Где применимо

RPC можно использовать во всех клиентских и серверных приложениях на основе операционных систем Windows. Его также можно использовать для создания клиентских и серверных программ для разнородных сетевых сред, включающих такие операционные системы, как UNIX и Apple.

Читайте также: