Концепция RPC - Russian Pravoslavnaya Church

RPC - клиент-серверный механизм, который позволяет запустить исполнение кода процедуры на другой машине так, словно бы он исполнялся локально. То есть разработчик просто привычным образом обращается к процедуре, не задумываясь о том, где и как она исполняется - главное, чтобы она ответ вернула.
А программа уже сама реализует взаимодействие с удалённой машиной.
Прелесть этого подхода в том, что он, во-первых, позволяет скрыть удалённый характер работы. А, во-вторых, на той, другой, стороне совершенно неважно, какая операционная система, архитектура, язык программирования и окружение - главное, чтобы они подчинялись одному протоколу.
Например из-под винды в exe-шнике, написанном на Delphi, вы можете исполнить удалённую программу, написанную на го, запущенную на линуксе. И никто вам не сможет помешать!
Но что, по большому счёту, мы делаем, когда, зайдя по SSH, выполняем какую-то команду на коммутаторе или маршрутизаторе? Запускаем определённый код.
Например, сообщаем подсистеме BGP, что нужно теперь пробовать установить соединение с новым пиром.

Но только представьте, как было бы восхитительно, если бы для вызова этого кода, не нужно было заходить на железку по SSH и вбивать команду?!

Постойте! Да ведь именно об этом мы и говорим в данном разделе. | Большую оставшуюся часть статьи мы посвятим именно RPC.

Пример

Абстрактно взаимодействие с сетевым оборудованием выглядеть может примерно так.
Для начала мы определяем спецификацию - это некий контракт, который гарантирует, что у клиента и сервера одинаковое понимание процедуры: имя, параметры, типы данных итд.
  1. Наша убер-платформа автоматизации вызывает некую функцию add_bgp_peer_stub(ip="10.1.1.1", as="12345").
  2. Функция add_bgp_peer_stub открывает спецификацию для протокола, реализующего RPC, и согласно ей упаковывает полученные параметры, которые станут payload’ом для сообщения. Такая упаковка называется маршалинг.
  3. Далее формирует пакет и передаёт его вниз по стеку и - в сеть.
  4. На другой стороне - на устройстве - приложение получает пакета.
  5. Функция, принявшая сообщение, вытаскивает из него параметры процедуры, согласно той же самой спецификации и формирует список параметров. Это называется демаршалинг.
  6. Приложение выполняет функцию - настраивает BGP-соседа 10.1.1.1 с AS 12345. Проверяет успешность выполнения.
  7. Далее функция формирует на основе всё той же спецификации сообщение-ответ и передаёт его в ответном пакете.
  8. Наша локальная сторона, с которой мы инициировали выполнение RPC, получает ответ, словно бы его вернула локальная функция.
  9. Воаля

Поподробнее про RPC.

В целом RPC - это концепция, не говорящая ничего о реализации.
Она постулирует, что на стороне клиента есть так называемый стаб (stub) - фрагмент кода, который реализует взаимодействие по RPC. Именно стабы делают для разработчика прозрачным вызов функции - из приложения вызывается этот стаб с набором параметров, а уже стаб делает удалённый вызов.
Ключевая часть RPC - спецификация - штука, которая на стороне сервера и клиента определяет, как работать с данными - как упаковать, как распаковать. Без участия человека, конечно же.
Язык, на котором пишется спецификация - IDL - Interface Definition Language.
Иными словами, на IDL пишется спецификация, на основе которой создаются и серверный интерфейс, и клиентский стаб. Это может быть, например, набор классов в питоне, имеющих функции для удалённого вызова, с которыми разработчик работает так, словно всё происходит локально - для клиента. И набор объектов Go - для сервера.

Мы дальше разберём два протокола, которые используются под капотом RPC и при этом позволяют управлять сетевым железом.

  • NETCONF
  • gNMI (использующий gRPC)