Это классический вопрос, который мне недавно задали во время интервью. Как вызывать несколько веб-сервисов и при этом сохранять обработку ошибок в середине задачи. Сегодня в высокопроизводительных вычислениях мы избегаем двухфазных коммитов. Много лет назад я читал статью о том, что называлось «моделью Starbuck» для транзакций: подумайте о процессе заказа, оплаты, приготовления и получения кофе, который вы заказываете в Starbuck ... Я упрощаю вещи, но двухфазная модель фиксации могла бы Предположим, что весь процесс будет представлять собой одну транзакцию упаковки для всех этапов, пока вы не получите свой кофе. Однако с этой моделью все сотрудники будут ждать и прекращать работать, пока вы не получите свой кофе. Ты видишь картинку?
Вместо этого «модель Starbuck» более продуктивна, следуя модели «максимальных усилий» и компенсируя ошибки в процессе. Во-первых, они уверены, что вы платите! Затем есть очереди сообщений с вашим заказом, прикрепленным к чашке. Если что-то пойдет не так в процессе, например, вы не получили свой кофе, это не то, что вы заказали и т. Д., Мы вступаем в процесс компенсации и гарантируем, что вы получите то, что хотите, или вернете вам деньги. Это наиболее эффективная модель. для повышения производительности.
Иногда Starbuck тратит кофе, но в целом процесс эффективен. Есть и другие хитрости, о которых нужно подумать, когда вы создаете свои веб-сервисы, например, проектирование их таким образом, чтобы их можно было вызывать любое количество раз и при этом обеспечивать одинаковый конечный результат. Итак, моя рекомендация:
Не будьте слишком хороши при определении ваших веб-сервисов (я не уверен, что шумиха вокруг микро-сервисов происходит в наши дни: слишком много рисков зайти слишком далеко);
Async повышает производительность, поэтому предпочитайте быть асинхронными, отправляйте уведомления по электронной почте, когда это возможно.
Создавайте более интеллектуальные сервисы, чтобы их можно было «вызывать» любое количество раз, обрабатывая их с помощью идентификатора пользователя или задачи, которые будут следовать порядку снизу вверх до конца, проверяя бизнес-правила на каждом этапе;
Используйте очереди сообщений (JMS или другие) и переключайтесь на процессоры обработки ошибок, которые будут применять операции для «отката», применяя противоположные операции. Кстати, для работы с асинхронным порядком потребуется какая-то очередь для проверки текущего состояния процесса, так что подумай;
В крайнем случае (поскольку это может случаться не часто), поместите его в очередь для ручной обработки ошибок.
Давайте вернемся к первоначальной проблеме, которая была опубликована. Создайте аккаунт, создайте кошелек и убедитесь, что все сделано.
Скажем, веб-сервис призван организовать всю операцию.
Псевдокод веб-сервиса будет выглядеть так:
Позвоните в микросервис создания учетной записи, передайте ему некоторую информацию и какой-то уникальный идентификатор задачи. 1.1 Микросервис создания учетной записи сначала проверит, была ли эта учетная запись уже создана. Идентификатор задачи связан с записью учетной записи. Микросервис обнаруживает, что учетная запись не существует, поэтому создает ее и сохраняет идентификатор задачи. ПРИМЕЧАНИЕ: эту услугу можно вызывать 2000 раз, она всегда будет выполнять один и тот же результат. Служба отвечает «квитанцией, которая содержит минимальную информацию для выполнения операции отмены при необходимости».
Вызовите создание кошелька, присвоив ему идентификатор учетной записи и идентификатор задачи. Допустим, условие недействительно и создание кошелька не может быть выполнено. Вызов возвращается с ошибкой, но ничего не было создано.
Оркестр проинформирован об ошибке. Он знает, что должен прервать создание Учетной записи, но сам не сделает этого. Он попросит службу кошелька сделать это, передав свою «минимальную квитанцию об отмене», полученную в конце шага 1.
Служба Account считывает квитанцию об отмене и знает, как отменить операцию; квитанция об отмене может даже включать информацию о другом микросервисе, который он мог бы вызвать для выполнения части работы. В этой ситуации квитанция об отмене может содержать идентификатор учетной записи и, возможно, некоторую дополнительную информацию, необходимую для выполнения противоположной операции. В нашем случае, для упрощения, скажем, просто удалите учетную запись, используя ее идентификатор.
Теперь предположим, что веб-сервис никогда не получал успех (или неудачу) (в данном случае), что отмена создания учетной записи была выполнена. Он просто снова вызовет сервис отмены аккаунта. И этот сервис обычно не должен выходить из строя, поскольку его целью является отсутствие учетной записи. Таким образом, он проверяет, существует ли он, и видит, что ничего нельзя сделать, чтобы отменить его. Так что возвращается, что операция прошла успешно.
Веб-сервис возвращает пользователю, что учетная запись не может быть создана.
Это синхронный пример. Мы могли бы справиться с этим по-другому и поместить дело в очередь сообщений, предназначенную для службы поддержки, если мы не хотим, чтобы система полностью исправила ошибку ". Я видел, как это выполняется в компании, где недостаточно для серверной системы могут быть предоставлены хуки для исправления ситуаций. Служба поддержки получала сообщения, содержащие информацию о том, что было выполнено успешно, и имела достаточно информации для исправления таких вещей, которые можно было бы использовать для полной отмены получения квитанции об отмене.
Я выполнил поиск, и на веб-сайте Microsoft есть описание шаблона для этого подхода. Это называется моделью компенсирующей транзакции:
Компенсирующая схема транзакции