- •Лекція №2
- •Розподілені сервісні системи
- •Тема 2. Зв'язок в розподілених сервісних системах.
- •1. Рівні протоколів.
- •2. Віддалений виклик процедур.
- •2.1. Передача параметрів.
- •2.2. Розширені моделі rpc.
- •3. Зв'язок за допомогою повідомлень.
- •3.1. Збереження і синхронність у взаємодіях.
- •3.2. Зв'язок на основі потоків даних.
- •Питання для самоконтролю
1. Рівні протоколів.
У моделі OSI взаємодія ділиться на сім рівнів, як показано рис.6. Кожен рівень відповідає за один аспект взаємодії. Таким чином проблема може бути розділена на частини, які піддаються рішенню, кожна з яких може розбиратися незалежно від інших. Кожен з рівнів надає інтерфейс для роботи з вищим рівнем. Інтерфейс складається з набору операцій, які спільно визначають інтерфейс, що надається рівнем тих, хто ним користується.
Рис.6. Рівні, інтерфейси і протоколи моделі OSI
Коли процес А на машині 1 хоче спілкуватись з процесом В на машині 2, він будує повідомлення і посилає його прикладному рівню своєї машини. Цей рівень може представляти собою бібліотечну процедуру, або реалізовуватись всередині операційної системи, або зовнішнього мережевого процесора. Програмне забезпечення проміжного рівня додає в початок повідомлення свій заголовок (header) і передає отримане повідомлення через інтерфейс з рівня 7 на рівень 3, рівень представлення. Рівень представлення, в свою чергу, додає в початок повідомлення свій заголовок і передає результат вниз - на сеансовий рівень і т.д. Деякі рівні додають заголовок не тільки в початок, а й завершення в кінець повідомлення. Коли повідомлення дійде до фізичного рівня, він здійснить його реальну передачу, як показано рис.7.
Рис.7. Передача по мережі типового повідомлення.
Коли повідомлення приходить на машину 2, воно передається наверх, при цьому на кожному рівні зчитується і перевіряється відповідний заголовок. Наприкінці повідомлення доходить до одержувача, процесу Б, який може відповісти на нього, при цьому всі історія повторюється у зворотному напрямку. Інформація з заголовка n використовується протоколом рівня n.
В моделі OSI, як було показано на малюнку 1, не два рівня а сім. Набір протоколів, що використовуються в конкретній системі, називається комплектом або стеком протоколів. Важливо розрізняти еталонну модель від реальних протоколів. На противагу їм, протоколи що розроблялися для Інтернету, такі як TCP і IP, набули більшої популярності.
2. Віддалений виклик процедур.
Основою безлічі розподілених систем є явний обмін повідомленнями між процесами. Однак процедури sent і receive не приховують взаємодії, що необхідно для забезпечення прозорості. Для рішення цієї проблеми було запропоновано дозволити програмам викликати процедури, які знаходяться на інших машинах. Цей метод відомий під назвою віддалений виклик процедур (Remote Procedure Call, RPC).
Базова ідея проста але складнощі виникають при реалізації. Для початку, оскільки викликаючий процес і викликаюча процедура знаходяться на різних машинах, вони виконуються в різних адресних просторах, що тут же зароджує проблеми. Параметри і результати також передаються від машини до машини, що може викликати труднощі, особливо якщо машини не однакові. Нарешті, на обох машинах можуть бути збої, які викликають різноманітні складності. однак з цими проблемами можна справитись і RPC являється широко розповсюдженої технологією, на якій базується багато розподілених систем.
Загальноприйняті виклики процедур.
Для того щоб зрозуміти як працює RPC, важливо спочатку розібратися, як здійснюються загальноприйняті (в межах однієї машини) виклики процедур. Розглянемо виклик на прикладі мови типу С:
count = readCfd. buf. bytes):
тут fd - ціле число, яке вказує на файл;
buf - масив символів, в який будуть зчитуватись дані;
bytes - інше число, яке говорить, скільки байт слід рахувати.
Якщо виклик проводиться з головної програми, стек до виклику виглядає так, як показано на рис.8. Роблячи виклик, викликаюча програма поміщає параметри в стек в порядку "останній - перший", як показано на рис.8. Причина по якій компілятор С поміщає параметри в стеку в зворотному порядку, заключається в функціях типу printf. Щоб бути виконаю функцію printf завжди повинна знати, де шукати свій перший аргумент - рядок формату. Після завершення read система поміщає повернене значення в регістр, видаляє адресу повернення і повертає управління назад, в програму яка його викликала. Потім викликана програма видаляє з стека параметри, приводячи його в початковий стан.
В С параметри можуть передаватися як за значенням, так і за посиланням. Параметр - значення, такий як fd або bytes, просто копіюються в стек як показано на рис. 8.б. Для викликаємої процедури параметр - значення представляє собою просто ініціалізовану локальну змінну. Викликана процедура може її змінити.
Рис.8. Передача параметрів при локальному виклику процедури: стек виклику функції read (а). Стек під час роботи викликаної процедури (б).
Параметр - посилання в С - це покажчик на змінну (тобто адресу змінної), а не її значення. у виклику read другий параметр є параметром - посиланням, оскільки масиви С завжди передаються через посилання. В стек насправді буде поміщена адреса символьного масиву. Якщо викликана процедура використовує цей параметр для поміщення будь-чого і символьний масив, це призведе до зміни масиву в викликаній програмі. Різниця між параметрами - значеннями і параметрами - посиланнями вкрай важлива для RPC.
Існує ще один механізм передачі параметрів, що не застосовується в С. Він називається виклик через копіювання/відновлення (call-by-copy/restore). У цьому випадку до виклику визиваючою програмою проводиться копіювання змінної в стек, як при виклику за значенням, а після завершення виклику - копіювання цієї змінної з стека назад, з видаленням вихідного значення цієї змінної.
Рішення про використання того чи іншого механізму передачі параметрів приймається розробниками мови і є його фіксованою властивістю. Раніше це рішення залежало від типів даних. В С наприклад, цілі та інші скалярні типи завжди передаються за значенням, а масиви за посиланням. Визначення мови дозволяє обрати будь-який варіант, який хоч трохи спрощує семантику.
Заглушки для клієнта і сервера.
Ідея, що стоїть за RPC, полягає в тому, щоб віддалений виклик процедур виглядав точно так само, як і локальний, тобто викликаюча процедура не повинна повідомлятися про те, що викликана процедура виконується на іншій машині, і навпаки. Припустимо, програма хоче зчитати деякі дані з файлу. для читання файлу необхідних даних програміст поміщає в код виклик read. У традиційній (однопроцесорній) системі процедура read витягується компанувальником з бібліотеки і вставляється в об'єктний код програми. Процедура read - це інтерфейс між кодом користувача та локальною операційною системою.
Навіть якщо read - це системний виклик, він проводиться шляхом поміщення параметрів в стек, як показано на рис. 8.б. Таким чином програміст і не взнає що робить read.
RPC організовує свою прозорість аналогічним чином. Якщо read є віддаленою процедурою, в бібліотеку поміщається спеціальна версія read, яка називається клієнтською заглушкою (client stub). Як і оригінальна функція, вона також викликається у відповідністю з послідовністю, що на рис. 8.б. Як і оригінал, вона також виробляє виклик локальної операційної системи, тільки на відмінну від оригінальної функції, клієнтська заглушка не просить дані у операційної системи. Замість цього вона упаковує параметри в повідомлення і шляхом виклику процедури sent вимагає переслати це повідомлення на сервер, як показано на рис. 9. Після виклику процедури sent клієнтська заглушка викликає процедуру receive, блокуючись до отримання відповіді.
Рис.9. Схема RPC між програмами клієнта і сервера.
Коли повідомлення приходить на сервер, операційна система сервера передає його серверній заглушці (server stub). Серверна заглушка еквівалентна клієнтській, але працює на стороні сервера. Це фрагмент коду, який перетворює запити які проходять по мережі і виклики локальних процедур. Зазвичай серверна заглушка запускає процедуру receive і блокується, очікуючи вхідних повідомлень. Після отримання повідомлення серверна заглушка розпаковує його, витягуючи параметри, і традиційним способом викликає процедуру сервера. З точки зору сервера це сприймається як прямий виклик клієнта - параметри і адреса повернення знаходяться в стеку, де вони повинні знаходитись. Сервер звичайним порядком повертає результат процедурі, яка робила виклик. Так наприклад, у випадку читання файлу сервер заповнює даними буфер, на який вказує другий параметр. Цей буфер - внутрішній буфер серверної заглушки.
Коли серверна заглушка після закінчення обробки виклику повертає управління програмі яка робила виклик, вона запаковує результати виконання (буфер) в повідомлення і викликає процедуру sent, щоб повернути їх клієнтові. Після цього серверна заглушка знову викликає процедуру receive, переходячи в режим очікування наступного повідомлення.
Коли на клієнтську машину приходить відповідь, операційна система клієнта виявляє, що вона адресована клієнтському процесу. Повідомлення копіюється в буфер очікування, і клієнтський процес розблокується. Клієнтська заглушка розглядає повідомлення, розпаковує його, витягуючи результати, копіює їх у пам'ять програми яка робила виклик, і завершуючи роботу, передає в неї код повернення. Коли викликаюча програма отримує управління після виклику read, все, що вона знає - це те що дані знаходяться в буфері.
Підіб'ємо підсумки. При віддаленому виклику процедур відбувається наступні дії:
1. Процедура клієнта звичайним чином викликає клієнтську заглушку.
2. Клієнтська заглушка створює повідомлення і викликає локальну операційну систему.
3. Операційна система клієнта пересилає повідомлення віддаленій операційній системі.
4. Дистанційна операційна система передає повідомлення серверній заглушці.
5. Серверна заглушка витягує з повідомлення параметри і викликає сервер.
6. Сервер виконує виклик і повертає результати заглушці.
7. Серверна заглушка запаковує результати в повідомлення і викликає свою локальну операційну систему.
8. Операційна система сервера пересилає повідомлення операційній системі клієнта.
9. Операційна система клієнта приймає повідомлення і передає його клієнтській заглушці.
10. Заглушка витягує результати з повідомлення і передає їх клієнту.
Мережеві ефекти цих кроків полягають у тому, що клієнтська заглушка перетворює локальний виклик процедури клієнта в локальний виклик процедури сервера, причому клієнт і сервер нічого не знають про проміжні дії.
