Remote Procedure Call
Remote Procedure Call (RPC, удалённый вызов процедур) — это протокол или механизм, позволяющий программе вызывать функцию или процедуру, которая выполняется в другом адресном пространстве (обычно на другом компьютере в сети), как если бы это был локальный вызов. RPC абстрагирует детали сетевого взаимодействия, предоставляя разработчику интерфейс, сходный с вызовом локальной функции.
Принцип работы
В основе RPC лежит модель «клиент-сервер». Клиентское приложение инициирует вызов, а серверное — обрабатывает запрос и возвращает результат. Процесс включает следующие этапы:
- Создание заглушки (stub): Разработчик определяет интерфейс удалённой службы с помощью языка описания интерфейсов (IDL, Interface Definition Language). Компилятор IDL генерирует две заглушки: клиентскую (stub) и серверную (skeleton).
- Вызов клиентской заглушки: Клиентское приложение вызывает локальную функцию, которая на самом деле является заглушкой. Заглушка упаковывает аргументы вызова в сообщение — процесс называется маршалингом (marshalling). Сообщение включает идентификатор процедуры, параметры и метаданные.
- Передача по сети: Заглушка отправляет сообщение через транспортный протокол (например, TCP, UDP, HTTP/2) на сервер. Для этого часто используется дополнительный слой — RPC-протокол (например, ONC RPC, gRPC).
- Приём и распаковка на сервере: Серверная заглушка (skeleton) принимает сообщение, распаковывает (демаршалинг) аргументы и вызывает реальную серверную функцию.
- Выполнение процедуры: Серверная функция выполняется с переданными аргументами.
- Возврат результата: Результат выполнения упаковывается серверной заглушкой в ответное сообщение и отправляется обратно клиенту.
- Распаковка результата: Клиентская заглушка получает ответ, распаковывает его и возвращает результат клиентскому приложению.
История
Концепция RPC восходит к ранним исследованиям в области распределённых вычислений. В 1976 году в докладе Алана Кея (Alan Kay) был описан протокол, схожий по идеологии. Однако формальное определение и реализация были предложены в 1984 году Брюсом Джеем Нельсоном (Bruce Jay Nelson) в его докторской диссертации в Университете Карнеги — Меллон.
Ранние реализации включали:
- ONC RPC (Open Network Computing Remote Procedure Call) — разработан компанией Sun Microsystems в середине 1980-х годов. Использовался в файловой системе NFS (Network File System) и других сервисах Solaris.
- DCE/RPC (Distributed Computing Environment / Remote Procedure Call) — создан консорциумом Open Software Foundation (OSF) как часть платформы DCE. Использовался в Microsoft Windows (в частности, в компоненте DCOM — Distributed Component Object Model).
В 1990-х годах появились более высокоуровневые протоколы, такие как CORBA (Common Object Request Broker Architecture) и Java RMI (Remote Method Invocation), которые расширили концепцию RPC на объектно-ориентированное программирование. В 2000-х годах набрали популярность веб-сервисы на основе SOAP (Simple Object Access Protocol), которые, по сути, являются реализацией RPC поверх HTTP и XML. В 2010-х годах с развитием микросервисной архитектуры и контейнеризации возникли более современные и эффективные протоколы, такие как gRPC (разработан Google) и Apache Thrift (разработан Facebook).
Классификация
RPC-протоколы можно классифицировать по нескольким признакам:
По типу транспорта
- Синхронные: Клиент блокируется до получения ответа от сервера. Это наиболее распространённый и простой тип.
- Асинхронные: Клиент отправляет запрос и продолжает работу, не дожидаясь ответа. Ответ может быть получен позже через обратный вызов (callback) или механизм будущих результатов (future/promise).
- Однонаправленные (one-way): Клиент отправляет запрос без ожидания ответа. Сервер не отправляет подтверждения.
По формату сериализации
- Текстовые: Используют человекочитаемые форматы, такие как XML (в SOAP) или JSON (в JSON-RPC). Просты в отладке, но менее эффективны по скорости и объёму данных.
- Бинарные: Используют компактные двоичные форматы, такие как Protocol Buffers (protobuf) в gRPC, Thrift, Avro. Обеспечивают высокую производительность и малый размер сообщений.
По модели взаимодействия
- Запрос-ответ (Request-Reply): Классическая модель, где на каждый запрос приходит ровно один ответ.
- Потоковая передача (Streaming): Клиент и сервер могут обмениваться несколькими сообщениями в рамках одного RPC-вызова. Например, сервер может отправлять клиенту поток данных (server-side streaming) или клиент — поток запросов (client-side streaming). gRPC поддерживает все четыре комбинации (унарный, серверный стриминг, клиентский стриминг, двунаправленный стриминг).
Современные реализации
gRPC
gRPC — это высокопроизводительный RPC-фреймворк с открытым исходным кодом, разработанный компанией Google. Использует Protocol Buffers для сериализации и HTTP/2 в качестве транспорта. Поддерживает синхронные и асинхронные вызовы, потоковую передачу, аутентификацию и балансировку нагрузки. Широко применяется в микросервисных архитектурах, системах Интернета вещей (IoT) и мобильных приложениях.
Apache Thrift
Apache Thrift — фреймворк, разработанный компанией Facebook (продукт Meta, признанной экстремистской и запрещённой в РФ). Предоставляет собственный IDL и поддерживает множество языков программирования (C++, Java, Python, PHP, Ruby и др.). Использует бинарный протокол сериализации. Отличается высокой гибкостью и производительностью.
JSON-RPC
JSON-RPC — простой протокол, использующий JSON для сериализации. Основан на модели запрос-ответ. Часто применяется в веб-сервисах и API, где важна простота и совместимость с HTTP.
XML-RPC
XML-RPC — ранний протокол, использующий XML для сериализации и HTTP в качестве транспорта. В настоящее время считается устаревшим, но всё ещё встречается в некоторых legacy-системах.
Преимущества и недостатки
Преимущества
- Простота разработки: Разработчику не нужно вручную обрабатывать сетевое взаимодействие, сериализацию и десериализацию.
- Прозрачность: Вызов удалённой процедуры выглядит как вызов локальной функции, что упрощает понимание кода.
- Модульность: Позволяет разбивать приложение на независимые сервисы, которые взаимодействуют через чётко определённые интерфейсы.
- Производительность: Бинарные протоколы (gRPC, Thrift) обеспечивают высокую скорость передачи данных и низкую задержку.
Недостатки
- Сетевые задержки: Удалённые вызовы всегда медленнее локальных из-за затрат на передачу данных по сети.
- Уязвимость к сетевым ошибкам: Сбой сети, потеря пакетов или задержки могут привести к сбоям в работе приложения.
- Сложность отладки: Ошибки в удалённых вызовах сложнее диагностировать, чем локальные.
- Связность: Клиент и сервер жёстко связаны через интерфейс IDL, что может затруднить внесение изменений.
Применение
RPC широко используется в различных областях:
- Микросервисная архитектура: Внутренняя коммуникация между микросервисами (например, с помощью gRPC).
- Файловые системы: NFS использует ONC RPC для удалённого доступа к файлам.
- Базы данных: Многие СУБД (например, PostgreSQL, MySQL) используют RPC-подобные протоколы для взаимодействия с клиентами.
- Облачные вычисления: Взаимодействие между компонентами облачных платформ (например, Amazon Web Services, Google Cloud Platform).
- Игры: Онлайн-игры часто используют RPC для синхронизации состояния между сервером и клиентами.
Критика
Основная критика RPC связана с тем, что он пытается скрыть принципиальные различия между локальным и удалённым вызовом. Это может приводить к ошибкам, связанным с сетевыми задержками, отказами и сложностью распределённых транзакций. В 1994 году Питер Дойч (Peter Deutsch) сформулировал «Семь заблуждений распределённых вычислений», которые часто игнорируются разработчиками, использующими RPC. В частности, предполагается, что сеть надёжна, задержки отсутствуют, а пропускная способность бесконечна, что на практике неверно.
Источники
- Birrell, A. D., & Nelson, B. J. (1984). Implementing remote procedure calls. ACM Transactions on Computer Systems (TOCS), 2(1), 39-59.
- Nelson, B. J. (1981). Remote procedure call (Doctoral dissertation, Carnegie Mellon University).
- Tanenbaum, A. S., & Van Steen, M. (2007). Distributed systems: principles and paradigms. Prentice-Hall.
- Coulouris, G., Dollimore, J., Kindberg, T., & Blair, G. (2012). Distributed systems: concepts and design. Addison-Wesley.
- Документация gRPC: grpc.io
- Документация Apache Thrift: thrift.apache.org
- Deutsch, P. (1994). The eight fallacies of distributed computing. Sun Microsystems.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →