← Назад к вопросам

Что такое RPC?

2.2 Middle🔥 131 комментариев
#Теория тестирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое RPC?

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

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

Ключевые компоненты RPC

  • Клиент (Stub-клиент): Предоставляет интерфейс, идентичный удалённой процедуре. Его задача — упаковать (сериализовать) аргументы вызова в формат, пригодный для передачи по сети (marshalling), и отправить запрос серверу.
  • Сервер (Stub-сервер): Принимает сетевой запрос, распаковывает (десериализует) аргументы (unmarshalling), вызывает настоящую локальную реализацию процедуры, а затем упаковывает и отправляет результат обратно клиенту.
  • Сетевой транспорт: Обычно TCP/IP или HTTP, поверх которого работает протокол RPC.
  • Протокол сериализации: Определяет формат данных. Это может быть бинарный (например, Protocol Buffers (protobuf), Apache Thrift, MessagePack) или текстовый (например, JSON-RPC, XML-RPC).

Пример простого RPC взаимодействия

Рассмотрим на абстрактном примере вызова функции getUserBalance(userId).

1. Клиентская сторона (иллюзия локального вызова):

# Код разработчика выглядит просто
user_id = 123
balance = user_service.getUserBalance(user_id)
print(f"Balance: {balance}")

2. Что происходит "под капотом" (Stub-клиент):

# Клиентский stub сериализует вызов в сообщение (например, JSON)
request_message = {
    "method": "getUserBalance",
    "params": [123],
    "id": 1  # Идентификатор запроса для сопоставления ответа
}
# Сообщение отправляется по сети на сервер
network.send("http://api.example.com/rpc", request_message)

3. Серверная сторона (Stub-сервер):

# Сервер получает сообщение, десериализует его
received_message = network.receive()
method_name = received_message["method"]  # "getUserBalance"
params = received_message["params"]       # [123]

# Вызывает реальную бизнес-логику
real_result = real_database_query_for_balance(params[0])

# Формирует и отправляет ответ
response_message = {
    "result": real_result,
    "id": received_message["id"]
}
network.send_back(response_message)

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

  • gRPC (Google RPC): Современный высокопроизводительный фреймворк, использующий Protocol Buffers как язык описания интерфейсов (IDL) и бинарный протокол. Работает поверх HTTP/2.
  • JSON-RPC / XML-RPC: Более простые, человекочитаемые протоколы, использующие JSON или XML для кодирования сообщений. Часто используются в веб-сервисах.
  • Apache Thrift: Фреймворк от Facebook, похожий на gRPC, со своей системой типов и поддержкой множества языков.

Преимущества и недостатки с точки зрения QA

Преимущества для тестирования:

  • Чёткие контракты: Использование IDL (например, .proto файлы в gRPC) строго определяет API: методы, типы параметров и ответов. Это — источник истины для разработки тестов.
  • Производительность: Бинарные протоколы (gRPC) обычно эффективнее текстовых (REST/JSON), что важно для нагрузочного тестирования.
  • Сильная типизация: Снижает количество ошибок, связанных с несоответствием типов данных.

Недостатки и сложности для тестирования:

  • Сложность отладки: Бинарные данные нечитаемы без специальных инструментов. Необходимы прокси-инструменты (BloomRPC, grpcurl, Wireshark с декодерами) для просмотра трафика.
  • Сетевая природа: Обязательно нужно тестировать устойчивость к сетевым проблемам: таймауты, разрывы соединений, недоступность сервиса.
  • Совместимость версий: При обновлении .proto контракта необходимо тщательно тестировать обратную и прямую совместимость клиентов и серверов разных версий.

Что важно проверить QA-инженеру?

  1. Функциональное тестирование: Корректность вызова всех методов с валидными, граничными и невалидными данными.
  2. Тестирование контракта: Нарушение контракта (лишние поля, неверные типы, отсутствующие обязательные поля).
  3. Тестирование ошибок: Поведение системы при возврате сервером различных кодов ошибок (gRPC status codes).
  4. Нагрузочное тестирование: Проверка производительности и стабильности при высокой частоте вызовов, определение "узких мест".
  5. Тестирование таймаутов и устойчивости: Как клиент ведёт себя при медленном ответе сервера или его полной недоступности.
  6. Интеграционное тестирование: Взаимодействие между микросервисами через RPC в различных сценариях.
  7. Безопасность: Аутентификация и авторизация вызовов (например, с использованием TLS/SSL и JWT-токенов в gRPC).

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

Что такое RPC? | PrepBro