1. Web service

Documentation OR Specification:

В каждой отрасли бизнеса, каждой компании, как правило, используется огромное количество ПО, которым нужно взаимодействовать между собой. За десятилетия существования Web как отрасли сформировались следующие практики межсетевого взаимодействия:

  • Web services.

  • Неструктурированные HTTP-запросы, договорённости между разработчиками.

  • Sockets, порты, бинарные объекты.

  • Обмен файлами по FTP.

1.1. Что такое Web service?

Существует огромное количество различных определений того, что есть Web service. Некоторые из них весьма спорны и противоречивы, поэтому стоит обратиться к источнику, который является истинной высшей инстанции: The World Wide Web Consortium. World Wide Web Consortium (Консорциум World Wide Web/W3C) — это международное сообщество, разрабатывающее открытые стандарты для обеспечения долгосрочного роста Web.

A Web service is a software system designed to support interoperable machine-to-machine interaction over a network. It has an interface described in a machine-processable format (specifically WSDL). Other systems interact with the Web service in a manner prescribed by its description using SOAP-messages, typically conveyed using HTTP with an XML serialization in conjunction with other Web-related standards.
— W3C
Web Services Glossary

Это определение из Web Services Glossary, что в переводе звучит как:

Web service — это программная система, предназначенная для поддержки межмашинного взаимодействия по сети. Он имеет интерфейс, описанный в машинно-обрабатываемом формате (в частности, WSDL). Другие системы взаимодействуют с Web service способом, предписанным ее описанием, с использованием SOAP-сообщений, обычно передаваемых с использованием HTTP с сериализацией XML в сочетании с другими стандартами, связанными с Web.

Стоит отметить, что некоторые моменты из этого описания не должны быть панацеей, так как они связанные с моментом появления понятия Web service и не отражали текущих реалий (взаимодействия с помощью REST подхода, gRPC и т.д.):

  • Web service не обязан иметь такое интерфейс описанный в машинно-обрабатываемом формате.

  • Необязательно SOAP-сообщений

  • Необязательно в формате данных XML (сейчас, чаще всего, это JSON. Так же возможны вариант бинарный Protobuf используемый в gRPC, а так же Avro)

  • Необязательно по HTTP (обычно все же он, но есть не популярные альтернативы в виде SPDY, QUICK от Google)

Так же можно дать следующие, менее формальные определения:

  • Web services (веб сервисы, веб службы) - это технология, позволяющая системам обмениваться данными друг с другом через сетевое подключение. Обычно веб-сервисы работают поверх протокола HTTP или протокола более высокого уровня.

  • Web service можно использовать для одного приложения на компьютере или предоставить к нему доступ через Интернет любому числу приложений. Поскольку доступ к web service выполняется через стандартный интерфейс, с нем могут работать различные системы, образуя единую вычислительную сеть.

Взаимодействие с web services идет в рамках Client-Server Architecture (клиент-серверной архитектуры), где всегда есть Client и Server. Server – это и есть web service. Иногда его называют endpoint (типа как, конечная точка, куда доходят сообщения от клиента), но данное название будет не совсем корректным.

Самые известные способы реализации Web services:

  • XML-RPC (XML Remote Procedure Call) — протокол удаленного вызова процедур с использованием XML. Прародитель SOAP. Предельно прост в реализации.

  • SOAP (Simple Object Access Protocol) — стандартный протокол по версии W3C. Четко структурирован и задокументирован.

  • JSON-RPC (JSON Remote Procedure Call) — более современный аналог XML-RPC. Основное отличие — данные передаются в формате JSON.

  • REST (Representational State Transfer) — архитектурный стиль взаимодействия компьютерных систем в сети основанный на методах протокола HTTP.

  • gRPC как более эффективный, передающий данные в бинарном виде и использующий HTTP/2 в качестве транспорта.

  • GraphQL - специализированные протокол для конкретного вида задач.

Главное отличие web service от других способов передачи данных: стандартизированность. Приняв решение использовать web service, можно сразу переходить к структуре данных и доступным функциям. Например, В SOAP (как более строгом протоколе), уже решён вопрос уведомления об ошибках.

1.2. Отличия REST от SOAP

REST и SOAP на самом деле не сопоставимы. REST — это архитектурный стиль. SOAP — это протокол отправки сообщения. Давайте сравним популярные реализации стилей REST и SOAP.

  • SOAP это протокол, REST – это архитектурный стиль, SOAP имеет веб-сервис WSDL с прописанными методами, которые можно удаленно вызывать.

  • REST использует JSON и XML, SOAP только XML.

  • REST работает только по HTTP/HTTPS, SOAP с любым протоколом прикладного уровня: SMTP, FTP, HTTP, HTTPS, POP3

  • REST более простой, гибкий и быстрый, SOAP типизированный, но в некоторых случаях лучше визуализируется за счет применения им синтаксиса похожего на HTML разметку.

  • RESTful веб-сервисы, как правило, гораздо проще реализовать, чем веб-сервисы на основе SOAP.

  • В REST легко изменять функционал без изменения клиента, в то время в SOAP после изменений необходимо изменять WSDL и, следовательно, вносить изменения на клиенте.

  • REST может работать с ресурсами. Каждый URL это представление какого-либо ресурса. SOAP работает с операциями, которые реализуют какую-то бизнес-логику с помощью нескольких интерфейсов.

  • SOAP на основе чтения не может быть помещена в кэш, а REST в этом случае может быть кеширован.

  • SOAP поддерживает TLS и WS-security, в то время как REST - только TLS.

  • SOAP поддерживает ACID (Atomicity, Consistency, Isolation, Durability). REST поддерживает транзакции, но не один из ACID не совместим с two-phase commit protocol (2PC/двухфазная фиксация).

2. SOAP

Documentation OR Specification:

SOAP web-services ("Big web-service", классический web-service) - это протокол, предназначенный для обмена структурированной информацией в децентрализованной распределенной среде. Первоначально SOAP расшифровывался как Simple Object Access Protocol и предназначался в основном для реализации удалённого вызова процедур (RPC). Сейчас протокол используется для обмена произвольными сообщениями в формате XML, а не только для вызова процедур.

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

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

Две основные цели разработки SOAP - это простота и расширяемость. SOAP пытается достичь этих целей, исключая из инфраструктуры обмена сообщениями функции, которые часто встречаются в распределенных системах. Такие функции включают, помимо прочего, «надежность», «безопасность», «корреляцию», «маршрутизацию» и «шаблоны обмена сообщениями» (MEP). Хотя ожидается, что будут определены многие функции, эта спецификация предоставляет подробные сведения только для двух MEP. Остальные функции оставлены для определения как расширения другими спецификациями.

Как было сказано выше, SOAP является протоколом и имеет спецификацию. В качестве транспортного протокола может использовать HTTP, SMTP, FTP, JMS. Все детали сообщений (в обе стороны – от клиента к серверу и обратно) передаются в стандартизованном XML-документе. SOAP чаще всего применяется поверх HTTP(S).

soap architecture

SOAP – это базовая однонаправленная модель соединения, обеспечивающая согласованную передачу сообщения от отправителя к получателю, потенциально допускающая наличие посредников, которые могут обрабатывать часть сообщения или добавлять к нему дополнительные элементы. Спецификация SOAP содержит соглашения по преобразованию однонаправленного обмена сообщениями в соответствии с принципом «запрос/ответ», а также определяет как осуществлять передачу всего XML-документа.

Нужно отметить, что определение SOAP web-services состоит из набора протоколов (спецификаций):

  • Протокол SOAP необходим для реализации возможностей обратного вызова

  • Протокол WSDL (Web-Service Description Language) язык определения web-services или язык описания внешних интерфейсов web-службы на базе XML

  • Протокол UDDI (необязательный) (Universal Description, Discovery, Interoperability) универсальное описание или каталог веб-служб и сведений предоставляющих WSDL.

web service soap

2.1. SOAP message

Любое сообщение в протоколе SOAP — это XML документ.

Данный документ состоит из следующих элементов (тегов):

  • SOAP Envelope — конверт (корневой обязательный элемент), который определяет сообщение и пространство имен, использованное в документе.

  • SOAP Header — заголовок, необязательный элемент, содержит атрибуты сообщения, например: информация о безопасности или о сетевой маршрутизации.

  • SOAP Body — основной элемент, содержит сообщение, которым обмениваются приложения.

  • Fault — необязательный элемент, предоставляет информацию об ошибках, которые произошли при обработке сообщений.

soap message

Конверт является самым «верхним» элементом SOAP сообщения. Описывается с помощью элемента Envelope с обязательным пространством имен http://www.w3.org/2003/05/soap-envelope для версии 1.2 и http://schemas.xmlsoap.org/soap/ для версии 1.1. У элемента Envelope могут быть атрибуты xmlns, определяющие пространства имен, и другие атрибуты, снабженные префиксами.

Заголовок SOAP является не обязательный. Заголовок кроме атрибутов xmlns может содержать 0 или более стандартных атрибутов:

  • encodingStyle

  • actor (или role для версии 1.2)

  • mustUnderstand

  • relay

Элемент Body обязательно записывается сразу за элементом Header, если он есть в сообщении, или первым в SOAP-сообщении, если заголовок отсутствует. В элемент Body можно вложить произвольные элементы, спецификация никак не определяет их структуру. Определен только один стандартный элемент, который может быть в теле сообщения - Fault, содержащий сообщение об ошибке.

Если SOAP-сервер, обрабатывая поступившее SOAP-сообщение, обнаружит ошибку, то он прекратит обработку и отправит клиенту SOAP-сообщение, содержащее один элемент Fault с сообщением об ошибке.

Пример запроса на сервер:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
     <getProductDetails xmlns="www.example.com">
       <productID>12345</productID>
     </getProductDetails>
   </soap:Body>
</soap:Envelope>

Пример ответа:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
     <getProductDetailsResponse xmlns="www.example.com">
       <getProductDetailsResult>
         <productID>12345</productID>
         <productName>Стакан граненый</productName>
         <description>Стакан граненый. 250 мл.</description>
         <price>9.95</price>
         <currency>
             <code>840</code>
             <alpha3>USD</alpha3>
             <sign>$</sign>
             <name>US dollar</name>
             <accuracy>2</accuracy>
         </currency>
         <inStock>true</inStock>
       </getProductDetailsResult>
     </getProductDetailsResponse>
   </soap:Body>
</soap:Envelope>

2.2. WSDL

WSDL (Web Services Description Language) — язык описания веб-сервисов и доступа к ним, основанный на языке XML.

Другими словами, определения WSDL описывают, как получить доступ к веб-службе и какие операции она будет выполнять.

Каждый документ WSDL 1.1 можно разбить на следующие логические части:

  • Определение типов данных (types) — определение вида отправляемых и получаемых сервисом XML-сообщений

  • Элементы данных (message) — сообщения, используемые web-сервисом

  • Абстрактные операции (portType) — список операций, которые могут быть выполнены с сообщениями

  • Связывание сервисов (binding) — способ, которым сообщение будет доставлено

wsdl file

Документ WSDL содержит следующие элементы:

  • Определение — это корневой элемент всех документов WSDL. Он определяет имя веб-службы, объявляет несколько пространств имен, используемых в оставшейся части документа, и содержит все элементы службы, описанные здесь.

  • Типы данных — типы данных, которые будут использоваться в сообщениях, представлены в форме схем XML.

  • Сообщение — это абстрактное определение данных в форме сообщения, представленного либо в виде всего документа, либо в качестве аргументов, которые должны быть сопоставлены с вызовом метода.

  • Операция — это абстрактное определение операции для сообщения, например, присвоение имени методу, очереди сообщений или бизнес-процессу, которое примет и обработает сообщение.

  • Тип порта — это абстрактный набор операций, сопоставленный с одной или несколькими конечными точками, определяющий набор операций для привязки; коллекция операций, как она абстрактна, может быть сопоставлена с несколькими транспортными средствами через различные привязки.

  • Связывание — это конкретный протокол и форматы данных для операций и сообщений, определенных для определенного типа порта.

  • Порт — это сочетание привязки и сетевого адреса, обеспечивающее целевой адрес службы связи.

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

В дополнение к этим основным элементам спецификация WSDL также определяет следующие служебные элементы:

  • Документация — Этот элемент используется для предоставления удобочитаемой документации и может быть включен в любой другой элемент WSDL.

  • Импорт — этот элемент используется для импорта других документов WSDL или схем XML.

Файл WSDL выглядит следующим образом:

<definitions name = "HelloService"
   targetNamespace = "https://www.examples.com/wsdl/HelloService.wsdl"
   xmlns = "http://schemas.xmlsoap.org/wsdl/"
   xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:tns = "https://www.examples.com/wsdl/HelloService.wsdl"
   xmlns:xsd = "http://www.w3.org/2001/XMLSchema">

   <message name = "SayHelloRequest">
      <part name = "firstName" type = "xsd:string"/>
   </message>

   <message name = "SayHelloResponse">
      <part name = "greeting" type = "xsd:string"/>
   </message>

   <portType name = "Hello_PortType">
      <operation name = "sayHello">
         <input message = "tns:SayHelloRequest"/>
         <output message = "tns:SayHelloResponse"/>
      </operation>
   </portType>

   <binding name = "Hello_Binding" type = "tns:Hello_PortType">
      <soap:binding style = "rpc"
         transport = "http://schemas.xmlsoap.org/soap/http"/>
      <operation name = "sayHello">
         <soap:operation soapAction = "sayHello"/>
         <input>
            <soap:body
               encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/"
               namespace = "urn:examples:helloservice"
               use = "encoded"/>
         </input>

         <output>
            <soap:body
               encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/"
               namespace = "urn:examples:helloservice"
               use = "encoded"/>
         </output>
      </operation>
   </binding>

   <service name = "Hello_Service">
      <documentation>WSDL File for HelloService</documentation>
      <port binding = "tns:Hello_Binding" name = "Hello_Port">
         <soap:address
            location = "https://www.examples.com/SayHello/" />
      </port>
   </service>
</definitions>
  • Definitions - HelloService

  • Type - использование встроенных типов данных, которые определены в XMLSchema.

  • Message

    • sayHelloRequest - параметр firstName

    • sayHelloresponse - возвращаемое значение приветствия

  • Port Type - операция sayHello, состоящая из службы запроса и ответа.

  • Binding - Направление использования транспортного протокола SOAP HTTP.

  • Service - Сервис доступен по адресу http://www.examples.com/SayHello/.

  • Port - связывает привязку с URI http://www.examples.com/SayHello/, по которому можно получить доступ к работающей службе.

2.3. Преимущества

Преимущества:

  • Работа с методами

  • Наличие строгой спецификации

  • Большое количества спецификаций

  • Поддержка транзакций, уровней безопасности и пр.

  • Различные транспортные уровни (HTTP, SMTP, FTP, JMS)

2.4. Недостатки

Недостатки:

  • Сложность реализации (по сравнению с REST);

  • Работа только через XML

  • Сложность/ресурсоемкость parsing (разбора) XML-данных

  • При изменениях необходимо обновлять WSDL, и, следовательно, вносить изменения на клиенте

3. REST

REST (Representational State Transfer) — на самом деле архитектурный стиль, а не протокол. Фактически, он основывается на соглашениях. Сервис построенный в стиле REST называется REST-сервисом. Веб-сервис, построенный с учетом всех требований и ограничений архитектурного стиля, можно назвать RESTful веб-сервисом.

REST не зависит от какого-либо протокола, но почти каждый RESTful сервис использует HTTP как основной протокол.

Существует шесть обязательных ограничений для построения распределённых REST-приложений:

  • Модель клиент-сервер

  • Отсутствие состояния

  • Кэширование

  • Единообразие интерфейса

  • Слои

  • Код по требованию (необязательное ограничение)

3.1. Модель клиент-сервер

Первым ограничением, применимым к гибридной модели, является приведение архитектуры к модели клиент-сервер. Разграничение потребностей является принципом, лежащим в основе данного накладываемого ограничения. Отделение потребности интерфейса клиента от потребностей сервера, хранящего данные, повышает переносимость кода клиентского интерфейса на другие платформы, а упрощение серверной части улучшает масштабируемость. Наибольшее же влияние на всемирную паутину, пожалуй, имеет само разграничение, которое позволяет отдельным частям развиваться независимо друг от друга, поддерживая потребности в развитии интернета со стороны различных организаций.

3.2. Отсутствие состояния

Протокол взаимодействия между клиентом и сервером требует соблюдения следующего условия: в период между запросами клиента никакая информация о состоянии клиента на сервере не хранится (Stateless protocol или «протокол без сохранения состояния»). Все запросы от клиента должны быть составлены так, чтобы сервер получил всю необходимую информацию для выполнения запроса. Состояние сессии при этом сохраняется на стороне клиента. Информация о состоянии сессии может быть передана сервером какому-либо другому сервису (например, в службу базы данных) для поддержания устойчивого состояния, например, на период установления аутентификации. Клиент инициирует отправку запросов, когда он готов (возникает необходимость) перейти в новое состояние.

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

3.3. Кэширование

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

3.4. Единообразие интерфейса

К фундаментальным требованиям REST архитектуры относится и унифицированный, единообразный интерфейс. Клиент должен всегда понимать, в каком формате и на какие адреса ему нужно слать запрос, а сервер, в свою очередь, также должен понимать, в каком формате ему следует отвечать на запросы клиента. Этот единый формат клиент-серверного взаимодействия, который описывает, что, куда, в каком виде и как отсылать и является унифицированным интерфейсом.

Наличие унифицированного интерфейса является фундаментальным требованием дизайна REST-сервисов. Унифицированные интерфейсы позволяют каждому из сервисов развиваться независимо.

К унифицированным интерфейсам предъявляются следующие четыре ограничительных условия:

  • Идентификация ресурсов. Все ресурсы идентифицируются в запросах, например, с использованием URI в интернет-системах. Ресурсы концептуально отделены от представлений, которые возвращаются клиентам. Например, сервер может отсылать данные из базы данных в виде HTML, XML или JSON, ни один из которых не является типом хранения внутри сервера.

  • Манипуляция ресурсами через представление. Если клиент хранит представление ресурса, включая метаданные — он обладает достаточной информацией для модификации или удаления ресурса.

  • Само описываемые сообщения. Каждое сообщение содержит достаточно информации, чтобы понять, каким образом его обрабатывать. К примеру, обработчик сообщения (parser), необходимый для извлечения данных, может быть указан в списке MIME-типов.

  • Гипермедиа как средство изменения состояния приложения (HATEOAS). Клиенты изменяют состояние системы только через действия, которые динамически определены в гипермедиа на сервере (к примеру, гиперссылки в гипертексте). Исключая простые точки входа в приложение, клиент не может предположить, что доступна какая-то операция над каким-то ресурсом, если не получил информацию об этом в предыдущих запросах к серверу. Не существует универсального формата для предоставления ссылок между ресурсами, Web Linking (RFC 5988, потом RFC 8288) и JSON Hypermedia API Language являются двумя популярными форматами предоставления ссылок в REST HYPERMEDIA сервисах.

3.5. Слои

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

3.6. Код по требованию (необязательное ограничение)

REST может позволить расширить функциональность клиента за счёт загрузки кода с сервера в виде апплетов или сценариев. Roy Fielding (американский учёный, который и ввел термин REST) утверждает, что дополнительное ограничение позволяет проектировать архитектуру, поддерживающую желаемую функциональность в общем случае, но, возможно, за исключением некоторых контекстов.

3.7. Преимущества

Преимущества:

  • Легко разрабатывать

  • Производительность (за счёт использования кэша);

  • Может возвращать ответ в разных видах (HTML, XML, JSON, строка и т.д.)

  • Легко вносить изменения без изменения клиента

  • Надёжность (за счёт отсутствия необходимости сохранять информацию о состоянии клиента, которая может быть утеряна);

  • Масштабируемость;

  • Простота интерфейсов;

  • Портативность компонентов;

3.8. Недостатки

Недостатки:

  • Не сохраняет состояния (HTTP не сохраняет состояние)

  • Важный недостаток REST API — слабая устойчивость к взлому.

4. gRPC

gRPC - это мощный фреймворк для работы с удаленными вызовами процедур. RPC позволяют писать код, как если бы он был запущен на локальном компьютере, даже если он может выполняться на другом компьютере.

4.1. Что такое RPC?

RPC - это форма взаимодействия клиент-сервер, в которой используется вызов функции, а не обычный HTTP-вызов.

Он использует IDL (язык определения интерфейса) как форму контракта на вызываемые функции и на тип данных.

Архитектура RPC

Архитектура RPC

Если вы все еще этого не осознали, RPC в gRPC означает удаленный вызов процедуры. И да, gRPC действительно копирует этот архитектурный стиль взаимодействия клиент-сервер с помощью вызовов функций.

Так что gRPC технически не новая концепция. Скорее он был заимствован из этой старой техники и усовершенствован, что сделало его очень популярным всего за пару лет.

4.2. Обзор gRPC

В 2015 году Google открыла исходный код своего проекта, который в конечном итоге получил название gRPC. Но что на самом деле означает g в gRPC?

Google меняет значение буквы g для каждой версии до такой степени, что они даже сделали README, чтобы перечислить все значения.

С момента появления gRPC он приобрел довольно большую популярность, и многие компании его используют.

4.3. Что делает gRPC таким популярным?

Существует множество причин, по которым gRPC так популярен:

  • Абстракция - это просто (это вызов функции)

  • Поддерживается на многих языках.

  • Очень эффективен

  • HTTP-вызовы часто сбивают с толку, поэтому он упрощает интеграцию

И помимо всех вышеперечисленных причин, gRPC популярен, потому что очень популярны микросервисы.

Микросервисы часто запускают несколько сервисов на разных языках программирования. У них также часто бывает много сервисов для обслуживания взаимодействий.

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

gRPC очень популярен в сервисе для сервисных вызовов, поскольку часто HTTP-вызовы труднее понять с первого взгляда.

Обдумывать функции gRPC гораздо проще, поэтому разработчикам не нужно беспокоиться о написании большого количества документации, потому что сам код должен все объяснять.

Некоторые службы также могут быть написаны на разных языках, и gRPC поставляется с несколькими библиотеками для поддержки этого.

Производительность - это вишенка на вершине - и это большая изюминка.

4.4. Архитектура gRPC

Архитектура gRPC

Архитектура gRPC

Производительность gRPC очень хороша, но что делает его таким хорошим? Что делает gRPC намного лучше, чем RPC, когда их дизайн очень похож?

Вот несколько ключевых отличий, которые делают gRPC таким производительным.

4.4.1. HTTP/2

HTTP используется в Web уже давно. Сейчас почти все серверные службы используют этот протокол.

История HTTP

История HTTP

HTTP/1.1 долгое время оставался актуальным.

Затем в 2015 году появился HTTP/2, который по сути заменил HTTP/1.1 как самый популярный транспортный протокол в Интернете.

2015 год был годом выхода gRPC, это было отнюдь не совпадение. HTTP/2 также был создан Google для использования gRPC в своей архитектуре.

HTTP/2 - одна из главных причин, по которой gRPC может работать так хорошо.

4.4.2. Request/Response Multiplexing

В традиционном протоколе HTTP невозможно отправить несколько запросов или получить несколько ответов вместе в одном соединении. Для каждого из них необходимо будет создать новое соединение.

Этот вид Request/Response Multiplexing (мультиплексирования запроса/ответа) стал возможным в HTTP/2 с введением нового уровня HTTP/2, называемого binary framing (двоичным кадрированием).

Двоичным кадрирование

История HTTP

Этот двоичный уровень инкапсулирует и кодирует данные. На этом уровне HTTP-запрос/ответ разбивается на кадры.

Headers frame (кадр заголовков) содержит типичную информацию заголовков HTTP, а data frame (кадр данных) содержит полезную нагрузку. Используя этот механизм, можно получать данные из нескольких запросов в одном соединении.

Это позволяет получать полезные данные из нескольких запросов с одним и тем же заголовком, таким образом идентифицируя его как один запрос.

4.4.3. Header Compression

Иногда приходится сталкиваться со случаями, когда заголовки HTTP даже больше, чем полезная нагрузка. И HTTP/2 имеет очень интересную стратегию под названием HPACK, чтобы справиться с этим.

Во-первых, все в HTTP/2 кодируется перед отправкой, включая заголовки. Это действительно помогает с производительностью, но это не самое главное в Header Compression (сжатии заголовков).

HTTP/2 отображает заголовок как на стороне клиента, так и на стороне сервера. Исходя из этого, HTTP/2 может узнать, содержит ли заголовок то же значение, и отправляет значение заголовка, только если оно отличается от предыдущего заголовка.

Сжатие заголовка

Сжатие заголовка

На изображении выше, запрос №2 отправит только путь, поскольку другие значения точно такие же. И да, это значительно сокращает размер полезной нагрузки и, в свою очередь, еще больше улучшает производительность HTTP/2.

4.4.4. Protobuf

Protobuf

Protobuf

Protobuf (Буфер протокола) - это наиболее часто используемый IDL (Interface Definition Language/язык определения интерфейса) для gRPC. Здесь в основном хранятся модели данных и функциональные контракты в виде .proto-файла.

message Person {
    required string name = 1;
    required int32 id = 2;
    optional string email = 3;
}

Поскольку это форма контракта, и клиент, и сервер должны иметь один и тот же .proto-файл. Файл .proto действует как посреднический контракт для клиента для вызова любых доступных функций с сервера.

Protobuf также владеет механизмами, в отличие от обычного REST API, который просто отправляет строки JSON в виде байтов. Эти механизмы позволяют значительно уменьшить полезную нагрузку и повышать производительность.

Метод кодирования, который использует Protobuf, довольно сложен. Если вы хотите глубже понять, как это работает, ознакомьтесь с этой исчерпывающей документацией.

4.5. Что еще предлагает gRPC?

4.5.1. Metadata

Вместо использования обычного заголовка HTTP-запроса в gRPC есть нечто, называемое Metadata (метаданными). Метаданные - это тип данных "ключ-значение", которые могут быть установлены на стороне клиента или сервера.

Header могут быть назначены на стороне клиента, в то время как серверы могут назначать Header и Trailers при условии, что они оба находятся в форме метаданных.

4.5.2. Streaming

Streaming (Потоковая передача) - одна из основных концепций gRPC, при которой в одном запросе может выполняться несколько вещей. Это стало возможным благодаря возможности мультиплексирования HTTP/2.

Есть несколько видов стриминга:

  • Server Streaming RPC
    когда клиент отправляет один запрос, а сервер может отправить обратно несколько ответов. Например, когда клиент отправляет запрос на домашнюю страницу со списком из нескольких элементов, сервер может отправлять ответы отдельно, что позволяет клиенту использовать отложенную загрузку.

  • Client Streaming RPC
    когда клиент отправляет несколько запросов, а сервер отправляет только один ответ. Например, zip/chunk, загруженный клиентом.

  • Bidirectional Streaming RPC
    когда и клиент, и сервер отправляют сообщения друг другу одновременно, не дожидаясь ответа.

4.5.3. Interceptors

gRPC поддерживает использование Interceptors (перехватчиков) для своего запроса/ответа. Перехватчики перехватывают сообщения и позволяют изменять их.

Звучит знакомо? Если вы играли с HTTP-процессами в REST API, перехватчики очень похожи на middleware (промежуточное ПО).

Библиотеки gRPC обычно поддерживают перехватчики и позволяют легко реализовать. Перехватчики обычно используются для:

  • Изменения запроса/ответа перед передачей. Его можно использовать для предоставления обязательной информации перед отправкой на клиент/сервер.

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

4.5.4. Load Balancing

Load balancing (балансировка нагрузки) - это механизм, который позволяет распределять клиентские запросы по нескольким серверам.

Но балансировка нагрузки обычно выполняется на уровне прокси (например, nginx).

Оказывается, gRPC поддерживает метод балансировки нагрузки клиентом. Он уже реализован в библиотеке Golang и может быть легко использован.

Хотя это может показаться какой-то безумной магией, на самом деле это не так. Есть какой-то DNS-преобразователь для получения списка IP-адресов и алгоритм балансировки нагрузки под капотом.

4.5.5. Call Cancellation

Клиенты gRPC могут отменить вызов gRPC, когда ему больше не нужен ответ. Однако откат на стороне сервера невозможен.

Эта функция особенно полезна для потоковой передачи на стороне сервера, когда могут поступать несколько запросов к серверу. Библиотека gRPC оснащена методами Observer pattern (шаблона наблюдатель), чтобы знать, отменен ли запрос, и позволяет ему отменить сразу несколько соответствующих запросов.