Э. Таненбаум, М. ван Стеен - Распределённые системы (принципы и парадигмы) (1162619), страница 49
Текст из файла (страница 49)
results, size):/* Добавить ответ к содержимому буфера: */put_msg(root. sizeof(res). res):/•^ Освободить память, выделенную под запрос: */free(req):/* Освободить память, выделенную под результаты: */free(results):3.4. Перенос кода189}void 1nvoke_adapter(long old. message ^request) {put_msg(thread[oid]. sizeof (request), request);}Теперь реа7П1зация процедуры invoke^adapter несложна. Вызываемый потоквыполнения (в нашем примере — демультиплексор) добавляет свой запрос наобращение к буферу потока, ассоциированному с объектом, к которому был запрошен доступ. Позднее демультиплексор может извлечь результаты из своего собственного буфера и вернуть их клиенту, который и заказывал обращениек объекту.Важно отметить, что реализация адаптера не зависит от объектов, обращенияк которым он обрабатывает.
Фактически в примере реализации нет никакого зависящего для объектов кода. Соответственно, можно создать обобщенный адаптер и поместить его на промежуточный уровень программного обеспечения. Послеэтого разработчикам серверов объектов можно сконцентрироваться исключительно на разработке объектов, просто указывая при необходимости, какой адаптер обращения к каким объектам должен контролировать.Последнее замечание.
Хотя на рис. 3.7 показан специальный компонент, который занимается распределением поступивших запросов соответствующим адаптерам (демультиплексор), он не обязателен. Для этой цели мы вполне могли быиспользовать адаптер объектов. Как мы увидим в главе 9, подобный подход реализован в технологии CORBA.3.4. Перенос кодаДо сих пор мы в основном обсуждали распределенные системы, в которых взаимодействие ограничивалось передачей данных.
Однако существуют ситуации,когда передача программ, иногда даже во время их выполнения, позволяет упростить разработку распределенных систем. В этом разделе мы детально рассмотрим, как происходит перенос кода. Мы начнем с обсуждения различных подходовк переносу кода и продолжим разговором о локальных ресурсах, которые используются переносимыми программами. Отдельной сложной проблемой являетсяперенос кода в гетерогенных системах. Об этом мы тоже поговорим.
Чтобы вестипредметный разговор, в конце этого раздела мы рассмотрим систему D'Agentsдля мобильных агентов. Отметим, что вопросы безопасности, связанные с переносом кода, вынесены в главу 8.3 . 4 . 1 . Подходы к переносу кодаПеред тем как рассматривать различные варианты переноса кода, обсудим сперва, зачем подобный перенос может понадобиться.190Глава 3.
ПроцессыПричины для переноса кодаТрадиционно перенос кода в распределенных системах происходит в форме переноса процессов {process migration)у в случае которых процесс целиком переноситсяс одной машины на другую. Перенос работающего процесса на другую машину —дорогостоящая и сложная задача, и для ее выполнения должна быть веская причина. Такой причиной всегда была производительность. Основная идея состоит втом, что производительность может возрасти при переносе процессов с сильнозагруженной на слабо загруженную машину. Загрузка обычно выражается в понятиях длины очереди к процессору РШИ загрузки процессора, используются также и другие индикаторы производительности.Алгоритм распределения загрузки, на базе которого принимаются решения,включающие распределение и перераспределение задач в соответствии с имеющимся набором процессоров, играет важную роль в системах интенсивных вычислений.
Однако во многих современных распределенных системах оптимизациявычислительной мощности — менее важная задача по сравнению, например, соснижением коммуникационного трафика. Более того, учитывая гетерогенностьбазовых платформ и компьютерных сетей, повышение производительности путем переноса кода нередко основывается скорее на качественных рассуждениях,чем на математических моделях.Рассмотрим, например, систему клиент-сервер, в которой сервер управляетбольшой базой данных. Если клиентское приложение собирается выполнятьмножество операций с базой данных, используя большие объемы данных, можетбыть лучше перенести часть клиентского приложения на сервер, а по сети передавать только результаты. В противном случае сеть может быть перегружена данными, передаваемыми с сервера на клиент.
В этом случае перенос кода основанна соображении о том, что обычно имеет смысл обрабатывать данные поблизости от того места, где они находятся.Сходная причина может быть использована и при переносе части сервера наклиент. Например, во многих интерактивных приложениях баз да1Н1ых клиентдолжен заполнять форму, которая затем будет преобразована в серию операцийбазы данных. Обработка формы на стороне клиента с пересылкой на сервер только заполненной формы нередко позволяет избежать пересылки по сети значительного количества небольших сооби1ений. В результате клиент покажет лучшую производительность, а сервер затратит меньше времени на обработку формыи взаимодействие.Поддержка переноса кода может также помочь повысить производительностьна основе параллелизма, но без обычных сложностей, связанных с параллельным программированием.
Типичным примером может быть поиск информациив Web. Относительно несложно реализовать поисковый запрос в виде небольшой мобильной программы, переносимой с сайта на сайт. Создав несколькокопий этой программы и разослав их по разным сайтам, мы можем добиться линейного возрастания скорости поиска по сравнению с единственным экземпляром программы.Помимо повышения производительности существуют и другие причины поддержания переноса кода.
Наиболее важная из них — это гибкость. Традицион-3.4. Перенос кода191ный подход к построению распределенных приложений состоит в разбиенииприложения на части с последующим определением, где какая часть будетвыполняться. Подобный подход, например, использовался в различных многозвенных приложениях клиент-сервер, обсуждавшихся в главе 1.Однако, если код можно переносить с машины на машину, становится возможным конфигурировать распределенные системы динамически.
Например,рассмотрим сервер, реализующий стандартизованный интерфейс к файловойсистеме. Чтобы предоставить удаленному клиенту доступ к файловой системе,сервер использует специальный протокол. В обычном варианте клиентская реализация интерфейса с файловой системой, основанная на этом протоколе, должна быть скомпонована с приложением клиента. Этот подход предполагает, чтоподобное программное обеспечение для клиента должно быть доступно уже тогда, когда создается клиентское приложение.Альтернативой является предоставление сервером клиенту реализации не ранее, чем это будет действительно необходимо, то есть в момент привязки клиента к серверу. В этот момент клиент динамически загружает реализацию, производит необходимые действия по инициализации, а затем обращается к серверу.Схема такого пути показана на рис.
3.8. Подобная модель динамически переносимого из удаленного хранилища кода требует стандартизации протокола загрузки и инициализации кода. Кроме того, необходимо, чтобы загружаемый кодможно было выполнять на машине клиента. Различные решения этой проблемыбудут рассмотрены ниже и в последующих главах.КлиентСоответствующийслужбе клиентский2. Взаимодействиеклиента и сервераСервер1. Извлечение кода клиентомкодХранилище кодаРис. 3.8. Принцип динамического конфигурирования клиента для связи с сервером.Сначала клиент извлекает необходимое программное обеспечение,а затем обращается к серверуВажное преимущество подобной модели динамической дозагрузки клиентского программного обеспечения состоит в том, что клиенту для общения с сервером нет необходимости иметь полный комплект предварительно устанавливаемого программного обеспечения.
Вместо этого при необходимости программымогут быть перенесены на клиента и точно так же удалены, когда необходимостьв них исчезнет. Другим преимуществом будет то, что поскольку интерфейсыстандартизованы, то мы можем менять протокол взаимодействия клиент-сервери его реализацию так часто, как пожелаем.