Почему HTTP/SOAP считается "толстым"
Я слышал некоторые мнения, что стек вызовов веб-сервисов SOAP/HTTP "толстый" или "тяжеловесный", но я не могу точно определить, почему. Будет ли он считаться толстым из-за сериализации / десериализации конверта SOAP и сообщения? Это действительно тяжелая операция?
Или это просто считается "толстым" по сравнению с передачей необработанных / двоичных данных по фиксированному соединению?
Или это какая-то другая причина? Может кто-нибудь пролить некоторый свет на это?
8 ответов
SOAP разработан достаточно абстрактно, чтобы использовать другие транспорты, кроме HTTP. Это означает, среди прочего, что он не использует преимущества определенных аспектов HTTP (в основном RESTful использование URL-адресов и методов, например, PUT /customers/1234
или же GET /customers/1234
).
SOAP также обходит существующие механизмы TCP/IP по той же причине - быть независимой от транспорта. Опять же, это означает, что он не может использовать преимущества транспорта, такие как управление последовательностями, управление потоками, обнаружение услуг (например, accept()
подключение к известному порту означает, что сервис существует) и т. д.
SOAP использует XML для всей своей сериализации - хотя это означает, что данные являются "универсально читаемыми" с помощью всего лишь синтаксического анализатора XML, он вводит так много шаблонов, что вам действительно нужен анализатор SOAP для эффективной работы. И в этот момент вы (как потребитель программного обеспечения) в любом случае утратили преимущества XML; кто заботится о том, как выглядит полезная нагрузка через провод, если вам нужно libSOAP
чтобы справиться с этим в любом случае.
SOAP требует WSDL для описания интерфейсов. Сам WSDL не является проблемой, но он, как правило, рекламируется гораздо более "динамично", чем на самом деле. Во многих случаях создается один WSDL, и из этого автоматически генерируется код производителя / потребителя, и он никогда не изменяется. В целом, для этого требуется много инструментов, без реального решения исходной проблемы (как общаться между различными серверами). А поскольку большинство служб SOAP работают по протоколу HTTP, исходная проблема уже была в основном решена с самого начала.
SOAP и WSDL являются чрезвычайно сложными стандартами, которые имеют много реализаций, которые поддерживают различные подмножества стандартов. SOAP не очень хорошо сопоставляется с простым интерфейсом внешних функций так же, как это делает XML-RPC. Вместо этого вы должны понимать пространства имен XML, конверты, заголовки, WSDL, схемы XML и т. Д., Чтобы создавать правильные сообщения SOAP. Все, что вам нужно сделать для вызова службы XML-RPC - это определить конечную точку и вызвать для нее метод. Например, в Ruby:
require 'xmlrpc/client'
server = XMLRPC::Client.new2("http://example.com/api")
result = server.call("add", 1, 2)
Помимо XML-RPC, существуют и другие методы, которые также могут быть гораздо более простыми и легкими, такие как простой XML или JSON через HTTP (часто называемый REST, хотя это подразумевает некоторые другие соображения проектирования). Преимущество чего-то вроде XML или JSON перед HTTP заключается в том, что его легко использовать из JavaScript или даже просто глупой веб-страницы с отправкой формы. Это также может быть легко написано из командной строки с помощью таких инструментов, как curl. Он работает практически с любым языком, поскольку HTTP-библиотеки, XML-библиотеки и JSON-библиотеки доступны практически везде, и даже если JSON-анализатор недоступен, написать свой собственный очень легко.
Изменить: я должен уточнить, что я имею в виду, как концептуально тяжелый SOAP, в отличие от большого веса это с точки зрения необработанного объема данных. Я думаю, что необработанный объем данных менее важен (хотя он быстро складывается, если вам нужно обрабатывать множество небольших запросов), а то, насколько он концептуально тяжелый, весьма важен, потому что это означает, что есть гораздо больше мест, где что-то может пойти не так, где может быть несовместимость и т. д.
Я согласен с первым постером, но хотел бы добавить к нему. Толстое и тонкое определение является относительным. С такими транспортными средствами, как JSON или REST, SOAP выглядит тяжело на поверхности для примеров "привет мира". Теперь, как вы, возможно, уже знаете, что делает SOAP тяжелым, а WS 2.0 в целом - корпоративными / надежными функциями. JSON не так безопасен, как WS 2.0. Я не слышал, чтобы SOAP назывался толстым, но многие не-XML-орехи смотрят на эти спецификации как на толстые или толстые. Чтобы было ясно, я не говорю ни за, ни против, поскольку оба имеют свое место. XML более многословен, удобен для чтения и, следовательно, "толще". Последняя часть состоит в том, что некоторые люди считают HTTP постоянным протоколом соединения тяжелым, учитывая новые веб-тенденции, такие как AJAX, вместо того, чтобы работать на большой странице. Накладные расходы на соединение велики, учитывая, что в действительности нет никакой выгоды.
Таким образом, нет никакой реальной причины, кроме того, что кто-то хочет назвать SOAP/HTTP толстым, это все относительно. Меньше стандартов идеально подходит и для всех сценариев. Если бы мне пришлось угадывать, какой-нибудь умный веб-разработчик думает, что он такой умный, говоря о том, как думают технологии XML и насколько супер JSON. У каждого есть место.
Соотношение сигнал / шум SOAP слишком низкое. Для простого разговора слишком много структурных издержек без значения данных; и требуется слишком много явной конфигурации (по сравнению с неявной конфигурацией, такой как JSON).
Это не началось таким образом, но в конечном итоге это стало детищем для того, что случается с хорошей идеей, когда в нее вмешивается комитет по стандартам.
Прежде всего, это во многом зависит от того, как реализованы ваши сервисы (то есть вы можете многое сделать для уменьшения полезной нагрузки, просто следя за тем, как выполняются сигнатуры вашего метода).
Тем не менее, не только мыльный конверт, но и само сообщение может быть намного более громоздким в xml, чем в упрощенном двоичном формате. Просто выбор правильного класса и имен членов может сильно уменьшить его...
Рассмотрим следующие примеры возврата сериализованного метода из методов, возвращающих коллекцию материала. Простой выбор правильного имени [serialization] для классов / оболочек и членов может существенно повлиять на многословность сериализованного запроса / ответа мыла, если вы возвращаете повторяющиеся данные (например, списки / коллекции / массивы).
Краткие / короткие имена:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfShortIDName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<ShortIDName>
<id>0</id>
<name>foo 0</name>
</ShortIDName>
<ShortIDName>
<id>1</id>
<name>foo 1</name>
</ShortIDName>
<ShortIDName>
<id>2</id>
<name>foo 2</name>
</ShortIDName>
...
</ArrayOfShortIDName>
Длинные имена:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfThisClassHasALongClassNameIDName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<ThisClassHasALongClassNameIDName>
<MyLongMemberNameObjectID>0</MyLongMemberNameObjectID>
<MyLongMemberNameObjectName>foo 0</MyLongMemberNameObjectName>
</ThisClassHasALongClassNameIDName>
<ThisClassHasALongClassNameIDName>
<MyLongMemberNameObjectID>1</MyLongMemberNameObjectID>
<MyLongMemberNameObjectName>foo 1</MyLongMemberNameObjectName>
</ThisClassHasALongClassNameIDName>
<ThisClassHasALongClassNameIDName>
<MyLongMemberNameObjectID>2</MyLongMemberNameObjectID>
<MyLongMemberNameObjectName>foo 2</MyLongMemberNameObjectName>
</ThisClassHasALongClassNameIDName>
...
</ArrayOfThisClassHasALongClassNameIDName>
1 - XML-схемы, которые являются ключевой частью спецификации WSDL, действительно, очень большие и сложные. На практике вы, инструменты, которые делают такие вещи, как отображение схемы XML на конструкции языка программирования, в конечном итоге поддерживают только часть функций схемы XML.
2 - Спецификации WS-*, например WS-Security и WS-SecureConversation, опять же являются большими и сложными. Они почти спроектированы таким образом, чтобы никто, кроме Microsoft или IBM, не располагал меньшим количеством ресурсов для их полной реализации.
Я посчитал это "толстым" из-за относительно больших накладных расходов, связанных с упаковкой и распаковкой сообщения (сериализацией и десериализацией).
Рассмотрим веб-сервис с веб-методом Add
это занимает два 32-разрядных целых числа. Вызывающая сторона упаковывает два целых числа и получает одно целое в ответе. Там, где на самом деле передается только 96 бит информации, добавление пакетов SOAP, вероятно, добавит около 3000 или более дополнительных бит в каждом направлении. 30-кратное увеличение.
К этому следует добавить относительно медленную производительность, связанную с сериализацией и десериализацией сообщения в XML-код UTF-8 (или любой другой). По общему признанию это довольно быстро в эти дни, но это конечно не тривиально.
Я думаю, это в основном то, что конверт SOAP добавляет большие издержки при построении сообщения, особенно для обычного случая простого запроса только с несколькими неструктурированными параметрами. Сравните это с веб-сервисом в стиле REST, в котором параметры просто включены в URL-запрос.
Затем добавьте к этому сложность WSDL и типичные "корпоративные" реализации библиотек...