ЛЕКЦІЯ 21. ПРОМІЖНЕ ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ
План
21.1. Поняття проміжного програмного забезпечення
21.2. Виклики віддалених процедур.
21.2.1. Концепція віддаленого виклику процедур
21.2.2. Базові операції RPC
21.2.3. Етапи виконання RPC
21.2.4. Семантика RPCв разі відмов
21.3. Брокери об'єктних запитів.
21.4. Монітори оброблення транзакцій.
21.5. Вибір застосування, сервісів, компонентів і протоколів зв'язку.
21.1. Поняття проміжного програмного забезпечення
Важливу роль у створенні кросплатформних програмних систем відіграють додаткові загальносистемні програмні засоби, які вирішують завдання взаємодії та інтеграції компонентів. Ці засоби розміщуються між рівнем операційної системи (ОС) і рівнем прикладного програмного забезпечення і входять до складу так званого проміжного рівня (middleware). (рис. 21.1).
Рис. 21.1. Загальна структура системи з проміжним рівнем.
Проміжні́ програ́мні за́соби — це програмні засоби, що пов'язують програмні компоненти або прикладні програми.
Програмні засоби складаються з набору послуг, що дозволяють декільком процесам, запущених на одній або декількох машинах взаємодіяти через мережу. Ця технологія забезпечує взаємодію при переході до розподілених архітектур, які використовуються найчастіше для підтримки та спрощення складних, розподілених прикладних програм. До проміжних програмних засобів відносять веб-сервери, сервери застосувань та інші аналогічні інструменти, які підтримують розробку та впровадження програм. Проміжні програмні засоби є невід'ємною частиною сучасних інформаційних технологій, заснованих на XML, SOAP, та сервісно-орієнтованій архітектурі.
Такі програмні засоби знаходяться між прикладними програмами, що працюють на різних операційних системах. Вони схожі на середній шар трирівневої архітектури, що знаходиться на одній системі, за винятком того, що вона розтягується на кілька систем або програм. Прикладами можуть бути бази даних, телекомунікаційні програмні засоби, монітори транзакцій, а також програмні засоби повідомлень і черг.
Відмінність між системними і проміжними програмними засобами, не дуже чітка. Якщо основна функціональність ядра надається самою операційною системою, то деякі функції, що раніше надавалися лише окремим проміжними програмними засобами тепер інтегровані в операційні системи. Типовим прикладом є стек TCP/IP в телекомунікаціях, який сьогодні включено практично у всі операційні системи.
Компоненти, які входять до складу проміжного ПЗ вирішують такі завдання:
– забезпечення єдиного і незалежного від операційної системи механізму використання одними програмними компонентами сервісів інших компонентів;
– забезпечення безпеки розподіленої системи: аутентифікація і авторизація всіх користувачів сервісів компоненти і захист інформації, яка передається між компонентами від спотворення і читання третіми сторонами;
– забезпечення цілісності даних: управління транзакціями, розподіленими між віддаленими компонентами системами;
– балансування навантаження на сервери з програмними компонентами;
– знаходження віддалених компонент.
В межах однієї розподіленої системи може використовуватися декілька видів проміжних середовищ (рис. 21.2.). При хорошому підході до проектування системи кожна розподілена її компонента надає свої сервіси за допомогою єдиного проміжного середовища, і використовує служби інших компонентів за допомогою так само єдиного проміжного середовища, проте ці середовища можуть бути різними (гетерогенними).
Рис. 21.2. Гетерогенна розподілена система
Розподілену систему, компоненти якої використовують декілька проміжних середовищ, можна називати гетерогенною, в протилежність гомогенній, яка використовує єдине проміжне середовище.
Взаємодія програмних компонент в межах одного і того ж комп'ютера також відбувається за допомогою проміжного середовища, що при використанні деяких проміжних середовищ може бути як незручно, так і неефективно. У ідеальному випадку розподілена компонента має бути реалізована так, щоб перехід з одного проміжного середовища на інше відбувався шляхом зміни конфігурації програмної компоненти, а не зміни вихідного коду.
Завдання цього ПЗ, як відомо, і полягає в зв'язуванні програмних застосувань для обміну даними.
Еволюція проміжного програмного забезпечення - це шлях від програм передачі інформації між конкретними застосуваннями, через засоби імпорту- експорту даних і організацію мостів між деякими застосуваннями, через SQL, RPC (Remote Procedure Call), TP монітори (Transaction Proceesing) обробки транзакцій, Groupware - управління різними неструктурованими даними (тексти, факси, листи електронної пошти, календарі і так далі) і, нарешті, MOM - Message-Oriented Middleware (асинхронний обмін повідомленнями між сервером і клієнтом), до створення розподілених комп'ютерних систем. Елементи цих систем можуть взаємодіяти один з одним як на одній локальній машині, так і по мережі. CORBA дозволяє організувати єдине інформаційне середовище, елементи якого можуть спілкуватися один з одним, незалежно від їх конкретної реалізації, "прописки" в розподіленій системі, платформи і мови їх реалізації.
21.2. Виклики віддалених процедур
Виклик віддалених процедур (англ. Remote procedure call, RPC) — протокол, що дозволяє програмі, запущеній на одному комп'ютері бути викликаною на іншому комп'ютері без написання безпосередньо коду для цієї операції.
21.2.1. Концепція виклику віддалених процедур
Ідея виклику віддалених процедур (Remote Procedure Call — RPC) полягає у розширенні добре відомого і зрозумілого механізму передачі управління і даних усередині програми, що виконується на одній машині, на передачу керування й даних через мережу. Засоби віддаленого виклику процедур призначені для полегшення організації розподілених обчислень. Найбільша ефективність використання RPC досягається в тих програмах, в яких існує інтерактивний зв'язок між віддаленими компонентами з невеликим часом відповідей і відносно малою кількістю переданих даних. Такі програми називаються RPC-орієнтованими.
Існують цілий ряд технологій, що забезпечують RPC:
- Sun RPC (бінарний протокол на базі TCP та UDP)
- Net Remoting (бінарний протокол на базі TCP, UDP, HTTP)
- XML-RPC (текстовий протокол на базі HTTP)
- SOAP — Simple Object Access Protocol (текстовий протокол на базі HTTP)
- Java RMI — Java Remote Method Invocation
- JSON-RPC JavaScript Object Remote Procedure Calls (текстовий, на базі HTTP).
Характерними рисами виклику локальних процедур є:
• Асиметричність, тобто одна з взаємодіючих сторін є ініціатором;
• Синхронність, тобто виконання викликаючої процедури призупиняється з моменту видачі запиту і відновлюється тільки після повернення з визваної процедури.
Реалізація віддалених викликів істотно складніше реалізації викликів локальних процедур. Почнемо з того, що оскільки викликаюча і викликана процедури виконуються на різних машинах, то вони мають різні адресні простори, і це створює проблеми при передачі параметрів і результатів, особливо якщо машини не ідентичні. Так як RPC не може розраховувати на розподілену пам'ять, то це означає, що параметри RPC не повинні містити покажчиків на комірки нестековой пам'яті і що значення параметрів повинні копіюватися з одного комп'ютера на інший.
Але в реалізації RPC беруть участь як мінімум два процеси — по одному в кожній машині. У випадку, якщо один з них аварійно завершиться, можуть виникнути такі ситуації: при аварії викликаючої процедури віддалено викликані процедури стануть «осиротілими», а при аварійному завершенні віддалених процедур стануть «знедоленими батьками» викликаючі процедури, які будуть безрезультатно чекати відповіді від віддалених процедур.
Крім того, існує ряд проблем, пов'язаних з неоднорідністю мов програмування та операційних середовищ: структури даних і структури виклику процедур, підтримувані в будь-якому однією мовою програмування, не підтримуються точно так само у всіх інших мовах.
Ці та деякі інші проблеми вирішує широко поширена технологія RPC, що лежить в основі багатьох розподілених операційних систем.
21.3.3. Базові операції RPC
Щоб зрозуміти роботу RPC, розглянемо спочатку виконання виклику локальної процедури у звичайній машині, що працює автономно. Нехай це, наприклад, буде системний виклик: count = read (fd, buf, nbytes); де fd — ціле число, buf — масив символів, nbytes — ціле число.
Щоб здійснити виклик, викликаюча процедура заштовхує параметри в стек у зворотному порядку. Після того, як виклик read виконаний, він поміщає значення, що повертається в регістр, переміщує адресу повернення і повертає управління викликаючій процедурі, яка вибирає параметри з стека, повертаючи його в початковий стан. Зауважимо, що в мові С параметри можуть викликатися або за посиланнюм (by name), або за значенням (by value). По відношенню до викликаючої процедури параметри-значення є ініціалізованими локальними змінними. Викликана процедура може змінити їх, і це не вплине на значення оригіналів цих змінних в викликаючій процедурі. Якщо в визвану процедуру передається покажчик на змінну, то зміна значення цієї змінної визваної процедури тягне зміну значення цієї змінної і для викликаючої процедури. Цей факт дуже істотний для RPC.
Існує також інший механізм передачі параметрів, який не використовується в мові С. Він називається call-by-copy/restore і полягає в необхідності копіювання викликаючою програмою змінних в стек у вигляді значень, а потім копіювання назад після виконання виклику поверх оригінальних значень викликаючої процедури.
Рішення про те, який механізм передачі параметрів використовувати, приймається розробниками мови. Іноді це залежить від типу переданих даних. У мові С, наприклад, цілі та інші скалярні дані завжди передаються за значенням, а масиви — за посиланнюм.
Ідея, покладена в основу RPC, полягає в тому, щоб зробити виклик віддаленої процедури по можливості схожим до виклику локальної процедури. Іншими словами — зробити RPC прозорим: викликаючій процедурі не потрібно знати, що викликається процедура знаходиться на іншій машині, і навпаки.
RPC досягає прозорості наступним шляхом. Коли викликана процедура дійсно є віддалена, в бібліотеку поміщається замість локальної процедури інша версія процедури, яка називається клієнтським стабом (stub — заглушка). Подібно оригінальної процедурі, стаб викликається з використанням викликаючої послідовності, так само відбувається переривання при зверненні до ядра. Тільки на відміну від оригінальної процедури він не поміщає параметри в регістри і не запитує у ядра дані, замість цього він формує повідомлення для відправки ядру віддаленої машини.
21.2.3. Етапи виконання RPC
Взаємодія програмних компонентів при виконанні віддаленого виклику процедури здійснюється наступним чином. Після того, як клієнтський стаб був викликаний програмою-клієнтом, його першим завданням є заповнення буфера відправлені повідомленням. У деяких системах клієнтський стаб має єдиний буфер фіксованої довжини, що заповнюється щоразу з самого початку при вступі кожного нового запиту. В інших системах буфер повідомлення являє собою пул буферів для окремих полів повідомлення, причому деякі з цих буферів вже заповнені. Цей метод особливо підходить для тих випадків, коли пакет має формат, що складається з великої кількості полів, але значення багатьох з цих полів не змінюються від виклику до виклику.
Потім параметри повинні бути перетворені у відповідний формат і вставлені в буфер повідомлення. До цього моменту повідомлення готове до передачі, тому виконується переривання за викликом ядра.
Коли ядро отримує управління, воно перемикає контексти, зберігає регістри процесора і карту пам'яті (дескриптори сторінок), встановлює нову карту пам'яті, яка буде використовуватися для роботи в режимі ядра. Оскільки контексти ядра і користувача розрізняються, ядро має точно скопіювати повідомлення в свій власний адресний простір, так, щоб мати до нього доступ, запам'ятати адресу призначення (а, можливо, і інші поля заголовка), а також воно має передати його мережевому інтерфейсу. На цьому завершується робота на клієнтській стороні. Включається таймер передачі, і ядро може або виконувати циклічне опитування наявності відповіді, або передати управління планувальником, який обере будь-який інший процес на виконання. У першому випадку прискорюється виконання запиту, але відсутнє мультипрограмування.
На стороні сервера біти, що надходять, поміщаються приймаючої апаратурою або у вбудований буфер, або в оперативну пам'ять. Коли вся інформація буде отримана, генерується переривання. Обробник переривання перевіряє правильність даних пакета і визначає, якому стабу слід їх передати. Якщо жоден із стабів не очікує цей пакет, обробник повинен або помістити його в буфер, або взагалі відмовитися від нього. Якщо є очікуючий стаб, то повідомлення копіюється йому. Нарешті, виконується переключення контекстів, в результаті чого відновлюються регістри і карта пам'яті, приймаючи ті значення, які вони мали в момент, коли стаб зробив виклик receive.
Тепер починає роботу серверний стаб. Він розпаковує параметри і поміщає їх відповідним чином в стек. Коли все готово, виконується виклик сервера. Після виконання процедури сервер передає результати клієнту. Для цього виконуються всі описані вище етапи, тільки в зворотному порядку.
14 етапів виконання RPC:
Клієнт
1. Виклик стабу
2. Підготувати буфер
3. Упакувати параметри
4. Заповнити поле заголовка
5. Обчислити контрольну суму в повідомленні
6. Переривання до ядра
7. Черга пакету на виконання
8. Передача повідомлення контролеру по шині QBUS
9. Час передачі по мережі Ethernet
Сервер
10. Отримати пакет від контролера
11. Процедура обробки переривання
12. Обчислення контрольної суми
13. Переключення контексту в простір користувача
14. Виконання серверного стабу
21.2.4. Динамічне зв'язування
Розглянемо питання про те, як клієнт задає місце розташування сервера. Одним з методів вирішення цієї проблеми є безпосереднє використання адреси сервера в клієнтській програмі. Недолік такого підходу — його надзвичайна негнучкість: при переміщенні сервера, або при збільшенні числа серверів, або при зміні інтерфейсу у всіх цих та багатьох інших випадках необхідно перекомпілювати всі програми, які використовували жорстке завдання адреси сервера. Для того, щоб уникнути всіх цих проблем, в деяких розподілених системах використовується так зване динамічне зв'язування.
Початковим моментом для динамічного зв'язування є формальне визначення (специфікація) сервера. Специфікація містить ім'я файлу-сервера, номер версії і список процедур-послуг, що надаються даним сервером для клієнтів. Для кожної процедури дається опис її параметрів із зазначенням того, чи є даний параметр вхідним чи вихідним щодо сервера. Деякі параметри можуть бути одночасно вхідними і вихідними — наприклад, деякий масив, який надсилається клієнтом на сервер, модифікується там, а потім повертається назад клієнтові.
Формальна специфікація сервера використовується в якості вихідних даних для програми-генератора стабів, яка створює як клієнтські, так і серверні стаби. Потім вони поміщаються у відповідні бібліотеки. Коли клієнтська програма викликає якусь процедуру, визначену в специфікації сервера, відповідна стаб-процедура зв'язується з двійковим кодом програми.
При запуску сервера найпершою його дією є передача свого серверного інтерфейсу спеціальною програмою, так званим binder'ом. Цей процес, відомий як процес реєстрації сервера, включає передачу сервером свого імені, номера версії, унікального ідентифікатора і описувача місцезнаходження сервера. Описувач системно незалежний і може представляти собою IP, Ethernet, X.500 або ще яку-небудь адресу. Крім того, він може містити й іншу інформацію, наприклад дані, що стосуються аутентифікації.
Коли клієнт викликає одну з віддалених процедур перший раз клієнтський стаб бачить, що він ще не підключений до сервера, і надсилає повідомлення binder-програмі з проханням про імпорт інтерфейсу потрібної версії потрібного сервера. Якщо такий сервер існує, то binder передає описувач і унікальний ідентифікатор клієнтському стабу.
Клієнтський стаб при посилці повідомлення із запитом використовує в якості адреси описувач. У повідомленні містяться параметри і унікальний ідентифікатор, який ядро сервера використовує для того, щоб направити повідомлення в потрібний сервер у випадку, якщо їх декілька на цій машині.
Цей метод, що полягає в імпорті / експорті інтерфейсів, має високу гнучкість. Наприклад, може бути кілька серверів, що підтримують один і той же інтерфейс, і клієнти розподіляються по серверах випадковим чином. У рамках цього методу стає можливим періодичне опитування серверів, аналіз їх працездатності та, у разі відмови, автоматичне відключення, що підвищує загальну відмовостійкість системи. Цей метод може також підтримувати аутентифікацію клієнта. Наприклад, сервер може визначити, що він може бути використаний тільки клієнтами з певного списку.
Однак у динамічного зв'язування є недоліки, наприклад, додаткові накладні витрати (тимчасові витрати) на експорт та імпорт інтерфейсів. Величина цих витрат може бути значною, тому що багато клієнтських процесів існують короткий час, а при кожному старті процесу процедура імпорту інтерфейсу повинна бути знову виконана. Крім того, у великих розподілених системах може бути вузьким місцем програма binder, а створення декількох програм аналогічного призначення також збільшує накладні витрати на створення і синхронізацію процесів.
21.2.4. Семантика RPC в разі відмов
В ідеалі RPC повинен функціонувати правильно і у випадку відмов. Розглянемо наступні класи відмов:
- Клієнт не може визначити місцезнаходження сервера, наприклад, у разі відмови потрібного сервера, або через те, що програма клієнта була скомпільована давно і використовувала стару версію інтерфейсу сервера. У цьому випадку у відповідь на запит клієнта надходить повідомлення, що містить код помилки.
- Втрачено запит від клієнта до сервера. Найпростіше рішення — через певний час повторити запит.
- Втрачено повідомлення-відповідь від сервера до клієнта. Цей варіант складніший від попереднього, так як деякі процедури не є ідемпотентними. Ідемпотентною називається процедура, запит на виконання якої можна повторити кілька разів, і результат при цьому не зміниться. Прикладом такої процедури може бути читання файлу. Але ось процедура зняття деякої суми з банківського рахунку не є ідемпотентною, і в разі втрати відповіді повторний запит може істотно змінити стан рахунку клієнта. Одним з можливих рішень є приведення всіх процедур до ідемпотентного виду. Однак на практиці це не завжди вдається, тому може бути використаний інший метод — послідовна нумерація всіх запитів клієнтським ядром. Ядро сервера запам'ятовує номер самого останнього запиту від кожного з клієнтів, і при отриманні кожного запиту виконує аналіз — чи є цей запит первинним або повторним.
- Сервер зазнав аварію після отримання запиту. Тут також важливо властивість Ідемпотентний, але на жаль не може бути застосований підхід з нумерацією запитів. У даному випадку має значення, коли відбулася відмова — до чи після виконання операції. Але клієнтське ядро не може розпізнати ці ситуації, для нього відомо тільки те, що час відповіді вичерпано.
Існує три підходи до цієї проблеми:
- Чекати до тих пір, поки сервер не перезавантажиться і намагатися виконати операцію знову. Цей підхід гарантує, що RPC був виконаний до кінця принаймні один раз, а можливо і більше.
- Відразу повідомити програму про помилку. Цей підхід гарантує, що RPC був виконаний не більше одного разу.
- Третій підхід не гарантує нічого. Коли сервер відмовляє, клієнтові не надається ніякої підтримки. RPC може бути або не виконано взагалі, чи виконано багато разів. В усякому разі цей спосіб дуже легко реалізувати.
21.3. Брокери об'єктних запитів
Брокер об'єктних запитів (Object Request Broker, ORB) це об'єктна шина, по якій в стилі, що нагадує класичний механізм RPC, відбувається взаємодія локальних і віддалених об'єктів. На відміну від моделі СОМ, ORB не спирається безпосередньо на механізм RPC, але працює по тих же принципах. Окрім самого виклику методу віддаленого об'єкту, ORB відповідає за пошук реалізації об'єкту, його підготовку до отримання і обробки запиту, передачу запиту і доставку результатів клієнту. ORB є ядром компонентної моделі CORBA, яку ми розглянемо в лекції 15.
CORBA (Common Object Request Broker Architecture) - це стандарт, набір специфікацій для проміжного програмного забезпечення (middleware) об'єктного типа. Різні розробники архітектури CORBAпо різному реалізовують ці специфікації.
При визначенні конкретної архітектури Брокер Об'єктних Запитів зовсім необов'язково має бути реалізований як один компонент, але кожна реалізація повинна реалізовувати три категорії операцій:
- Операції, які однакові для всіх реалізацій ORB.
- Операції, специфічні для конкретного об'єктного типа.
- Операції, специфічні для окремих видів реалізацій об'єктів.
Різні реалізації ORB можуть підтримувати різні види реалізацій, а різні адаптери об'єктів можуть забезпечувати різні набори сервісів для клієнта і реалізацій.
Ядро Брокера Об'єктних Запитів забезпечує основні механізми для маніпуляцій об'єктами і виконання запитів. Специфікація CORBA призначається для підтримки різних механізмів реалізації об'єктів, тому структура ядра не визначається. Замість цього задається набір інтерфейсних функцій, які мають бути присутніми в кожній реалізації ORB і тим самим маскують відмінності між різними реалізаціями Брокерів Об'єктних Запитів.
Система об'єктів забезпечує клієнта набором сервісів. Клієнт здатний запитати деякий сервіс. Об'єкт - це щось, що забезпечує один або більше сервісів, які може запитати клієнт.
Доступна багато способів реалізації конкретних ORB. Розглянемо окремі приклади таких реалізацій. Слід зазначити, що конкретний ORB може бути реалізований відразу декількома способами.
ORB, що включається в клієнтське і серверне застосування
Якщо є відповідний механізм комунікацій, то можлива реалізація ORB у вигляді набору підпрограм як з боку клієнта, так і з боку реалізації об'єкту. Виклики методів можуть транслюватися в роботу із засобами взаємодії процесів (Inter Process Communication - IPC).
ORB, виконаний у вигляді сервера
З метою забезпечення централізованого збору і управління всілякою інформацією, ORB може бути реалізований у вигляді окремого застосування. Взаємодіючі застосування встановлюють контакт з ORB-ом за допомогою нормальних механізмів IPC.
ORB як частина системи
Для підвищення надійності, захисту даних і досягнення кращої продуктивності ORB може бути реалізований як частина операційної системи. При цьому посилання на об'єкт можуть бути зроблені постійними, таким чином, зменшуючи час, необхідний для обробки кожного запиту. При реалізації ORB як частини операційної системи можливі всілякі види оптимізації, такі як уникнення кодування і декодування даних, якщо клієнт і сервер знаходяться на одній і тій же машині.
ORB, заснований на бібліотеках
Якщо код об'єкту займає невеликий об'єм і не вимагає жодних додаткових засобів, то він може бути виконаний у вигляді бібліотеки. При цьому всі заглушки насправді будуть справжніми методами. При цьому передбачається, що маючи доступ до даних реалізації, клієнт не зруйнує ці дані.
21.4. Монітори обробки транзакцій
Поняття транзакції прийшло в інженерію ПЗ з бізнесу і використовується найчастіше (але не завжди) для реалізації функціональності, пов'язаної із забезпеченням різного роду операцій. Прикладом, що пояснює необхідність використання транзакцій, є переказ грошей з одного банківського рахунку на іншій. При переказі відповідна сума має бути знята з першого рахунку і додатися до вже наявних грошей на другому. Якщо між першою і другою операцією станеться збій, наприклад, пропаде зв'язок між банками, гроші зникнуть з першого рахунку і не з'являться на другому, що явно не влаштує їх власника. Перестановка операцій місцями не допомагає — при збої між ними рівно така ж сума виникне ні з чого на другому рахунку. В цьому випадку невдоволений буде банк, оскільки він повинен буде виплатити ці гроші власникові рахунку, хоча сам їх не отримував. Вихід з цієї ситуації один — зробити так, щоб або обидві операції виконувалися, або жодна з них не виконувалася. Така властивість забезпечується їх об'єднанням в одну транзакцію. Транзакції є групами дій, що володіють наступним набором властивостей.
• Атомарність (atomicity). Для оточення транзакція неподільна — вона або виконується цілком, або жодна з дій транзакції не виконується. Інші процеси не мають доступу до проміжних результатам транзакції.
Несуперечність (consistency). Транзакція не порушує інваріантів і обмежень цілісності даних системи.
• Ізольованість (isolation). Транзакції, що одночасно відбуваються, не впливають одна на одну. Це означає, що декілька транзакцій, що виконувалися паралельно, справляють таке сумарне враження, неначе вони виконувалися в деякій послідовності. Сама ця послідовність визначається внутрішніми механізмами реалізації транзакцій. Цю властивість також називають серіалізуємістю транзакцій, оскільки будь-який сценарій їх виконання еквівалентний деякій їх послідовності або серії.
• Довговічність (durability). Після завершення транзакції зроблені нею зміни стають постійними і доступними для виконуваних далі операцій. Якщо транзакція завершилася, жодні збої не можуть відмінити результати її роботи.
По перших буквах англійських термінів для цих властивостей, їх часто називають ACID. Властивостями ACID у всій повноті володіють так звані плоскі транзакції (flat transactions), найпоширеніший варіант транзакцій. Інколи потрібна набагато складніша поведінка, в рамках якої потрібно уміти виконувати або відміняти лише частину операцій у складі транзакції; бувають випадки, коли процесам, що не беруть участь в транзакції, потрібно уміти отримати її проміжні результати. приховування проміжних результатів часто накладає дуже сильні обмеження на роботу системи, якщо транзакція продовжується помітний час (а інколи їх виконання вимагає декількох місяців!). Для вирішення таких завдань застосовуються механізми, що допускають вкладеність транзакцій одна в одну, довгі транзакції, що дозволяють діставати доступ до своїх проміжних результатів, і ін.
Одним з поширених видів програмного забезпечення проміжного рівня є монітори транзакцій (transaction monitors), що забезпечують виконання віддалених викликів процедур з підтримкою транзакцій. Такі транзакції часто називають розподіленими, оскільки процеси, що беруть участь в них, можуть працювати на різних машинах.
Рис. 21.3. Розподілені транзакції
Для організації таких транзакцій необхідний координатор, який отримує інформацію про всі дії, що беруть участь в транзакції, і забезпечує її атомарність і ізольованість від інших процесів. Зазвичай транзакції реалізуються за допомогою примітивів Клієнтської заглушки.
Клієнт виклик Серверна заглушка Сервер Координатор транзакцій виклик додавання ідентифікатора транзакції розпаковування ідентифікатора транзакції результат виконання протоколу підтвердження підтвердити локально результат почати транзакцію ідентифікатор транзакції створення транзакції реєстрація учасника реєстрація в даній транзакції реєстрація учасника завершити транзакцію підтвердити локально 224 почати транзакцію, завершити її успішно (commit), із збереженням всіх зроблених змін, і відкотити транзакцію (rollback), відмінивши всі виконані в її рамках дії.
Примітив «почати транзакцію» повідомляє координатора про необхідність створити нову транзакцію, зареєструвати об'єкт, що почав її, як учасника і передати йому ідентифікатор транзакції. При передачі управління (у тому числі за допомогою віддаленого виклику методу) учасник транзакції передає разом із звичайними даними її ідентифікатор. Компонент, операція якого була викликана в рамках транзакції, повідомляє координаторові ідентифікатор транзакції з тим, аби координатор зареєстрував і його як учасника цієї ж транзакції. Якщо один з учасників не може виконати свою операцію, виконується відкот транзакції. При цьому координатор розсилає всім зареєстрованим учасникам повідомлення про необхідність відмінити виконані ними раніше дії. Якщо викликається примітив «завершити транзакцію», координатор виконує деякий протокол підтвердження, аби переконатися, що всі учасники виконали свої дії успішно і можна відкрити результати транзакції для зовнішнього світу. Найширше використовується протокол двофазного підтвердження (Two-phase Commit Protocol, 2PС), який полягає в наступному.
1. Координатор посилає кожному компоненту-учасникові транзакції запит про підтвердження успішності його дій.
2. Якщо даний компонент виконав свою частину операцій успішно, він повертає координаторові підтвердження. Інакше — він посилає повідомлення про помилку.
3. Координатор збирає підтвердження всіх учасників і, якщо всі зареєстровані учасники транзакції присилають підтвердження успішності, розсилає їм повідомлення про підтвердження транзакції в цілому. Якщо хоч би один учасник прислав повідомлення про помилку або не відповів в рамках заданого часу, координатор розсилає повідомлення про необхідність відмінити транзакцію.
4. Кожен учасник, отримавши повідомлення про підтвердження транзакції в цілому, зберігає локальні зміни, зроблені в рамках транзакції. Якщо ж він отримати повідомлення про відміну транзакції, він відміняє локальні зміни. Аналог протоколу двофазного підтвердження використовується, наприклад, в компонентній моделі JavaBeans для повідомлення про зміни властивостей компонента, які деякі з компонентів-підписчиків, що оповіщаються про них, можуть відмінити.
Таким чином, Монітори обробки транзакцій (Transaction Processing Monitor — TPM) — це програмні системи, які входять до складу РЗ проміжного рівня, які вирішують завдання ефективного управління інформаційно-обчислювальними ресурсами в розподіленій системі. Вони є гнучким, відкритим середовищем для розробки і управління мобільними застосуваннями, орієнтованими на оперативну обробку розподілених транзакцій. У числі найважливіших характеристик TPM — масштабованість, підтримка функціональної повноти і цілісності застосувань, досягнення максимальної продуктивності при обробці даних при невисоких вартісних показниках, підтримка цілісності даних в гетерогенному середовищі. TPM спираються на трирівневу модель "клієнт-сервер".
Монітори обробки транзакцій можуть мати клієнтський компонент, але основну частину роботи вони виконують на сервері застосування, пов'язаному з декількома серверами баз даних і виконуючому при необхідності розподіл навантаження. Як і RPC, монітори традиційно мають синхронну природу, тому найбільш відповідною для них сферою застосування є та, де першочергове значення має цілісність даних; вони набагато менш придатні для надання даних в реальному часі.
Висновки
Проміжне програмне забезпечення містить набір загальносистемних сервісів (служб) для спрощення розробки і інтеграції програмних застосувань. Ці служби розміщуються над програмними засобами ядра операційної системи. Розглянуті в цій лекції основні сервіси як от RPC, брокери об'єктних запитів, монітори обробки транзакцій відносяться до ПЗ низького рівня і входять до складу всіх сучасних операційних систем. Для подальшого спрощення програмування над цими базовими сервісами існують ПЗ вищого (прикладного рівня), реалізовані в відповідних моделях проміжного рівня, які розглядаються в наступних лекціях.
Контрольні запитання і завдання для самостійної роботи
1. Яке призначення ПЗ проміжного рівня? Які завдання вирішують ПЗ проміжного рівня?
2. Характеристика RPC. Чим віддалений виклик відрізняється від локального виклику процедури?
3. Чому віддалений виклик процедери є складнішим за локальний?
4. Базові операції RPC.
5. Для чого при віддаленому виклику використовується програми-заглушки?
6. Яке призначення клієнтської заглушки? Яке призначення серверної заглушки?
7. Етапи виконання RPC.
8. Семантика RPC в разі відмов
9. Брокери об'єктних запитів. Призначення та основні операції, які вони повинні реалізувати.
10. Можливі способи реалізації Брокеру об'єктних запитів.
11. Монітори обробки транзакцій.
(Для ознайомлення з повним текстом статті необхідно залогінитись)