2013-03-31 2 views
5

Предположим, у нас есть инфраструктура SOA, подобная той, что написана ниже, и , что каждая служба может работать на другом хосте (это особенно актуально для сети с двумя сетевыми сервисами) сайт "и" платежная система ").Service Oriented Architecture и Loose Coupling vs SQL JOINS

SOA infrastructure

Очевидно, мы получили слой данных (устойчивость). Предположим, что он реализуется через EJB + JPA или что-то подобное.

Если мы хотим объединить данные (в пользовательском интерфейсе) между различными услугами, которые я вижу, по крайней мере несколько альтернатив:

  • мы хотим сделать эффективным JOIN и на уровне СУБД, поэтому мы имеем пакет (т.е. persistence.package), который содержит все объекты и сессионные фасады (реализация CRUD), которые каким-то образом должны быть разделены (как?) или, развернутых для каждой службы. Тем не менее, если я что-то изменил в схеме заказа, я должен перераспределить эти пакеты, введя узкую связь между почти всем. Кроме того, база данных должна быть уникальной и общей.

  • , чтобы избежать таких проблем, мы сохраняем пакет сущности для каждой отдельной службы (то есть order.package) и позволяем службам обмениваться данными через некоторый протокол (мыло, отдых, esb и т. Д.). поэтому мы можем хранить данные локально в каждом хосте (не использовать ни одну архитектуру), и нам не нужно повторно развертывать пакет сущности. Но этот подход страшен для интеллектуального анализа данных в качестве запроса, который должен искать и возвращать коррелированные данные между несколькими службами будет очень неэффективен (как мы не можем сделать SQL присоединяется)

Есть ли лучше/стандартный подход к указанным выше вопросам?

ответ

4

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

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

Когда и если вы найти разделение на сервисы логично, чем следовать совету Марко и обеспечить, чтобы службы были изолированы и не делят базы данных. Предоставление услуг, изолированных таким образом, служит их способности к изменению. Затем вы можете интегрировать их в пользовательский интерфейс с помощью composite front end. Следует отметить, что это хорошо работает для операционной стороны приложения, так как вам нужно всего несколько элементов от каждой службы. Для отчетности вам нужно что-то вроде aggregated reporting, т. Е. Экспортировать неизменяемые копии данных в центральную базу данных, оптимизированную для отчетности (например, денормализованная звездная схема и т. Д.)

+0

«этот [только] работает хорошо для операционной стороны приложения, так как вам нужно всего несколько элементов от каждой службы». действительно, в этом проблема: обычно нам нужно много данных из разных сервисов, сложных поисков и поиска в режиме реального времени в пользовательском интерфейсе. Что касается агрегированной отчетности, я вижу очень мало случаев, когда эти данные можно считать неизменяемыми (так что обычно денормализация вводит проблемы синхронизации). – gpilotino

+0

Ну сказал Армон. Я думаю, что лучшее для @gpilotino - немного прочитать о DDD; это очень хорошая книга: http://www.infoq.com/minibooks/domain-driven-design-quickly, и перейдите оттуда. – Marco

+0

Отсутствие денормализации @gpilotino не вызывает проблем с синхронизацией, не знаю, откуда вы это взяли. Использование разных моделей записи и чтения действительно может привести к проблемам синхронизации, но это не имеет ничего общего с денормализованными данными. – Marco

2

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

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

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

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

enter image description here

Служба платежей необходимо идентификатор заказа и идентификатор клиента, но эти лица принадлежат их собственным услугам, так что вместо обмена секретного ключа (первичный ключ) каждую запись, каждая запись будет иметь вместо этого первичный ключ и суррогатный внешний ключ, который сервисы будут использовать для совместного использования. Дело в том, что вы должны стремиться к созданию спаренных услуг, каждый со своей собственной «небольшой» базой данных. Каждая служба также должна иметь каждый собственный API, который должен использоваться не только передним концом, но и другими службами. Еще одна вещь, которую вам следует избегать, заключается в использовании DTC или другого поставщика управления транзакциями в качестве гаранта транзакций для всей службы, это то, что может быть легко архивировано с использованием другого архитектурного подхода.

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

UPDATE:

Вы можете использовать что-то вроде событий SOA, но позволяет держать вещи простыми здесь. Зарегистрированный клиент приходит на ваш сайт для размещения заказа. Служба, ответственная за это, - это Заказы. Список внешних идентификаторов для продуктов отправляется службе Ордеров, которые затем регистрируют заказ, на данный момент заказ находится в состоянии «ожидающего платежа», и эта служба возвращает общедоступный идентификатор заказа Guid. Для того чтобы заказ был завершен, клиенту необходимо оплатить товар. Детали оплаты передаются в службу оплаты, которая пытается обработать платеж, но для этого ему нужны детали заказа, поскольку единственное, что отправил frontend, - это идентификатор заказа, и для этого он использует GetOrderDetails (Guid orderId) из API заказа. Как только платеж будет завершен, услуга «Платежи» вызывает еще один метод API-заказа OrderWasCompletedForOrder (Guid orderID). Дай мне знать, если что-то не получишь.

+0

ОК, но это все еще не решает проблемы «больших объединений с корреляционными данными» , конечно, я могу хранить внешние ключи в подсистеме заказов, но когда мне нужен список ордеров, коррелированных с именем покупателя, которое будет неэффективно (в равной степени уважать соединение sql), чтобы спросить подсистему людей и т. д.забыть о ejb и технологиях, моя проблема в том, что если я не хочу синхронизировать/распространять изменения схемы (чтобы не повредить вещи), что является самым эффективным способом справиться с этим. – gpilotino

+0

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

+0

Я знаю, что вы имеете в виду, но проблема в том, что веб-система не является надлежащим отделом, поэтому она не должна существовать. Как я уже сказал, каждая служба должна иметь свои собственные уровни API. В домене заказов у ​​вас есть список заказов, связанных с внешним идентификатором покупателя, который затем сопоставляется с частным идентификатором в службе people, поэтому я не знаю, где проблема. – Marco