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-система обычно включает три ключевых компонента:
- Клиент — программа, которая инициирует вызов удалённой процедуры.
- Сервер — программа, которая реализует и предоставляет удалённые процедуры.
- Транспортный уровень — сетевая инфраструктура (например, TCP/IP, HTTP/2), обеспечивающая передачу данных между клиентом и сервером.
Процесс вызова RPC состоит из нескольких этапов:
- Клиентский вызов: Клиент вызывает локальную функцию-заглушку (stub), которая выглядит как обычная локальная процедура.
- Сериализация (маршалинг): Заглушка упаковывает имя процедуры и её аргументы в формат, пригодный для передачи по сети (например, JSON, XML, Protocol Buffers).
- Передача запроса: Заглушка отправляет сериализованные данные через сетевой протокол (например, HTTP, TCP) на сервер.
- Демаршалинг на сервере: Серверная заглушка (skeleton) получает данные, распаковывает их и извлекает аргументы.
- Выполнение процедуры: Сервер вызывает реальную реализацию процедуры с переданными аргументами.
- Сериализация ответа: Результат выполнения процедуры упаковывается серверной заглушкой.
- Передача ответа: Сервер отправляет сериализованный результат обратно клиенту.
- Демаршалинг на клиенте: Клиентская заглушка распаковывает ответ и возвращает его клиенту как результат вызова.
Классификация и виды
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 →