Українська
Завдання
Відповідно до номера свого варіанта виконайте завдання обраного рівня складності.
Варіанти
Варіант 1. Маркетплейс книжок
1. Початковий рівень. Створити рішення Aspire з двома вебсервісами маркетплейсу книжок: продавці (GET /sellers/{id}/offers – пропозиції продавця з цінами) і кошик (POST /cart/{user}/items з пропозицією, GET /cart/{user}), та шлюзом YARP, який через виявлення сервісів маршрутизує /api/sellers/** і /api/cart/**; перевірити запити до шлюзу командою curl і показати ресурси в дашборді Aspire.
2. Базовий рівень. Створити рішення Aspire маркетплейсу книжок із сервісами продавців (пропозиції з цінами й залишком у власній базі PostgreSQL) і кошика (Redis, час життя 7 днів). Під час додавання кошик перевіряє пропозицію й залишок у сервісі продавців, а GET /cart/{user} групує позиції за продавцями в таблицю «продавець – книга – кількість – ціна – сума» з підсумком; помилки введення дають код 400 з ProblemDetails, а зміна ціни продавцем позначається як «ціну змінено».
3. Високий рівень. Створити маркетплейс із сервісами кошика, продавців, замовлень і виплат: оформлення кошика розбиває замовлення на підзамовлення за продавцями, кожен продавець підтверджує чи відхиляє своє підзамовлення подією через RabbitMQ (Outbox та Inbox), а відхилене підзамовлення скасовується без скасування інших і зменшує суму до оплати; виплати продавцям нараховуються лише за підтверджені підзамовлення. Інтеграційні тести Aspire.Hosting.Testing перевіряють часткове підтвердження, а програма market-load з опціями --orders, --sellers, --reject-rate, --help виводить таблицю «продавець – підзамовлень – підтверджено – виплата»; розбіжність сум замовлень і виплат виводиться в потік помилок, коди завершення 0/1/2.
Варіант 2. Бронювання готелю
1. Початковий рівень. Створити рішення Aspire із сервісами номерів і бронювань: POST /bookings з номером кімнати й датами викликає сервіс номерів через виявлення сервісів, резервує номер і повертає номер бронювання або код 409, якщо номер на ці дати зайнятий; показати в дашборді трасування запиту через обидва сервіси.
2. Базовий рівень. Створити сервіси номерів, оплати й бронювань з оркестрованою сагою в сервісі бронювань: резерв номера → оплата → підтвердження; якщо оплату відхилено (сума понад ліміт або тестова картка «0000»), сага знімає резерв номера (компенсація). Стан саги зберігається в PostgreSQL, а GET /bookings/{id} повертає стан і журнал кроків у вигляді таблиці «крок – результат – час».
3. Високий рівень. Створити систему бронювання з сервісами бронювань (оркестратор саги), номерів, оплати й сповіщень, що обмінюються командами й відповідями через RabbitMQ з Outbox та Inbox у кожному сервісі; крок без відповіді за 10 с завершується тайм-аутом і компенсацією, а незавершені саги продовжуються після перезапуску оркестратора. Інтеграційні тести Aspire.Hosting.Testing перевіряють успіх, відмову оплати й тайм-аут; програма hotel-chaos з опціями --bookings, --fail-rate, --help виводить таблицю «результат – кількість – середній час» і перевіряє, що жоден номер не лишився зарезервованим без оплати (коди завершення 0/1/2).
Варіант 3. Доставка їжі
1. Початковий рівень. Створити рішення Aspire з RabbitMQ і сервісами замовлень та ресторану: POST /orders публікує подію OrderCreated, а ресторан отримує її й виводить у журнал страви та час отримання; показати в дашборді трасування від HTTP-запиту до обробки події.
2. Базовий рівень. Створити систему доставки їжі з хореографією без центрального координатора (RabbitMQ): сервіс замовлень публікує OrderCreated, ресторан – OrderAccepted або OrderRejected (страви немає в меню), сервіс кур’єрів призначає вільного кур’єра й публікує CourierAssigned, а сервіс замовлень оновлює стан за подіями. GET /orders/{id} повертає історію подій замовлення, відмова ресторану переводить замовлення у стан «скасовано».
3. Високий рівень. Створити систему доставки з чотирьох сервісів (замовлення, ресторан, кур’єри, оплата) з хореографічною сагою: якщо вільного кур’єра немає протягом 30 с, оплата повертає кошти, а ресторан скасовує приготування; усі сервіси мають Outbox та Inbox, уся сага видна в дашборді як одне трасування. Інтеграційні тести Aspire.Hosting.Testing перевіряють доставку й скасування; програма food-load з опціями --orders, --couriers, --help виводить таблицю «кур’єрів – доставлено – скасовано – середній час доставки».
Варіант 4. Кінотеатр
1. Початковий рівень. Створити сервіси сеансів і місць кінотеатру за шлюзом YARP у рішенні Aspire: GET /api/sessions повертає сеанси, POST /api/seats/{session}/{seat}/hold блокує місце, а повторне блокування того самого місця повертає код 409.
2. Базовий рівень. Створити сервіси сеансів, місць і оплати кінотеатру за шлюзом YARP, у яких тимчасові блокування місць зберігаються в Redis з часом життя (5 хв, для перевірки – 30 с): оплата перетворює блокування на продаж, а фоновий сервіс знімає прострочені блокування й публікує SeatReleased. Неіснуючий ряд чи місце дають код 400, а GET /api/sessions/{id}/map повертає текстову схему залу («.» вільне, «x» продане, «o» заблоковане).
3. Високий рівень. Створити систему продажу квитків з сервісами сеансів, місць, оплати й квитків і сагою «блокування → оплата → квиток» з компенсацією при тайм-ауті оплати та Outbox для подій; одночасні спроби купити одне місце мають рівно одного переможця. Інтеграційні тести перевіряють конкуренцію й тайм-аут, а програма cinema-rush з опціями --buyers, --seats, --help виводить таблицю «покупців – продано – конфліктів – подвійних продажів» (останнє значення має бути 0, інакше код завершення 1).
Варіант 5. Банківські перекази
1. Початковий рівень. Створити рішення Aspire із сервісом рахунків (PostgreSQL, EF Core) і сервісом переказів: POST /transfers з рахунками й сумою викликає списання та зарахування в сервісі рахунків і повертає новий баланс обох рахунків.
2. Базовий рівень. Створити рішення Aspire із сервісом рахунків (PostgreSQL) і сервісом ідемпотентних переказів: клієнт передає заголовок Idempotency-Key, оброблені ключі зберігаються в таблиці, повторний запит повертає той самий результат без повторного списання. Оркестратор переказу повертає списані кошти, якщо зарахування неможливе (рахунок заблоковано); некоректна сума, однакові рахунки й недостатній баланс дають код 400 або 409 з поясненням.
3. Високий рівень. Створити систему з чотирьох сервісів (оркестратор переказів, рахунки банку А, рахунки банку Б, аудит): команди й відповіді передаються через RabbitMQ з Outbox та Inbox, HTTP-виклики мають повтори й тайм-аути Microsoft.Extensions.Http.Resilience, аудит фіксує кожен крок саги. Інтеграційні тести перевіряють ідемпотентність і компенсацію, а програма bank-chaos з опціями --transfers, --kill-every, --help виконує перекази, періодично перезапускаючи сервіси, і виводить таблицю «переказів – успішних – компенсованих – сума до/після»; зміна загальної суми означає код завершення 1.
Варіант 6. Бібліотека
1. Початковий рівень. Створити сервіси книжкового фонду й читачів бібліотеки за шлюзом YARP: GET /api/books повертає книги з кількістю примірників, POST /api/readers реєструє читача; кожен сервіс має власну базу PostgreSQL.
2. Базовий рівень. Створити сервіси бібліотеки (фонд примірників, читачі, видача) з власними базами, у яких сервіс видачі має власну модель книги (ідентифікатор і назва, скопійовані з фонду). Видача перевіряє читача й наявність примірника, відхиляє понад 5 книг на читача й публікує BookIssued, за якою фонд зменшує кількість доступних примірників; GET /api/loans/overdue повертає таблицю боржників.
3. Високий рівень. Створити бібліотечну систему з сервісами фонду, читачів, видачі й нагадувань: фоновий сервіс знаходить прострочені видачі й публікує події, сервіс нагадувань «надсилає» листи в журнал, проєкція «читач – книги – термін» зберігається в Redis; усі події проходять через Outbox та Inbox. Програма library-sim з опціями --days, --readers, --help імітує прискорений час і виводить таблицю «день – видано – повернено – нагадувань»; інтеграційні тести перевіряють ліміт видачі й нагадування.
Варіант 7. Університетський розклад
1. Початковий рівень. Створити сервіси аудиторій і викладачів за шлюзом YARP: GET /api/rooms?capacity=N повертає аудиторії з місткістю не менше N, GET /api/teachers/{id}/busy повертає зайняті пари викладача.
2. Базовий рівень. Створити сервіс розкладу, який під час додавання заняття одночасно (Task.WhenAll) перевіряє в сервісах аудиторій, викладачів і груп вільність пари; конфлікт повертає код 409 з переліком причин, а GET /api/schedule/group/{id} повертає розклад групи на тиждень у вигляді таблиці «день – пара – дисципліна – аудиторія – викладач».
3. Високий рівень. Створити сервіси аудиторій, викладачів, груп і розкладу з сагою розміщення заняття: резерв аудиторії, викладача й групи з компенсацією вже зроблених резервів при відмові будь-якого кроку, Outbox для подій. Програма schedule-gen з опціями --csv, --help імпортує навантаження з CSV, розміщує заняття й виводить таблицю розміщених і нерозміщених занять з причинами; інтеграційні тести перевіряють, що одночасні запити на одну аудиторію не створюють накладок.
Варіант 8. Прокат автомобілів
1. Початковий рівень. Створити рішення Aspire із сервісами автопарку й прокату: POST /rentals перевіряє доступність автомобіля викликом автопарку й створює прокат або повертає код 409.
2. Базовий рівень. Створити сервіси автопарку й прокату автомобілів з Transactional Outbox у сервісі прокату: прокат і повідомлення CarRented записуються в одній транзакції EF Core, фоновий ретранслятор публікує повідомлення в RabbitMQ, а автопарк змінює статус автомобіля. Показати, що при зупиненому брокері події не губляться й доходять після його запуску; GET /outbox/stats повертає кількість неопублікованих повідомлень.
3. Високий рівень. Створити систему прокату з сервісами автопарку, прокату, оплати й повернень: сага «резерв → оплата → видача» з компенсацією, повернення розраховує штраф за запізнення й пробіг, споживачі мають Inbox. Інтеграційні тести зупиняють брокер під час роботи, а програма rental-chaos з опціями --rentals, --broker-downtime, --help виводить таблицю «надіслано – доставлено – відкинуто дублів – максимальна затримка».
Варіант 9. Онлайн-курси
1. Початковий рівень. Створити сервіси курсів і реєстрацій на курси в рішенні Aspire: POST /enrollments перевіряє існування курсу й вільні місця викликом сервісу курсів і реєструє студента.
2. Базовий рівень. Створити сервіси онлайн-курсів (курси, реєстрації, оплата) і сервіс «кабінет студента» як проєкцію CQRS: кабінет отримує події StudentEnrolled і PaymentCompleted та будує в Redis представлення «курс – статус – доступ»; доступ відкривається лише після оплати, а відповідь показує, скільки мілісекунд проєкція відставала від події.
3. Високий рівень. Створити платформу з чотирьох сервісів (курси, реєстрації, оплата, кабінет): події зберігаються в журналі, проєкцію кабінету можна перебудувати з нуля командою POST /admin/rebuild, події мають версію й читаються толерантно. Програма courses-load з опціями --students, --help виводить таблицю «реєстрацій – затримка проєкції медіана і 95-й процентиль»; інтеграційні тести перевіряють перебудову проєкції.
Варіант 10. Поліклініка
1. Початковий рівень. Створити сервіси лікарів і записів на прийом за шлюзом YARP: GET /api/doctors/{id}/slots повертає вільні слоти, POST /api/appointments записує пацієнта на слот.
2. Базовий рівень. Створити сервіси лікарів, записів на прийом і сповіщень поліклініки, у яких подвійний запис на слот запобігається оптимістичним блокуванням (токен паралельності EF Core для PostgreSQL): конфлікт повертає код 409, запис поза робочими годинами чи в минулому – код 400; успішний запис публікує подію, а сервіс сповіщень виводить повідомлення пацієнту в журнал.
3. Високий рівень. Створити систему поліклініки з сервісами лікарів, записів, сповіщень і нагадувань: скасування вивільняє слот подією, нагадування надсилаються за добу (у тесті – за хвилину), усі події проходять через Outbox та Inbox. Програма clinic-rush з опціями --patients, --slots, --help виконує одночасні записи й виводить таблицю «спроб – записано – конфліктів – подвійних записів»; інтеграційні тести перевіряють скасування й конфлікти.
Варіант 11. Склад і логістика
1. Початковий рівень. Створити сервіси замовлень і залишків з RabbitMQ у рішенні Aspire: подія OrderPlaced зменшує залишок товару, а GET /stock/{sku} повертає поточний залишок.
2. Базовий рівень. Створити сервіси замовлень, складу й звітності з RabbitMQ: склад реалізує резерв, зняття резерву й відвантаження товару, а звітність тримає власну копію залишків, оновлювану подіями. Показати тимчасову розбіжність даних і виміряти час узгодження; повторно доставлені події відкидати за ідентифікатором повідомлення.
3. Високий рівень. Створити логістичну систему з кількома складами: сага розподіляє замовлення між складами з компенсацією резервів при нестачі, сервіси мають Outbox та Inbox, звітність будує проєкцію. Програма stock-audit з опціями --url, --help звіряє залишки сервісів складу й звітності, виводить таблицю розбіжностей і повертає код 1 за їхньої наявності; навантажувальний режим --orders N вимірює час узгодження.
Варіант 12. Квитки на потяги
1. Початковий рівень. Створити сервіс розкладу потягів за шлюзом YARP у рішенні Aspire: GET /api/trains?from=Лондон&to=Париж повертає потяги з часом відправлення й вільними місцями.
2. Базовий рівень. Створити сервіс розкладу потягів (GET /api/trains?from=…&to=…) за шлюзом YARP з глобальним обмеженням частоти в шлюзі: ковзне вікно 100 запитів за секунду на маршрут /api/trains/** і окреме фіксоване вікно для кожної IP-адреси; перевищення повертає код 429 із заголовком Retry-After. Розклад кешується в Redis на 60 с, а подія ScheduleChanged з RabbitMQ очищує кеш потрібного маршруту.
3. Високий рівень. Створити систему з сервісами розкладу, місць і квитків, у якій кеш розкладу побудовано на HybridCache (пам’ять процесу й Redis) із захистом від лавини запитів: при закінченні терміну кешу лише один запит звертається до бази, а решта чекають. Програма train-load з опціями --rps, --seconds, --help виводить таблицю «запитів – 200 – 429 – влучань у кеш – звернень до бази – затримка 95-й процентиль» для кешу вимкненого, лише в Redis і гібридного; інтеграційні тести перевіряють інвалідацію кешу подією.
Варіант 13. Соціальна мережа
1. Початковий рівень. Створити сервіси користувачів і публікацій за шлюзом YARP: POST /api/posts створює публікацію автора, GET /api/users/{id}/posts повертає його публікації.
2. Базовий рівень. Створити сервіси соцмережі (користувачі, публікації, стрічка), у яких сервіс стрічки підписаний на події PostPublished і UserFollowed та будує стрічку кожного користувача в Redis під час публікації (розсилання під час запису); лайки враховуються лічильником, GET /api/feed/{user}?page=N повертає сторінку стрічки з кількістю лайків.
3. Високий рівень. Створити соцмережу з сервісами користувачів, публікацій, стрічки й лайків з Outbox для подій: видалення публікації прибирає її зі стрічок, стрічку можна будувати під час запису або під час читання (параметр конфігурації). Програма feed-load з опціями --users, --followers, --help виводить таблицю порівняння двох способів за часом публікації, часом читання й обсягом Redis; інтеграційні тести перевіряють видалення.
Варіант 14. Туристичні тури
1. Початковий рівень. Створити сервіси перельотів і готелів та сервіс турів у рішенні Aspire: POST /tours послідовно бронює переліт і готель через виявлення сервісів і повертає підсумкову вартість туру.
2. Базовий рівень. Створити сервіси перельотів, готелів і екскурсій та сервіс турів з оркестрованою сагою: переліт → готель → екскурсії; при відмові будь-якого кроку виконуються компенсації у зворотному порядку. Стан саги зберігається в PostgreSQL, а GET /tours/{id} повертає таблицю «крок – дія – компенсація – стан».
3. Високий рівень. Створити систему турів з оркестратором саги як скінченним автоматом і сервісами перельотів, готелів, екскурсій та оплати: тайм-аути кроків, повторювані й неповторювані помилки, крок оплати як точка неповернення, після якої компенсації не виконуються, а кроки лише повторюються. Інтеграційні тести моделюють відмову кожного кроку, а програма tour-chaos з опціями --tours, --fail-step, --help виводить таблицю результатів і перевіряє відсутність «напівзаброньованих» турів.
Варіант 15. Спортзал
1. Початковий рівень. Створити сервіси абонементів і відвідувань за шлюзом YARP: відвідування POST /api/visits перевіряє в сервісі абонементів, що абонемент чинний.
2. Базовий рівень. Створити сервіси абонементів і відвідувань спортзалу за шлюзом YARP з версіонуванням API абонементів: /v1/memberships повертає дату закінчення, а /v2/memberships – також дні заморожування й залишок відвідувань; шлюз маршрутизує обидві версії, старий клієнт продовжує працювати, а відповідь v1 має заголовок про застарілість.
3. Високий рівень. Створити систему спортзалу з сервісами абонементів, відвідувань і платежів, де подія MembershipCreated має версії 1 і 2, а споживачі читають обидві (толерантний читач, перетворення старих подій). Програма gym-compat з опціями --old, --new, --help перевіряє сумісність двох версій контрактів і виводить таблицю змін з позначкою «сумісна/несумісна»; інтеграційні тести перевіряють роботу старого клієнта.
Варіант 16. Ремонтна служба
1. Початковий рівень. Створити сервіси заявок і майстрів у рішенні Aspire: POST /requests з типом ремонту призначає вільного майстра відповідної спеціалізації або повертає код 409.
2. Базовий рівень. Створити сервіси ремонтної служби (майстри, запчастини) і оркестратор заявки: призначення вільного майстра відповідної спеціалізації → резерв запчастин → підтвердження клієнту; відсутність запчастин знімає призначення майстра (компенсація); GET /requests/{id} повертає журнал кроків таблицею.
3. Високий рівень. Створити ремонтну службу з сервісами заявок (оркестратор), майстрів, запчастин і розрахунків, що обмінюються командами через RabbitMQ з Outbox та Inbox, з трасуванням усієї заявки в дашборді. Програма repair-sim з опціями --requests, --masters, --help виводить таблицю «виконано – скасовано – середній час – завантаження майстрів»; інтеграційні тести перевіряють компенсацію.
Варіант 17. Міський транспорт
1. Початковий рівень. Створити сервіси транспортних карток і поповнення: POST /topups з номером картки й сумою викликає сервіс карток і повертає новий баланс.
2. Базовий рівень. Створити сервіс транспортних карток (баланс, поповнення) і консольні валідатори, що надсилають проїзди подіями через RabbitMQ; списання ідемпотентне за ідентифікатором проїзду, недостатній баланс публікує подію відмови, а валідатор без зв’язку з брокером накопичує проїзди в локальному буфері й надсилає їх пізніше.
3. Високий рівень. Створити систему з сервісами карток, поповнень, проїздів і звітів (проєкція в PostgreSQL); програма validator-sim з опціями --validators, --minutes, --offline, --help імітує валідатори з періодами без зв’язку, а потім звіряє баланси й виводить таблицю «проїздів – списано – відмов – дублів відкинуто».
Варіант 18. Аукціон
1. Початковий рівень. Створити сервіси лотів і ставок за шлюзом YARP: ставка POST /api/bids перевіряє в сервісі лотів, що лот відкритий, і повертає поточну найвищу ставку.
2. Базовий рівень. Створити сервіси лотів і ставок аукціону за шлюзом YARP з фоновим сервісом завершення лотів за часом (подія AuctionClosed); ставка, не більша за поточну, або ставка на закритий лот відхиляється з кодом 409, а одночасні ставки не втрачаються (оптимістичне блокування); GET /api/lots/{id} повертає історію ставок таблицею.
3. Високий рівень. Створити аукціон з сервісами лотів, ставок, оплати й сповіщень: сага оплати переможцем передає лот наступному учаснику, якщо переможець не оплатив за відведений час; події проходять через Outbox та Inbox. Програма auction-bots з опціями --bots, --seconds, --help виводить таблицю лотів з переможцями й перевіряє, що виграшна ставка максимальна; інтеграційні тести перевіряють неоплату.
Варіант 19. Система голосування
1. Початковий рівень. Створити сервіси виборців і голосування: POST /votes перевіряє право виборця викликом сервісу виборців і зараховує голос за кандидата.
2. Базовий рівень. Створити сервіси виборців, голосування, підрахунку й аудиту з ідемпотентними голосами: повторний голос того самого виборця й повторна доставка події не змінюють результат; підрахунок отримує події через RabbitMQ, аудит записує кожен голос, а GET /results повертає таблицю «кандидат – голоси – відсоток».
3. Високий рівень. Створити систему голосування з сервісами виборців, голосування, підрахунку й аудиту: аудит зберігає записи ланцюжком хешів SHA-256, а GET /audit/verify перевіряє цілісність. Програма vote-chaos з опціями --voters, --duplicates, --help надсилає голоси з дублями й перезапускає підрахунок, а потім порівнює результати підрахунку й аудиту (невідповідність – код завершення 1).
Варіант 20. Інтернет-провайдер
1. Початковий рівень. Створити сервіси тарифів і абонентів за шлюзом YARP: GET /api/subscribers/{id} повертає абонента разом із назвою й ціною тарифу, отриманими із сервісу тарифів.
2. Базовий рівень. Створити сервіси абонентів, рахунків і доступу інтернет-провайдера: сервіс рахунків щомісяця (у тесті – щохвилини) нараховує плату й публікує InvoiceOverdue для неоплачених рахунків, сервіс доступу блокує такого абонента, а оплата публікує InvoicePaid і розблоковує його.
3. Високий рівень. Створити систему провайдера з сервісами тарифів, абонентів, рахунків і доступу, сагою зміни тарифу з перерахунком і компенсацією, Outbox та Inbox. Програма isp-sim з опціями --months, --subscribers, --help імітує оплати й виводить таблицю «місяць – нараховано – сплачено – заблоковано»; інтеграційні тести перевіряють блокування й розблокування.
Варіант 21. Благодійний фонд
1. Початковий рівень. Створити сервіси зборів і пожертв з RabbitMQ: пожертва POST /donations публікує подію, за якою сервіс зборів збільшує зібрану суму.
2. Базовий рівень. Створити сервіси пожертв і зборів благодійного фонду з RabbitMQ: пожертва збільшує зібрану суму збору; реалізувати Transactional Outbox у сервісі пожертв та Inbox у сервісі зборів і показати, що подія доставляється щонайменше один раз, а дублікат не збільшує суму; GET /campaigns/{id} повертає ціль, зібрану суму й відсоток виконання.
3. Високий рівень. Створити фонд із сервісами зборів, пожертв, звітів і повернень: збір закривається при досягненні цілі, надлишок повертається донору (компенсація). Програма charity-chaos з опціями --donations, --restarts, --help перезапускає споживача під час обробки й виводить таблицю «пожертв – подій – дублів відкинуто – сума збігається»; інтеграційні тести перевіряють закриття збору.
Варіант 22. Мережа кав’ярень
1. Початковий рівень. Створити сервіси меню й замовлень мережі кав’ярень у рішенні Aspire: POST /orders отримує ціни напоїв із сервісу меню й повертає суму замовлення.
2. Базовий рівень. Створити сервіси меню, замовлень і бонусів мережі кав’ярень, де виклик бонусів має тайм-аут 500 мс і два повтори (Microsoft.Extensions.Http.Resilience); при недоступності бонусів замовлення приймається без знижки з позначкою «бонуси буде нараховано пізніше», а команда нарахування потрапляє в чергу RabbitMQ і виконується після відновлення сервісу (деградація функцій замість відмови).
3. Високий рівень. Створити систему кав’ярень із сервісами меню, замовлень, бонусів, складу й рекомендацій, де кожна необов’язкова функція (бонуси, рекомендації, перевірка складу) вимикається перемикачем функцій у конфігурації або автоматично при відмові, а відповідь замовлення містить перелік вимкнених функцій. Програма coffee-chaos з опціями --scenario, --seconds, --help зупиняє по черзі сервіси й виводить таблицю «сценарій – успішних – деградованих – помилок – затримка 95-й процентиль»; інтеграційні тести перевіряють, що після відновлення всі відкладені бонуси нараховано.
Варіант 23. Служба таксі
1. Початковий рівень. Створити сервіси поїздок і водіїв: POST /rides з координатами пасажира викликає сервіс водіїв і призначає найближчого вільного водія.
2. Базовий рівень. Створити сервіси таксі: поїздок, водіїв (призначення найближчого вільного водія), розрахунку вартості з інтерфейсом gRPC і подію RideCompleted через RabbitMQ; налаштувати OpenTelemetry так, щоб одна поїздка була одним трасуванням через HTTP, gRPC і RabbitMQ, та додати власні спани (ActivitySource) з атрибутами водія й відстані.
3. Високий рівень. Створити службу таксі з сервісами поїздок, водіїв, тарифів і розрахунків, власними метриками (лічильник поїздок, гістограма часу призначення) і навмисною затримкою в одному із сервісів. Програма taxi-load з опціями --rides, --tasks, --help створює навантаження, а звіт за даними дашборду Aspire визначає найповільніший етап і містить таблицю «етап – середній час – частка від загального».
Варіант 24. Електронна черга
1. Початковий рівень. Створити сервіси талонів і вікон обслуговування за шлюзом YARP: POST /api/tickets видає талон з номером, POST /api/windows/{id}/next викликає наступний талон.
2. Базовий рівень. Створити сервіси талонів і вікон електронної черги з атомарним викликом наступного талона (FOR UPDATE SKIP LOCKED у PostgreSQL), щоб два вікна не отримали той самий талон; виклик публікує подію для табло, а GET /api/stats повертає таблицю «послуга – у черзі – обслуговано – середнє очікування».
3. Високий рівень. Створити систему черги з сервісами талонів, вікон, табло й статистики (проєкція подій у Redis). Програма queue-sim з опціями --clients, --windows, --help імітує відвідувачів і вікна та виводить таблицю очікування для різної кількості вікон; інтеграційні тести перевіряють, що жоден талон не викликано двічі.
Варіант 25. Інтернет-аптека
1. Початковий рівень. Створити сервіси каталогу ліків і рецептів за шлюзом YARP: GET /api/drugs?name= шукає ліки, GET /api/prescriptions/{id} повертає рецепт.
2. Базовий рівень. Створити сервіс замовлень, який перевіряє вхідні дані (кількість, адреса) і дозволяє рецептурні ліки лише з чинним рецептом із сервісу рецептів; помилки повертаються як ValidationProblemDetails, а кожен сервіс публікує документ OpenAPI.
3. Високий рівень. Створити аптеку з сервісами каталогу, рецептів, замовлень і доставки та сагою «резерв → оплата → доставка». Програма contract-check з опціями --old, --new, --help порівнює два документи OpenAPI, виводить таблицю змін з позначкою «сумісна/несумісна» й повертає код 1 при несумісних змінах; контрактні тести перевіряють схеми подій.
Варіант 26. Спортивні події
1. Початковий рівень. Створити сервіси подій і квитків за шлюзом YARP: POST /api/tickets перевіряє в сервісі подій наявність місць і продає квиток.
2. Базовий рівень. Створити сервіси подій і продажу квитків за шлюзом YARP та сервіс оплати з налаштовуваною затримкою й часткою відмов, виклики до якого мають повтори й запобіжник; зміни стану запобіжника (відкритий, напіввідкритий, закритий) записуються в журнал, а при відкритому запобіжнику продаж одразу повертає код 503.
3. Високий рівень. Створити систему продажу квитків з обмеженням частоти в шлюзі, ізоляцією (bulkhead) викликів оплати й чергою очікування покупців. Програма ticket-storm з опціями --buyers, --seconds, --help імітує старт продажу й виводить таблицю «секунда – запитів – продано – 429 – 503 – затримка 95-й процентиль»; інтеграційні тести перевіряють, що квитків не продано більше, ніж місць.
Варіант 27. Ветеринарна клініка
1. Початковий рівень. Створити сервіси власників з тваринами та записів на прийом у рішенні Aspire: запис перевіряє існування тварини й повертає номер запису.
2. Базовий рівень. Створити сервіси ветеринарної клініки (тварини, записи, щеплення, нагадування): після прийому подія VaccinationDone фіксує щеплення й обчислює дату наступного, сервіс нагадувань виводить нагадування в журнал; GET /pets/{id}/card повертає картку тварини зі щепленнями таблицею.
3. Високий рівень. Створити клініку з сервісами власників, записів, щеплень і нагадувань з Outbox та Inbox, перевірками працездатності /health і /alive для кожного сервісу. Програма vet-sim з опціями --pets, --days, --help імітує прийоми й виводить таблицю нагадувань за днями; інтеграційні тести перевіряють нагадування.
Варіант 28. Коворкінг
1. Початковий рівень. Створити сервіси переговорних кімнат і учасників коворкінгу: POST /meetings на кімнату й годину перевіряє, що учасник має чинне членство, а кімната вільна, і повертає номер зустрічі.
2. Базовий рівень. Створити сервіси кімнат, учасників (пакет годин) і зустрічей коворкінгу з хореографією подій: MeetingRequested → RoomHeld → HoursDebited → MeetingConfirmed; недостатній залишок годин публікує HoursRejected, після чого кімната звільняється; GET /meetings/{id} повертає ланцюжок отриманих подій із часом.
3. Високий рівень. Створити коворкінг із сервісами кімнат, учасників, зустрічей і доступу (видає шестизначний код дверей на час зустрічі й анулює його після скасування) з Outbox та Inbox; скасування зустрічі за годину до початку повертає години, пізніше – ні. Програма cowork-load з опціями --members, --meetings, --help виводить таблицю «зустрічей – підтверджено – відхилено – завислих» (завислих має бути 0); інтеграційні тести перевіряють повернення годин і анулювання коду.
Варіант 29. Міграція моноліту
1. Початковий рівень. Створити моноліт ASP.NET Core з модулями замовлень і звітів та шлюз YARP перед ним, який передає всі запити моноліту; перевірити, що клієнт працює через шлюз без змін.
2. Базовий рівень. Створити моноліт ASP.NET Core з модулями замовлень і звітів за шлюзом YARP і виділити модуль звітів в окремий сервіс з власною базою PostgreSQL: моноліт публікує зміни замовлень через Outbox, сервіс звітів будує свої дані з подій, а шлюз спрямовує /reports на новий сервіс (патерн strangler fig); порівняти відповіді старого й нового звіту.
3. Високий рівень. Створити моноліт ASP.NET Core із замовленнями й звітами, окремий сервіс звітів (дані з подій моноліту) і шлюз YARP, що спрямовує 10, 50 і 100 % запитів звітів на новий сервіс, а в тіньовому режимі надсилає копію запиту в обидві системи. Програма strangler-check з опціями --url, --requests, --help порівнює відповіді й виводить таблицю «частка – запитів – розбіжностей – затримка»; показати відкат на моноліт зміною конфігурації шлюзу.
Варіант 30. Хаос-тестування
1. Початковий рівень. Створити два сервіси за шлюзом YARP у рішенні Aspire з перевірками працездатності /health і /alive; зупинити один сервіс у дашборді й показати зміну його стану та відповіді шлюзу.
2. Базовий рівень. Створити два сервіси за шлюзом YARP у рішенні Aspire з повторами, тайм-аутами й запобіжником між ними та консольну програму, яка щосекунди викликає шлюз, а під час зупинки контейнера сервісу (docker stop) виводить кількість успішних і невдалих запитів та час відновлення після запуску.
3. Високий рівень. Створити програму chaos-runner з опціями --scenario kill|latency|broker-down, --seconds, --help, яка вносить збої в систему з трьох сервісів і RabbitMQ (зупинка контейнера, затримка через проміжне ПЗ, зупинка брокера) й виводить таблицю «сценарій – доступність, % – час відновлення – помилок – затримка 95-й процентиль»; порушення цілі 99 % доступності дає код завершення 1.
Порядок виконання та захисту роботи
- Опрацювати теоретичні відомості та приклади розв’язання завдань.
- Перевірити інструменти:
dotnet --version(.NET SDK 10),aspire --version,docker version; запустити Docker Desktop. - Для свого варіанта виконати декомпозицію: визначити обмежені контексти й сервіси, дані кожного сервісу, синхронні виклики й події, кроки саги та компенсувальні дії; накреслити схему (сервіси, бази, брокер, шлюз).
- Створити в JetBrains Rider рішення Aspire (AppHost, ServiceDefaults і сервіси), реалізувати сервіси, шлюз YARP і обмін подіями через RabbitMQ; для кожного сервісу – власна база або сховище.
- Перевірити основний сценарій і сценарії відмов: відмову бізнес-правила (компенсація), зупинку сервісу чи брокера (
aspire resource … stop,docker stop), повторні запити й дублікати повідомлень; у дашборді Aspire знайти трасування сценарію й порахувати спани. - Виміряти показники (затримку, частку успішних відповідей, час відновлення) і звести їх у таблицю; для високого рівня – написати інтеграційний тест з
Aspire.Hosting.Testing. - Після роботи зупинити застосунок (
aspire stop) і переконатися, що контейнери видалено (docker ps -a). - Продемонструвати роботу викладачеві, пояснити архітектуру, код і результати та відповісти на контрольні питання.