Возврат больших результатов через веб-сервис

В настоящее время я работаю над веб-службой, и есть вероятность, что возвращаемые результаты могут быть довольно большими (> 5 МБ).

Совершенно допустимо, чтобы этот набор данных был таким большим, и веб-сервис можно было назвать синхронным или асинхронным, но мне интересно, что люди думают о следующем:

  1. Если соединение потеряно, весь набор результатов придется заново сгенерировать и отправить. Есть ли способ сделать какое-либо «возобновление», если соединение потеряно или сброшено?

  2. Уместна ли отправка такого большого набора результатов? Было бы лучше реализовать своего рода «пейджинг», при котором набор результатов генерируется и хранится на сервере, а затем клиент может загружать фрагменты набора результатов в меньших количествах и повторно собирать набор на их конце?

Ответов (4)

Решение

Я видел все три подхода: с разбивкой по страницам , с сохранением и извлечением и с массовым толчком .

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

Подход к пейджингу

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

Хранить и извлекать

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

Массивный толчок

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

  1. убедиться, что части доходят до клиента
  2. можете отказаться от чанка, как только получите квитанцию ​​от клиента
  3. может уменьшить возможные проблемы с потреблением памяти из-за необходимости хранить 5 МБ XML, DOM или чего-либо еще в памяти (при условии, что вы не обрабатываете результаты в потоковом режиме) на стороне сервера и клиента.

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

Жесткого закона против 5 Мб в результате размера набора нет. Пересылка более 400 Мб может быть затруднена .

Вы автоматически получите асинхронные обработчики (поскольку вы используете .net)

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

Это уже происходит с вами - это называется tcp / ip ;-) Повторная реализация этого может быть излишней.

Сходным образом --

весь набор результатов нужно будет регенерировать и снова отправить

Если, например, MS-SQL генерирует большую часть набора результатов, то при его повторном создании будет использовано некоторое неявное кеширование в SQL Server, и последующие поколения будут быстрее.

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

Я несколько не согласен с комментарием secretGeek:

Это уже происходит с вами - это называется tcp / ip ;-) Повторная реализация этого может быть излишней.

Бывают случаи, когда вы можете захотеть сделать именно это, но на самом деле только с точки зрения пользовательского интерфейса. Если вы реализуете какой-либо способ потоковой передачи данных клиенту (с помощью чего-то вроде механизма pushlets) или разбиения их на страницы, как вы предлагаете, вы можете затем загрузить какое-то действительно небольшое подмножество на клиент, а затем медленно создать пользовательский интерфейс с помощью полный объем данных.

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

Похоже, вас заинтересует решение, которое добавляет параметр «номер начальной записи» и «номер конечной записи» в ваш веб-метод. (или "номер страницы" и "результатов на страницу")

Это не должно быть слишком сложно, если резервным хранилищем является сервер sql (или даже mysql), поскольку они имеют встроенную поддержку нумерации строк.

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