Открыть сервис

RPC

RPC (англ. Remote Procedure Call, «удалённый вызов процедур») — это протокол или механизм, позволяющий программе вызывать выполнение функции (процедуры) в другом адресном пространстве (обычно на удалённом компьютере или в другом процессе) так, как если бы это был локальный вызов. RPC абстрагирует детали сетевого взаимодействия, сериализации данных и обработки ошибок, предоставляя разработчику модель, близкую к вызову локальной функции. Основная цель RPC — упростить создание распределённых систем, скрывая сложность передачи данных по сети.

История

Концепция RPC восходит к 1970-м годам, когда возникла необходимость в организации взаимодействия между программами, работающими на разных узлах сети. Одной из первых реализаций стала система NFS (Network File System), разработанная компанией Sun Microsystems в 1984 году, которая использовала собственный протокол RPC на основе ONC (Open Network Computing). В 1980-х годах компания Xerox разработала протокол Courier, а затем в 1990-х годах появились стандартизированные спецификации, такие как DCE/RPC (Distributed Computing Environment / Remote Procedure Call) от Open Software Foundation.

В 1990-е годы широкое распространение получили XML-RPC и SOAP (Simple Object Access Protocol), которые использовали XML для сериализации данных и HTTP в качестве транспортного протокола. В 2000-х годах, с развитием микросервисной архитектуры, появились более лёгкие и производительные протоколы, такие как gRPC (от Google, 2015 год) и Apache Thrift (от Facebook, 2007 год). gRPC использует Protocol Buffers для сериализации и HTTP/2 для транспорта, что обеспечивает высокую скорость и поддержку потоковой передачи данных.

Архитектура и принцип работы

RPC-система обычно включает три ключевых компонента:

  1. Клиент — программа, которая инициирует вызов удалённой процедуры.
  2. Сервер — программа, которая реализует и предоставляет удалённые процедуры.
  3. Транспортный уровень — сетевая инфраструктура (например, TCP/IP, HTTP/2), обеспечивающая передачу данных между клиентом и сервером.

Процесс вызова RPC состоит из нескольких этапов:

  1. Клиентский вызов: Клиент вызывает локальную функцию-заглушку (stub), которая выглядит как обычная локальная процедура.
  2. Сериализация (маршалинг): Заглушка упаковывает имя процедуры и её аргументы в формат, пригодный для передачи по сети (например, JSON, XML, Protocol Buffers).
  3. Передача запроса: Заглушка отправляет сериализованные данные через сетевой протокол (например, HTTP, TCP) на сервер.
  4. Демаршалинг на сервере: Серверная заглушка (skeleton) получает данные, распаковывает их и извлекает аргументы.
  5. Выполнение процедуры: Сервер вызывает реальную реализацию процедуры с переданными аргументами.
  6. Сериализация ответа: Результат выполнения процедуры упаковывается серверной заглушкой.
  7. Передача ответа: Сервер отправляет сериализованный результат обратно клиенту.
  8. Демаршалинг на клиенте: Клиентская заглушка распаковывает ответ и возвращает его клиенту как результат вызова.

Классификация и виды

RPC-протоколы можно классифицировать по нескольким признакам:

По формату сериализации данных

  • Текстовые протоколы: Используют человекочитаемые форматы, такие как XML (SOAP) или JSON (JSON-RPC). Обеспечивают простоту отладки, но менее производительны.
  • Бинарные протоколы: Используют компактные бинарные форматы, такие как Protocol Buffers (gRPC), Apache Thrift или Avro. Обеспечивают высокую скорость и низкую задержку, но сложнее для отладки.

По транспортному протоколу

  • На основе HTTP: SOAP, JSON-RPC, gRPC (через HTTP/2). Используют стандартные веб-порты (80, 443), что упрощает прохождение через брандмауэры.
  • На основе TCP: ONC RPC, DCE/RPC. Обеспечивают более низкую задержку, но требуют настройки сетевых правил.

По модели синхронизации

  • Синхронные RPC: Клиент блокируется до получения ответа от сервера. Это наиболее распространённая модель.
  • Асинхронные RPC: Клиент отправляет запрос и продолжает работу, не дожидаясь ответа. Ответ обрабатывается через callback или механизм событий (например, в gRPC с использованием потоков).

По типу вызова

  • Однонаправленный (unary): Клиент отправляет один запрос и получает один ответ.
  • Потоковый (streaming): Клиент или сервер могут отправлять несколько сообщений в рамках одного RPC-вызова (например, серверный стриминг, клиентский стриминг, двунаправленный стриминг в gRPC).

Популярные реализации

gRPC

Разработан компанией Google в 2015 году. Использует Protocol Buffers для сериализации и HTTP/2 для транспорта. Поддерживает множество языков программирования (C++, Java, Python, Go, C# и др.). Отличается высокой производительностью, поддержкой потоковой передачи данных, встроенными механизмами аутентификации и балансировки нагрузки. Широко применяется в микросервисных архитектурах.

Apache Thrift

Разработан компанией Facebook (продукт Meta, признанной экстремистской и запрещённой в РФ) в 2007 году, передан в Apache Software Foundation. Поддерживает бинарную и компактную сериализацию, а также собственный транспортный протокол. Позволяет генерировать код для многих языков. Используется в высоконагруженных системах, таких как Cassandra и Hadoop.

JSON-RPC

Лёгкий протокол, использующий JSON для сериализации. Может работать поверх HTTP, TCP или WebSockets. Прост в реализации и отладке, но менее производителен, чем бинарные протоколы. Часто применяется в веб-приложениях и API.

SOAP (Simple Object Access Protocol)

Протокол, основанный на XML. Использует WSDL (Web Services Description Language) для описания интерфейсов. Обеспечивает строгую типизацию и поддержку сложных структур данных, но является громоздким и медленным. В настоящее время вытесняется более лёгкими протоколами, такими как REST и gRPC.

XML-RPC

Предшественник SOAP, использующий XML для сериализации и HTTP для транспорта. Прост, но ограничен в возможностях (поддерживает только простые типы данных). В настоящее время используется редко.

Применение

RPC-протоколы широко применяются в различных областях:

  • Микросервисная архитектура: gRPC и Thrift являются стандартными инструментами для организации взаимодействия между микросервисами.
  • Распределённые файловые системы: NFS использует ONC RPC для удалённого доступа к файлам.
  • Базы данных: Многие СУБД (например, MySQL, PostgreSQL) используют собственные RPC-протоколы для взаимодействия между клиентом и сервером.
  • Облачные вычисления: API облачных провайдеров (например, Google Cloud, AWS) часто используют gRPC для вызова удалённых процедур.
  • Встраиваемые системы: RPC применяется для управления устройствами через сеть (например, в IoT).

Критика и ограничения

Несмотря на популярность, RPC имеет ряд недостатков:

  • Сложность отладки: Ошибки в RPC-вызовах (например, таймауты, сетевые сбои) могут быть трудны для диагностики, так как они скрыты за абстракцией локального вызова.
  • Проблемы с версионированием: Изменение сигнатуры процедуры (добавление или удаление аргументов) может привести к несовместимости между клиентом и сервером.
  • Сетевая задержка: Каждый RPC-вызов влечёт за собой накладные расходы на сериализацию, передачу и демаршалинг, что может быть критично для высоконагруженных систем.
  • Проблемы с безопасностью: RPC-системы требуют тщательной настройки аутентификации, авторизации и шифрования, чтобы предотвратить несанкционированный доступ.

Интересные факты

  • Термин «RPC» был впервые введён в 1976 году в статье Брюса Джея Нельсона «Remote Procedure Call».
  • gRPC был разработан для внутренних нужд Google и использовался для связи между сервисами, обрабатывающими миллиарды запросов в день.
  • Apache Thrift изначально создавался для решения проблем масштабирования Facebook, где требовалось быстрое и эффективное взаимодействие между серверами.

Источники

  • Birrell, A. D., & Nelson, B. J. (1984). Implementing remote procedure calls. ACM Transactions on Computer Systems.
  • gRPC documentation. (2024). gRPC.io.
  • Apache Thrift documentation. (2024). Thrift.apache.org.
  • Tanenbaum, A. S., & Van Steen, M. (2007). Distributed Systems: Principles and Paradigms.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →