Сопоставление SOA/веб-сервисов

В SOA мы не должны создавать или удерживать состояние (или конструировать зависимости) между клиентом и сервером. Это понятно. Но какие шаблоны могут соблюдаться в случае, когда клиент хочет использовать услугу в режиме реального времени, которая может возвращать число строк с открытым концом?

Веб-приложения, похожие на SOA, но разрешающие состояние (сеансы), решили это с разбивкой по страницам. Для разбиения на страницы требуется (в большинстве случаев, особенно с SQL), что сервер хранит данные и что клиент запрашивает данные в кусках.

Если мы рассмотрим сценарии, похожие на страницы, для веб-сервисов, какие шаблоны будут следовать этим, это все равно позволит придерживаться принципов SOA (или как можно ближе).

Некоторые правила для мыслителей: 1) При поддержке базы данных SQL (поэтому в наборе выбора нет понятия номера строки) 2) Важно не пропускать строку или дублировать строку в наборе во время разбивки на страницы 3) Данные могут быть вставлены и удалены в любое время в базу данных другими клиентами 4) Нет необходимости рассматривать набор данных как живой (обновляемый) набор данных

Лично я считаю, что 1 и 2 выше уже произнесли наше решение, сдерживая пространство решения с требованиями.

Мое предлагаемое решение будет содержать данные (насколько это было выбрано) в хранилище/кеш-память, доступном только для чтения, где ему может быть присвоен номер строки в результирующем наборе и разрешить разбиение на страницы в этом снимке данных. У меня была бы инфраструктура для хранения снимков (серверов, внешних кэшей, memcached или ehcache - это должно масштабироваться довольно велико). Результатом такого запроса будет идентификатор моментального снимка, и клиенты могут извлекать данные из моментального снимка с помощью API-интерфейса моментальных снимков (веб-служб) и идентификатора моментального снимка. Результаты будут обрабатываться только в режиме "только для чтения", только для х записей в то время, когда x было чем-то разумным.

Было бы высоко оценено конкурирующие мысли и идеи, критические замечания или похвалы.

Ответ 1

SOA не предназначена для таких низкоуровневых функций.

SOA предназначена для склеивания бизнес-областей, а не интерфейсов к бэкэндам. Не потому, что ваше приложение обращается к заднему концу с помощью веб-служб, у вас есть приложение "SOA". Это не имеет смысла, поскольку SOA не имеет смысла в контексте одной изолированной системы.

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

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

Использование этого веб-сервиса в SOA-шине было бы плохо. Я не могу быть последовательным, так как пользователь разбивается на страницы, и по мере того как другие приложения зависают, они становятся привязанными к конкретному SQL.

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

SOA предназначен для деловых сообщений между системами, а не для склеивания интерфейса приложения к серверу.

Ответ 2

Разобранные результаты в веб-службе на самом деле довольно легко достичь.

Все, что вам нужно сделать, это добавить два параметра к вызову веб-службы: размер страницы, номер страницы.

Размер страницы - это количество результатов, которые должны быть указаны на странице. Номер страницы - это номер страницы, которую вы ищете.

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

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

Ответ 3

То, что вы предлагаете с memcached, также будет работать с таблицей кеширования. Первый вызов службы (1) INSERT приведет к тому, что в таблицу кэширования с идентификатором моментальной копии (2) верните первую страницу из таблицы кеширования и идентификатора моментального снимка. Последующие вызовы будут возвращать страницы на основе размера страницы и номера страницы, запросив таблицу кэширования с помощью идентификатора моментального снимка.

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

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

Ответ 4

Такая же проблема решена с использованием подхода Navision.

$ws->getList($first_record_id, $limit)

Это возвращает страницу $limit, которая начинается с переданного id

select * from collection where collection.id > $first_record_id ASC limit $limit

упорядочен по id ASC

Ключ использования Navision (каждый элемент имеет ключ), но в MySQL лучше использовать идентификатор автоинкремента.

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

Ответ 5

Я не уверен, что здесь SOA вызывает беспокойство. Проблема, с которой вы сталкиваетесь, связана с разбиением на страницы ваших API. Я укажу вам, как твиттер обрабатывает их разбиение на страницы dev.twitter.com/rest/public/timelines