Рубрики
Без рубрики

rpc против ОСТАЛЬНЫХ – Простой Тест Производительности

Обзор Как разработчик Java, API RESTful – это мой хлеб с маслом. В большинстве дней я провожу… С тегами java, grpc, отдых, весна.

Обзор

Как разработчик Java, API RESTful – это мой хлеб с маслом. В большинстве дней я трачу большую часть своего времени на написание кода, который либо составляет конечные точки RESTful, либо взаимодействует с ними, либо нисходящий код, запускаемый конечной точкой.

Несколько лет назад я слышал о некоторых слухах о новом формате RPC, и я сразу же вспомнил о своих днях, когда занимался легким GWT (Google Web Toolkit) разработка. С этими словами я отбросил идею исследования gRPC и продолжил свои стандартные рабочие процессы.

Однако несколько месяцев назад мне была предоставлена возможность заняться новым проектом Golang на работе. Я слышал много хорошего о Голанге, поэтому сразу же нырнул в него.

С тех пор я влюбился в этот язык, хотя Java по-прежнему остается тем местом, где я чувствую себя как дома.

Однако, используя Go, я все чаще и чаще сталкиваюсь с использованием gRPC.

Поэтому в рамках моего дальнейшего обучения я разработал этот простой небольшой тест, чтобы увидеть, как дебаты о производительности rpc против REST на самом деле разворачиваются только в Java.

Это не невероятно научный эксперимент, но я чувствую, что он, по крайней мере, дает несколько четкие результаты относительно того, чего можно ожидать, когда кто-то на вашей работе начнет предлагать новую горячность (в данном случае gRPC) и клянется, что это решит проблему X или Y и даст преимущества в производительности A или B.

Я был таким парнем раньше, и это всегда помогает иметь соответствующие и конкретные результаты, чтобы показать всем, что помогает повлиять на вашу точку зрения.

Итак, с этим покончено, вот мой глупый маленький эксперимент по производительности rpc на основе Java против Rest.

Отдых против rpc tl;dr

Прежде чем мы перейдем к эксперименту и тестированию, вот краткий обзор.

API-интерфейсы RESTful используют HTTP 1.0/1.1 и включают использование глаголов HTTP (например. ПОЛУЧИТЬ/ОПУБЛИКОВАТЬ/УДАЛИТЬ) для передачи сообщений от клиента к серверу. Большинство серверов предоставляют конечные точки, которые ожидают определенных заголовков и команд и используют входящие данные для выполнения операций. Данные обычно представлены в формате JSON, который Java-код десериализует в объекты Java для использования в приложении.

gRPC, с другой стороны, использует HTTP/2 и буферы протоколов, которые могут быть упрощены в двоичный файл по протоколу HTTP. Буферы протокола описывают длину компонентов в двоичном потоке. Поэтому вместо того, чтобы разграничивать данные с помощью токенов JSON (таких как {, и “), потоки данных являются двоичными и анализируются с использованием известных размеров ожидаемых типов данных. Затем это десериализуется в объекты Java.

Хорошо, вот упрощенный обзор деталей теста.

Тестовые данные и макет

Цель этого теста состояла в том, чтобы дать некоторые примеры производительности rpc по сравнению с Rest, в частности. Это одна из наиболее часто приводимых причин для перехода на gRPC, поскольку данные в виде двоичного потока меньше, чем объект json.

Этот тест был реализован с использованием ровно 2 приложений JVM. Одним из них является приложение Spring Boot, которое содержит аннотированные классы RestController для обработки входных данных, а также содержит клиент, который использует WebClient Spring Webflux для выполнения блокирующих вызовов API к RestController.

Второе приложение – это собственное приложение Java, которое использует библиотеки io.grpc для определения клиента и сервера gRPC.

Эти приложения были развернуты в двух местах и запускались как выполняемые jar-файлы. Оба были развернуты на локальном рабочем столе, а также на экземпляре AWS EC2. Подробности для обоих включены в следующий раздел.

Тест заключается в следующем:

  • Используйте случайно сгенерированные данные в определенном формате, который идентичен в gRPC и Тестирование на отдых

  • Отправляйте все большее количество запросов, чтобы увидеть, как масштабируется обработка

  • представьте производительность в полуреальном мире, совершая звонки из локальной системы в центр обработки данных, расположенный на расстоянии не менее 200 миль.

Вот пример макета шаблона Rest JSON:

{
    "car": {
        "make": "toyota",
        "model": "corolla",
        "trim": "4DR Sedan",
        "color": "gray",
        "year": 2012,
        "mileage": 120000
    },
    "driver": {
        "firstname": "John",
        "lastname": "Smith",
        "driverId": "someId"
    }
}

Вот определение прототипа для сообщений gRPC

syntax = "proto3";
option java_multiple_files = true;

message Message {

    message Car {
        string make = 1;
        string model = 2;
        string trim = 3;
        string color = 4;
        uint32 year = 5;
        uint32 mileage = 6;
    }

    message Driver {
        string firstname = 1;
        string lastname = 2;
        string driverId = 3;
    }

    Car car = 1;
    Driver driver = 2;
}

Они функционально идентичны и могут служить примером того, как может выглядеть переход от существующего Rest API к заменяющему gRPC api.

Испытательные машины

Удаленной машиной, на которой работали серверы gRPC и Rest, были машины экземпляра t2.small EC2. Это были обычные, не спортивные, не выделенные экземпляры t2.small, в которых был открыт весь трафик TCP и UDP. С белым списком для локальной тестовой машины, которая будет попадать в него.

Приложения JVM были запущены локально с использованием Windows 10 x64 OpenJDK версии 11.0.11. Удаленные JVM были запущены с использованием java-11-amazon-corbett на ОС AWS Linux 2.

Локальная тестовая машина была моим личным рабочим столом для разработки. Эта система содержит Ryzen 3700x и 64 ГБ оперативной памяти 3200 ГГц. Более чем излишне для выполнения описанных выше тестов.

Результаты

Каждый тест был проведен (от локального до ec2) 10 раз, и было взято среднее значение. Это было для последовательных запросов через Rest и gRPC, как показано в столбцах ниже.

gRPC (ВРП) 14478мс 25239 мс 37823 мс 53073мс 62624 мс
Отдых 16451 мс 30181 мс 43996 мс 58221 мс 71300 мс

Есть пара вещей, которые мы хотим рассмотреть в рамках этих результатов. Они являются подразделами ниже!

Насколько медленнее отдых при каждой сумме запроса

1000 на 13,6% медленнее
2000 на 19,5% медленнее
3000 на 16% медленнее
4000 на 9% медленнее
5000 на 13% медленнее

Мы можем с уверенностью сказать, что gRPC всегда будет быстрее, чем вызовы Rest. Это согласуется с деталями реализации gRPC, в частности двоичными потоками через JSON, двоичным анализом и маршалингом и т. Д.

Какова была корреляция между увеличением количества запросов и временем завершения для Rest и rpc

Хороший вопрос! Таким образом, при каждом увеличении количества запросов мы ожидаем линейного увеличения времени обработки этих сообщений. Т. е. дважды сообщения должны занимать в два раза больше времени. Давайте посмотрим, так ли это было на самом деле.

gRPC (ВРП) основание на 74% дольше на 49% дольше на 40% дольше на 17% дольше
Отдых основание на 83% дольше на 45% дольше на 32% дольше на 22% дольше
Запрос на увеличение в % 0 на 100% больше на 50% больше на 33% больше на 25% больше

Основываясь на приведенных выше результатах, это немного хит или промах. И Rest, и gRPC примерно отслеживают увеличение. В большинстве случаев время обработки увеличивается быстрее, чем увеличивается запрос, и это хорошо! Это означает, что мы не тратим экспоненциально все больше и больше времени на обработку большего количества запросов.

О чем все это нам говорит?

Вне этого конкретного теста? Ни тонны. Это хороший пример для использования в качестве основы и хороший простой эксперимент для сравнения эффективности двух парадигм.

Как и следовало ожидать, репозиторий доступен на Github со всем исходным кодом .

Оригинал: “https://dev.to/stevenpg/grpc-vs-rest-simple-performance-test-228m”