Э. Таненбаум, М. ван Стеен - Распределённые системы (принципы и парадигмы) (1162619), страница 47
Текст из файла (страница 47)
Сервербез фиксации состояния {stateless sewer) не сохраняет информацию о состояниисвоих клиентов и может менять свое собственное состояние, не информируя обэтом своих клиентов [55]. Web-сервер, например, это сервер без фиксации состояния. Он просто отвечает на входящие HTTP-запросы, которые могут требовать загрузки файла как на сервер, так и (гораздо чаще) с сервера.
После выполнения запроса web-сервер забывает о клиенте. Кроме того, набор файлов,которыми управляет web-сервер (возможно, в комбинации с файловым сервером), может быть изменен без уведомления клиентов об этом действии.В противоположность этому, сервер с фиксацией состояния (stateful server)хранит и обрабатывает информацию о своих клиентах. Типичным примеромтакого сервера является файловый сервер, позволяющий клиенту создавать локальные копии файлов, скажем, для повышения производительности операцийобновления. Подобный сервер поддерживает таблицу, содержащую записи пар(клиент, файл).
Такая таблица позволяет серверу отслеживать, какой клиентс каким файлом работает и, таким образом, всегда определять самую «свежую»версию файла. Подобный подход повышает производительность операций чтения-записи, осуществляемых на клиенте.
Рост производительности по сравнению с серверами без фиксации состояния часто является основным преимуществом и основной причиной разработки серверов с фиксацией состояния. Однакоданный пример также иллюстрирует основной недостаток таких серверов. В случае сбоя сервера он вынужден восстанавливать свою таблицу с записями пар(клиент, файл), в противном случае не будет никакой гарантии в том, что работапроисходит с последней обновленной версией файла. Как правило, серверы с фиксацией состояния нуждаются в восстановлении своего состояния в том виде,в котором оно было до сбоя. Как мы увидим в главе 7, необходимость обеспечитьвосстановление после сбоя сильно усложняет программу. В случае архитектурыбез фиксации состояния вообще нет необходимости принимать какие-то специальные меры по восстановлению серверов после сбоя. Они просто перезапускаются и работают, ожидая запросов клиента.При разработке сервера выбор между архитектурой с фиксацией и без фиксации состояния не отражается на службе, которую этот сервер должен предоставлять.
Так, например, поскольку до выполнения чтения или записи файлы в любом случае должны открываться, сервер без фиксации состояния должен тем илииным способом воспроизвести открытие файла. Стандартное решение, котороемы более детально обсудим в главе 10, состоит в том, чтобы сервер, обрабатываязапрос на запись в файл или чтение из файла, открывал нужный файл, выполнялоперацию чтения или записи и немедленно его закрывал.В других случаях сервер может пожелать хранить записи о поведении клиентов, чтобы более эффективно обрабатывать их запросы. Так, например, web-серверы иногда предоставляют клиентам возможность немедленно отправиться на3.3. Серверы183любимые страницы. Это можно сделать только в том случае, если сервер будетхранить информацию о клиенте.
Традиционное решение состоит в том, чтобыпозволить клиенту отсылать дополнительную информацию о его предыдущих сеансах работы с сервером. Эта информация часто прозрачно сохраняется браузером клиента в виде файлов cookie — маленьких фрагментов данных, содержащихинформацию о клиенте, важную для сервера. Файлы cookie никогда не исполняются браузером, они просто хранятся.При первом обращении клиента к серверу последний пересылает файл cookieвместе с запрошенными web-страницами браузеру, а браузер сохраняет этот файлcookie. Каждый раз в дальнейшем при обращении клиента к серверу файлыcookie пересылаются браузером на сервер вместе с текстом запроса. В теории этотподход работает прекрасно, на деле же файлы cookie для безопасного храненияотсылаются браузером назад на сервер часто совершению скрытно от пользователя.Такая вот «великая» секретность.
В отличие от бабушкиного печенья (cookie —печенье), эти cookie, как правило, следует оставлять там, где их «испекли».3.3.2. Серверы объектовПосле того как мы рассмотрели основные моменты, относящиеся к проектированию серверов, обсудим особый тип серверов, который становится все важнее.Сервер объектов {object sewer) — это сервер, ориентированный на поддержку распределенных объектов. Важная разница между стандартным сервером объектови другими (более традиционными) серверами состоит в том, что сам по себе сервер объектов не предоставляет конкретной службы. Конкретные службы реализуются объектами, расположенными на сервере.
Сервер предоставляет толькосредства обращения к локальным объектам на основе запросов от удаленныхклиентов. Таким образом, можно относительно легко изменить набор служб, просто добавляя или удаляя объекты.Сервер объектов, соответственно, выступает как место для хранения объектов.Объект состоит из двух частей: данных, отражающих его состояние, и кода, образующего реализацию его методов. Будут ли эти части храниться раздельно, а также смогут ли методы совместно использоваться несколькими объектами, зависит от сервера объектов.
Кроме того, существует разница и в способе обращениясервера объектов к его объектам. Например, в многопоточном сервере объектовотдельный поток выполнения может быть назначен каждому объекту или каждому запросу на обращение к объекту. Эту и другие тонкости мы сейчас и обсудим.Альтернативы обращению к объектамДля любого объекта, к которому происходит обращение, сервер объектов должензнать, какой код выполнять, с какими данными работать, запускать ли отдельныйпоток выполнения для поддержки обращения и т. д. Простейший подход — считать, что все объекты выглядят одинаково и обращение к ним может производиться единообразно.
Именно так работает среда DCE. К сожалению, подобномуподходу обычно не хватает гибкости, и он часто накладывает на разработчиковраспределенных объектов неоправданные ограничения.184Глава 3. ПроцессыБолее правильный подход со стороны сервера — поддерживать различныеправила обработки объектов. Рассмотрим, например, нерезидентные объекты.Напомним, что нерезидентным называется объект, существующий только во время существования сервера, а возможно, и еще более короткий срок.
Типичнойреализацией нерезидентного объекта можно считать хранящуюся в памяти копиюфайла, предназначенную только для чтения. Калькулятор (обычно запускаемыйна высокоскоростном сервере) также может быть реализован в виде нерезидентного объекта. Разумно создать нерезидентный объект при первом же запросек нему, а уничтожить после того, как не останется связанных с этим объектомклиентов. Преимущество подобного подхода состоит в том, что нерезидентныеобъекты нуждаются в ресурсах сервера только до тех пор, пока в этих объектахесть необходимость.
Недостаток — в том, что обращение может потребовать длявыполнения определенного времени, поскольку объект еще нужно создать. Поэтому иногда применяется другая политика — все нерезидентные объекты создаются при инициализации сервера. Это дается ценой выделения ресурсов на объекты даже в том случае, если ни один клиент не станет их использовать.Схожим образом сервер мог бы выделять каждому из своих объектов отдельный сегмент памяти. Другими словами, можно запретить совместное использование объектами кода и данных. Подобный подход мог бы применяться в техслучаях, когда для реализации каждого объекта не требуется отделять код отданных или когда объекты нужно отделить друг от друга по соображениям безопасности.
В этом последнем случае сервер должен будет для гарантированнойзащиты границ сегментов предоставить специальные средства измерения илитребовать поддержки от базовой операцрюнной системы. При альтернативном подходе можно позволить объектам совместно использовать хотя бы код. Так, базаданных, содержащая объекты, относящиеся к одному классу, может быть эффективно реализована путем однократной загрузки на сервер реализации этого класса.
В случае прихода запроса на обращение к объекту серверу достаточно будетизвлечь из базы данных состояние объекта и выполнить вызванный метод.Подобным же образом существует множество разных подходов, относящихсяк работе с потоками выполнения. Простейший из них ~ реализация серверас единственным управляющим потоком выполнения. С другой стороны, серверможет поддерживать несколько потоков выполнения — по одному на каждыйобъект.
В случае прихода запроса с обращеьпшм к объекту сервер просто передаетзапрос потоку выполнения, отвечающему за этот объект. Если поток выполненияв этот момент занят, запрос ставится в очередь. Преимущество такого подхода ~в автоматической защите объектов от одновременного доступа: для единственного связанного с объектом потока выполнения все обращения выстраиваются попорядку. Разумеется, можно также выделять отдельный поток выполнения каждому запросу, но при этом необходимо предварительно защитить объекты от одновременного доступа.
Независимо от того, назначается поток выполнения каждому объекту или каждому методу, нужно решить, создавать каждый поток позапросу или поддерживать на сервере пул потоков. Оптимального решения «навсе случаи жизни» здесь быть не может.3.3. Серверы185Адаптер объектовПравила обращения к объекту обычно называют политикой активизации {activation policies), чтобы подчеркнуть тот факт, что во многих случаях объект, передтем как к нему можно будет обратргться, должен быть перемещен в адресное пространство сервера (то есть активизирован).Нам нужен механизм группирования объектов в соответствии с политикойактивизации каждого из них. Этот механизм называют адаптером объектов (object adapter), или упаковщиком объектов (object wrapper), но чаще всего его существование скрыто в наборе средств построения сервера объектов.