Це класичне запитання, яке мені задали нещодавно під час інтерв'ю Як зателефонувати на декілька веб-сервісів і як і раніше зберігати якусь обробку помилок посеред завдання. Сьогодні, використовуючи високоефективні обчислення, ми уникаємо двох фазних комітетів. Я багато років тому читав статтю про те, що називалося "модель Starbuck" для транзакцій. Подумайте про процес замовлення, оплати, приготування та отримання кави, яку ви замовляєте в Starbuck ... Я спрощую речі, але двофазова модель фіксації буде припустимо, що весь процес буде однією транзакцією для обгортання всіх кроків, поки ви не отримаєте каву. Однак із цією моделлю всі співробітники зачекали б і перестали працювати, поки не отримаєте свою каву. Ви бачите картину?
Натомість "модель Starbuck" є більш продуктивною, дотримуючись моделі "найкращих зусиль" та компенсуючи помилки в процесі. По-перше, вони впевнені, що ви платите! Потім з'являються черги з повідомленнями з вашим замовленням, доданим до чашки. Якщо в процесі щось піде не так, як, наприклад, ви не отримали кави, це не те, що ви замовили тощо. Ми вступаємо в процес компенсації і ми гарантуємо, що ви отримаєте те, що хочете, або повернемо вам гроші. Це найефективніша модель для підвищення продуктивності праці.
Іноді, Starbuck витрачає каву, але загальний процес ефективний. Є й інші хитрощі, коли потрібно будувати веб-сервіси, як-от спроектувати їх таким чином, щоб їх можна було викликати будь-яку кількість разів і все-таки забезпечити той самий кінцевий результат. Отже, моя рекомендація:
Не будьте надто чіткими, визначаючи свої веб-сервіси (я не переконаний у тому, що в цей час відбувається мікросхема мікроелементів: занадто багато ризиків зайти занадто далеко);
Async підвищує продуктивність, тому віддайте перевагу асинхронізації, надсилайте сповіщення електронною поштою, коли це можливо.
Створіть більш інтелектуальні сервіси, щоб зробити їх "повторними" в будь-якій кількості разів, обробляючи uid або taskid, які дотримуватимуться порядку замовлення до кінця, перевіряючи ділові правила на кожному кроці;
Використовуйте черги повідомлень (JMS або інші) та перейдіть до процесорів обробки помилок, які застосовуватимуть операції до "відкату", застосовуючи протилежні операції, до речі, робота з порядком асинхронізації потребує певної черги для перевірки поточного стану процесу, тому вважайте це;
В крайньому випадку (оскільки це може траплятися не часто), поставте його в чергу для ручної обробки помилок.
Повернемося до початкової проблеми, яка була опублікована. Створіть обліковий запис і створіть гаманець і переконайтесь, що все зроблено.
Скажімо, веб-сервіс покликаний організувати всю операцію.
Псевдо-код веб-служби виглядатиме так:
Зателефонуйте до мікросервісу створення облікового запису, передайте йому певну інформацію та якийсь унікальний ідентифікатор завдання 1.1. Мікросервіс створення облікового запису спочатку перевірить, чи цей обліковий запис вже створений. Ідентифікатор завдання пов’язаний із записом облікового запису. Мікросервіс виявляє, що обліковий запис не існує, тому він створює його і зберігає ідентифікатор завдання. ПРИМІТКА: цю послугу можна викликати 2000 разів, вона завжди матиме однаковий результат. Сервіс відповідає "квитанцією, яка містить мінімальну інформацію для виконання скасування операції, якщо потрібно".
Виклик створення Wallet, надавши йому ідентифікатор облікового запису та ідентифікатор завдання. Скажімо, умова недійсна, і створення гаманця неможливо виконати. Виклик повертається з помилкою, але нічого не створено.
Оркестрові повідомляється про помилку. Він знає, що йому потрібно припинити створення облікового запису, але він не зробить це сам. Він попросить службу гаманця зробити це, передавши її "мінімальну розписку квитанції", отриману в кінці кроку 1.
Служба рахунків читає квитанцію про скасування і знає, як скасувати операцію; квитанція про скасування може навіть включати інформацію про інший мікросервіс, який він міг би закликати виконувати частину роботи. У цій ситуації квитанція про скасування може містити ідентифікатор облікового запису та, можливо, додаткову інформацію, необхідну для здійснення протилежної операції. У нашому випадку для спрощення речей скажімо, просто видаліть обліковий запис, використовуючи його ідентифікатор облікового запису.
Скажімо, веб-сервіс ніколи не отримував успіху чи невдачі (в даному випадку) відміни створення облікового запису. Він просто знову зателефонує до послуги скасування послуги. І ця послуга, як правило, ніколи не виходить з ладу, оскільки її мета полягає в тому, щоб обліковий запис більше не існував. Тож він перевіряє, чи існує, і не бачить нічого, щоб його скасувати. Тож повертається, що операція є успішною.
Веб-сервіс повертається користувачеві, що обліковий запис неможливо було створити.
Це синхронний приклад. Ми могли б управляти цим по-іншому і помістити справу в чергу повідомлень, спрямовану на службу довідки, якщо ми не хочемо, щоб система повністю відновила помилку ". Я бачив, як це виконується в компанії, де недостатньо для виправлення ситуацій можуть бути надані гачки до системи зворотного зв'язку. Довідкова служба отримала повідомлення, що містять те, що було успішно виконано та мали достатньо інформації, щоб виправити такі речі, як наша квитанція про скасування може бути використана повністю автоматизованим способом.
Я здійснив пошук, і на веб-сайті microsoft є опис шаблону для цього підходу. Він називається компенсаційною схемою транзакцій:
Компенсаційна схема транзакцій