Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type" Java version 1.7.0_05 |
Введение
Сложность реализации
Несмотря на то, что распределенные приложения могут обладать рядом преимуществ по сравнению с монолитными, при их создании приходится сталкиваться с рядом существенных трудностей. Ниже приведен неполный список некоторых типичных проблем, возникающих при проектировании и реализации распределенного приложения.
Зависимость от выбранной архитектуры
Точно так же, как и при проектировании традиционного приложения, вопрос выбора структурных решений (шаблонов), лежащих в его основе, является ключевым, более того, он приобретает решающую значимость. В силу того, что компоненты распределенного приложения часто вынуждены взаимодействовать по сети (что на порядок медленнее обычного для монолитных приложений метода взаимодействия - локального вызова процедуры), неудачно выбранная структура интерфейсов или компоновка модулей системы может привести к катастрофическим последствиям для производительности. Кроме того, поскольку различные модули системы выполняются на независимых узлах и, следовательно, в рамках независимых процессов, более остро проявляются проблемы синхронизации доступа к ресурсам и все связанные с этим вопросы, такие как обеспечение транзакционности обработки, уровни изоляции транзакций и т.д.
Гетерогенная среда
Поскольку различные части распределенного программного комплекса могут выполняться на разных узлах системы, которые могут отличаться аппаратной, сетевой, программной архитектурой, это влечет за собой серьезные проблемы в программировании таких систем. Достаточно сказать, что даже представление такого фундаментального понятия, как тип данных, зависит от используемого языка программирования и от аппаратной архитектуры. Наилучшим выходом из этой ситуации может считаться либо использование принятых и поддерживаемых стандартов (таких как протокол TCP/IP для сетевого взаимодействия или POSIX для системных вызовов), либо применение специальных промежуточных средств ( middleware ), маскирующих гетерогенность ( CORBA, Java RMI, . NET и т.д.). Интересным решением проблемы гетерогенности является использование виртуальных машин (например, jvm ), исполняющих некоторый независимый от используемой целевой системы код. При этом могут быть созданы системы, работающие и взаимодействующие друг с другом на любых платформах1На любых, для которых существует реализация виртуальной машины . Попутно решается еще ряд серьезных проблем, связанных, например, с безопасностью. Одним из серьезных недостатков такого подхода является то, что при этом снижается производительность (за счет ввода дополнительного посредника - виртуальной машины). Однако то, что ведущие игроки на рынке - Sun, IBM и Microsoft - в настоящее время активно работают в этом направлении, говорит о том, что этот подход перспективен. Альтернативным методом ("метод грубой силы") является подход, при котором все модули системы компилируются под все платформы, на которых система будет использоваться (применяется в настоящее время очень часто).
Сложность развертывания
В отличие от монолитного приложения распределенное приложение должно быть разделено на модули развертывания. Дело в том, что различные части распределенного приложения будут выполняться на разных узлах, имеющих, возможно, различные характеристики (различную аппаратную, программную платформу и т.д.). На каждый узел должен быть корректно инсталлирован свой модуль. В случае если в процессе работы системы происходит миграция программных компонент между узлами, необходимо учитывать особенности гетерогенной среды.
Сложность отладки
Характерной особенностью распределенных систем является то, что состояние, в котором пребывает система, тоже является "распределенным" - для того чтобы его зафиксировать, необходимо собрать информацию с нескольких вычислительных узлов. Другой проблемой является воспроизводимость результатов выполнения - поскольку процессы, выполняющиеся на различных вычислительных узлах, могут выполняться с разной скоростью, отличающейся от запуска к запуску.
Шаблоны решений
Все вышесказанное должно было убедить в том, что создание распределенной программной системы - гораздо более сложная задача, чем создание монолитной. Однако то, что подобные системы не только разрабатываются, но и успешно эксплуатируются уже довольно долго, говорит о том, что, по всей видимости, найдены какие-то рецепты борьбы с перечисленными ранее проблемами. Действительно, при решении любой сложной задачи имеет смысл посмотреть, как подобные задачи решались ранее.
При внимательном изучении крупных распределенных систем, действительно, можно заметить довольно много общего в их строении, что позволяет говорить о наличии различных архитектур построения распределенных систем, которые, по сути, представляют собой такие общие решения, или шаблоны, которые полезно знать и которые можно применять в подходящих для этого случаях. Кроме того, рассмотрение архитектур, где выполняются программные системы, позволяет их некоторым образом классифицировать по этому признаку. Поскольку с каждой архитектурой можно связать некоторые характерные особенности, которыми будут обладать все реализующие эту архитектуру программные комплексы, такая классификация может быть полезна при выборе архитектуры проектируемой системы.
В самом деле, зная требования к системе и отличительные черты различных архитектур построения, можно выбрать из них наиболее подходящую.
При начальном моделировании системы обращают внимание не только на разделение системы на части (декомпозиция), но и на взаимодействие этих частей (модулей), которые, возможно, будут выполняться на разных узлах. Выбор архитектуры в большинстве случаев порождает тот или иной способ декомпозиции задачи, а также, в большинстве случаев, и способы взаимодействия. Хорошо продуманная структура системы должна обеспечивать надежность, управляемость, гибкость и при этом позволять построить экономически эффективное решение.
При описании архитектуры функции отдельных компонент обычно не указывают. Важными являются размещение компонент (с учетом сетевой топологии, которая может иметь решающее значение при выборе той или иной архитектуры), способы распределения данных (и управления ими), распределение нагрузки между компонентами, а также способы взаимодействия.
Взаимодействие компонентов для распределенных систем является ключевым аспектом. Очень часто именно особенностями взаимодействия диктуется в конечном итоге выбор архитектуры системы. В самом деле, если говорить о реальной ситуации, то модули распределенной системы обычно вынуждены взаимодействовать через сеть (того или иного типа), для которой время передачи данных на несколько порядков больше, чем время обращения к данным в локальной памяти. Поэтому стремятся построить систему таким образом, чтобы минимизировать количество и объем сетевого взаимодействия, переносят наиболее активно взаимодействующие модули на узлы, связанные быстрыми каналами, и т.д.
Взаимодействие подразумевает участие как минимум двух сторон - вызывающей ("клиента") и вызываемой ("сервера"). Соответственно, первый модуль будет являться клиентом по отношению ко второму. Стоит отметить, что, вообще говоря, роли определяются только на момент конкретного взаимодействия - так, модуль, являющийся инициатором запроса ("клиентом") в один момент времени, может быть запрошен о чем-то другим модулем (и, таким образом, стать для него "сервером" )2Немного забегая вперед, можно сказать, что для архитектуры "клиент-сервер", речь о которой впереди, характерно такое разбиение, при котором одни модули почти всегда обращаются с запросами (являются клиентами) к другим модулям (серверам)..
Как уже говорилось, архитектуру можно понимать как некий шаблон, некоторую общую идею декомпозиции и взаимодействия компонентов, решение, которое до этого много раз применялось. В каком-то смысле, это попытка компенсировать возрастающую сложность системы.
Другой способ преодоления сложности лежит в области уже рассматриваемой модели разделения разрабатываемых систем на слои. Идея состоит в том, что, поскольку многие из задач возникают перед разработчиками постоянно, нужно создать некоторый набор готовых программных решений, достаточно общих, чтобы ими можно было бы воспользоваться в широком ряде случаев. При использовании такой методики приложение рассматривается как верхний слой (см. табл. 1.1) - он использует функциональность нижележащего слоя, который часто называют промежуточным программным обеспечением ( middleware ).
Приложения, сервисы |
Промежуточное программное обеспечение ( Middleware ) |
ОС |
Аппаратное обеспечение |
Два нижних слоя часто объединяют общим термином "платформа".
Middleware - промежуточное программное обеспечение между платформой и собственно компонентами распределенного приложения. Уровень этот, вообще говоря, обязательным не является, но его наличие крайне желательно. Его задача - скрыть (маскировать) гетерогенность платформы и обеспечить удобную модель программирования. В качестве примера такого рода программного обеспечения можно привести, например, следующие продукты:
- CORBA (OMG) - разрабатываемая консорциумом OMG технология, позволяющая вызывать методы удаленных3Удаленным называется объект, который расположен в памяти другого узла (в противоположность локальному объекту, который расположен в локальной памяти). объектов. Объекты могут быть созданы с использованием разных языков программирования;
- Java (Sun) - технология выполнения промежуточного байт-кода на виртуальной машине. Однажды откомпилированный байт-код может выполняться на любой платформе, для которой реализована JVM ( Java Virtual Machine ), без перекомпиляции;
- .NET (Microsoft) - технология, основанная на выполнении предварительно откомпилированных в промежуточный код компонентов. Такой компонент может выполняться на любой платформе, для которой реализована поддержка библиотеки времени исполнения . NET ;
- Remote Procedure Call (Sun), Java Remote Method Invocation (Sun);
- MPI, PVM и многие другие.
Следует, однако, отметить, что многие из перечисленных средств представляют собой несколько больше, чем просто библиотеку процедур. Часто для того, чтобы использовать одно из этих средств, программа должна быть не только написана, но и спроектирована специальным образом. По сути, производители часто навязывают ту или иную модель архитектуры, поэтому выбор промежуточного программного обеспечения превращается в очень серьезное решение, поменять которое в процессе реализации проекта будет очень сложно (практически невозможно).
Многие современные средства промежуточного программного обеспечения ( middleware ) поддерживают множество полезных сервисов, таких как сервис именования, сервис безопасности, поддержка транзакций, поддержка долговременного хранения объектов, сервис уведомления о событиях и многие другие. Их использование может значительно ускорить разработку приложений, упростить их отладку и сопровождение. Кроме того, их применение может упростить последующую интеграцию с компонентами (или целыми системами) других разработчиков, поскольку эти сервисы часто используют для взаимодействия открытые стандарты.