Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Технология «клиент-сервер» (Общие сведения о программных системах)

Содержание:

ВВЕДЕНИЕ

Современные программные системы представляют собой совокупность сложных распределенных программ, которые обмениваются друг с другом информацией, способны диагностировать свое состояние и самовосстанавливаться. Их разработка требует особых технологий как в области программирования, так и в области передачи данных.

Актуальность темы исследования заключается в том, что клиент-серверная архитектура на сегодняшний день является крайне распространенной как при проектировании отдельного приложения в многопроцессном или многопоточном режиме, так и при построении сложных информационных систем, включающих множество компьютеров. Современные корпоративные приложения все чаще основываются на серверах сторонних компаний, решающих широкий спектр вопросов, начиная от безопасного хранения данных, до услуг хостинг-провайдеров и удаленных вычислениях.

В качестве объекта исследования данной работы выступает клиент-серверная архитектура.

Предметом исследования являются изучение основных понятий клиент-серверной архитектуры.

Целью данной работы является обобщение имеющейся информации по вопросам функционирования клиент-серверной архитектуры

На основании поставленной цели сформулированы следующие задачи:

1. Проанализировать информации из литературных источников по теме исследования.

2. Провести обзор клиент-серверной архитектуры программных систем.

3. Исследовать современные примеры облачных решений.

4. Разработать программное обеспечение, работающее по клиент-серверной архитектуре.

ГЛАВА 1. ОБЩИЕ СВЕДЕНИЯ О ПРОГРАММНЫХ СИСТЕМАХ

1.1. Основные понятия и терминология программных систем

Программной системой называют, систему, которая включает в себя программное обеспечение. Помимо этого, она содержит в своем составе также аппаратное обеспечение и обычно не рассматривается в отдельности от других программно-аппаратных комплексов.

Программная система начинает свое существование с момента разработки и заканчивает его в момент морального устаревания. Этот период времени называется жизненным циклом программной системы. Данный термин используется в том случае, если подразумевается, что ПО будет функционировать довольно долго, в отличие от сферы экспериментального программирования, где программы создаются для нескольких запусков и после этого не используются [1].

1.2. Основные понятия и терминология архитектуры программных систем

Архитектура прикладного программного обеспечения - это процесс разработки структурированного решения, отвечающего всем техническим и эксплуатационным требованиям, при одновременной оптимизации общих параметров качества, таких как производительность, безопасность и управляемость [2]. Он включает в себя ряд решений, основанных на широком спектре факторов, и каждое из этих решений может оказать значительное влияние на качество, производительность, обслуживаемость и общий успех приложения.

Как и любая другая сложная структура, программное обеспечение должно быть построено на прочной основе. Неспособность рассмотреть ключевые сценарии использования, разработать общие проблемы или оценить долгосрочные последствия ключевых решений, может поставить успех приложения под угрозу. Современные инструменты и платформы помогают упростить задачу создания приложений, но они не заменяют необходимости тщательно разрабатывать ПО на основе конкретных сценариев и требований. Риски, связанные с плохой архитектурой ПО, включают нестабильную работу последнего, невозможность его поддержки и соответствия существующим или будущими требованиями заказчика. Кроме этого, усложняется процесс его развертывания и управления им в производственной среде [3].

Программные системы должны разрабатываться с учетом требований пользователя, специфики ИТ-инфраструктуры предприятия и бизнес-целей. Для каждой из этих областей необходимо определить ключевые сценарии, наиболее важные атрибуты качества (например, надежность или масштабируемость) и ключевые области удовлетворенности и неудовлетворенности. По возможности при разработке необходимо учитывать показатели, которые определяют успех в каждой из этих областей.

Архитектура приложения направлена на создание моста между требованиями бизнеса и техническими требованиями путем понимания вариантов использования программы, а затем поиска способов их реализации в программном обеспечении. Цель архитектуры - определить требования, которые влияют на структуру приложения [4]. Хорошая архитектура снижает риски для бизнеса, связанные с созданием технического решения, а также создает достаточно гибкий каркас приложения, с помощью которого программа будет иметь возможность обрабатывать естественное изменение параметров, которые со временем будут происходить в аппаратных и программных технологиях, а также в пользовательских сценариях и требованиях. Разработчик должен учитывать общий эффект от архитектурных решений, присущие им компромиссы между атрибутами качества (такими как производительность и безопасность) и компромиссы, необходимые для удовлетворения требований пользователя, системы и бизнеса.

1.3. Клиент-серверная архитектура программных систем

Архитектура клиент-сервер описывает системы, которые включают отдельную клиентскую и серверную части, зачастую представляющие собой отдельные компьютеры, соединенные сетью. Простейшая форма клиент-серверной системы включает серверное приложение, к которому напрямую обращаются несколько клиентов.

Исторически архитектура клиент-сервер содержала графическое приложение пользовательского интерфейса рабочего стола, которое сообщалось с сервером базы данных [6], содержащим большую часть бизнес-логики, в виде хранимых процедур или с выделенным файловым сервером. Однако в целом архитектурный стиль клиент-сервер описывает взаимосвязь между клиентом с одним или несколькими серверами, где клиент инициирует один или несколько запросов (возможно, используя графический интерфейс), ждет ответов и обрабатывает ответы при получении. Сервер обычно авторизует пользователя, а затем выполняет обработку запросов, необходимую для генерации результата. Сервер может отправлять ответы с использованием ряда протоколов и форматов данных для передачи информации клиенту [2].

Сегодня некоторые примеры архитектурного стиля клиент-сервер включают:

- программы на основе веб-браузера, работающего в Интернете или в интрасети;

- операционные системы, которые обращаются к сетевым службам данных;

- приложения, обращающиеся к удаленным хранилищам данных (например, почтовые программы, FTP-клиенты и инструменты запросов к базе данных);

- инструменты и утилиты, управляющие удаленными системами (такими как инструменты удаленного управления системой и инструменты сетевого мониторинга).

Кроме этого, данная архитектура может использоваться для взаимодействия между программными компонентами одного компьютера (примером может являться система X Window Server, позволяющая создавать графический интерфейс во многих UNIX подобных системах).

Другие варианты архитектуры клиент/сервер включают:

- Клиент-Очередь-Клиент. Такой подход позволяет клиентам общаться с другими клиентами через очередь, организованную на сервере. Клиенты могут считывать данные и отправлять данные на сервер, который действует просто как очередь для хранения данных. Это позволяет клиентам распространять и синхронизировать файлы и информацию. Это подход иногда называют «архитектурой пассивной очереди». Схема такого подхода представлена на рисунке 1.

Очередь

Клиент N

Клиент 2

Клиент 1

Рисунок 1 – Подход Клиент-Очередь-Клиент.

- Одноранговые (P2P) приложения (Рисунок 2). Разработанный с использованием стиля Клиент-Очередь-Клиент, стиль P2P позволяет клиенту и серверу менять свои роли, чтобы распространять и синхронизировать файлы и информацию между несколькими клиентами [7]. Он расширяет стиль клиент-сервер за счет нескольких ответов на запросы, общих данных, обнаружения ресурсов и устойчивости к удалению соседних компьютеров.

Клиент 1

(Сервер)

Клиент 2

(Сервер)

Клиент 3

(Сервер)

Рисунок 2 – Одноранговые (P2P) приложения.

- Серверы приложений. Специализированный архитектурный стиль, в котором сервер публикует и выполняет приложения и службы, к которым тонкий клиент обращается через браузер или специализированное клиентское программное обеспечение. Примером может служить клиент, исполняющий приложение, которое выполняется на сервере через инфраструктуру, такую как службы терминалов (Рисунок 3).

Служба терминалов

Терминал N

Терминал 2

Терминал 1

Рисунок 3 – Серверы приложений.

Основными преимуществами архитектурного стиля клиент-сервер являются:

- Повышенная безопасность. Все данные хранятся на сервере, который обычно обеспечивает более высокий контроль над безопасностью, чем клиентские машины.

- Централизованный доступ к данным. Поскольку данные хранятся только на сервере, доступ к ним и их обновление гораздо легче администрировать, чем в других архитектурных стилях.

- Простота обслуживания. Роли и обязанности вычислительной системы распределяются между несколькими серверами, которые известны друг другу через сеть.

Архитектурный стиль клиент-сервер необходимо применять, если проектируемое приложение будет работать на сервере и будет поддерживать подключение многих клиентов. Примером могут являться веб-приложения, открытые в веб-браузере. Архитектурный стиль клиент-сервер также подходит, если необходимо централизовать функции хранения, резервного копирования и управления данными или, когда проектируемое приложение должно поддерживать разные типы клиентов и различные устройства.

1.4. Основные стандарты, регламентирующие порядок межмодульного взаимодействия

Недостатком клиент-серверной архитектуры является то, что на сервер сильно возрастает нагрузка. Для решения этой проблемы часто используют несколько серверов, каждый из которых решает отдельные задачи. Так, один сервер может обрабатывать запросы клиентов, второй - выполнять вычисления, третий координирует работу системы и балансирует нагрузку. Обычно в сети серверы соединяются последовательно друг с другом, то есть позвенно. Это приводит к тому, что выход из строя одного из звеньев может серьезно затруднить работу всей системы или даже полностью ее остановить [3].

Для устранения вышеописанных недостатков используются специальные технологии, которые позволяют разбить программу на отдельные компоненты с возможностью их запуска на разных серверах. В этом случае при выходе из строя одного из компьютеров, нужный программный компонент запускается на резервных машинах. Этот процесс контролируют специальные программы-мониторы, которые позволяет компьютерам обмениваться информацией друг с другом и в случае ошибки перезапускать необходимый компонент. Это приводит к значительному повышению надежности системы, а также к появлению возможности динамически перераспределять нагрузку между серверами. Так как в этом случае практически вся вычислительная нагрузка ложится на серверы, то клиентам в основном отводится роль отображения информации и взаимодействия с пользователем. Это дает возможность создавать так называемый сверхтонкие клиенты, которые требуют минимальных вычислительных ресурсов. Благодаря этому, клиентами на сегодняшнем этапе могут являться не только компьютеры, но и мобильные устройства.

Частный случай компонентного подхода — доступ к серверным приложениям из браузеров через Интернет. В качестве примеров компонентных моделей могу служить: JavaBeans (EJB), COM (Component Object Model), .NET, Common Object Request Broker Architecture (CORBA).

Технология SOAP (Simple Object Access Protocol) представляет собой простой протокол доступа к объектам (компонентам распределенной вычислительной системы), основанный на обмене структурированными сообщениями (Рисунок 4). Подобно любому протоколу, основанному на текстовых сообщениях, SOAP может использоваться с любым протоколом прикладного уровня: SMTP, FTP, HTTPS и др., но чаще всего SOAP используется поверх HTTP.

Все сообщения SOAP оформляются в виде структуры, называемой конвертом (envelop), включающей следующие элементы:

- Идентификатор сообщения (локальное имя).

- Опциональный элемент Header (заголовок):

•Ноль или более ссылок на используемые пространства имен;

•Ноль или более свойств, доступных в этом пространстве имен.

- Обязательный элемент Body (тело сообщения):

•Ноль или более ссылок на используемые пространства имен;

•Дочерние элементы тела сообщения

Развернутый список элементов сообщения SOAP приведен в схеме данных (для SOAP версии 1.2) [8].

Пример сообщения SOAP:

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">

<env:Header>

<n:alertcontrol xmlns:n="http://example.org/alertcontrol">

<n:priority>1</n:priority>

<n:expires>2001-06-22T14:00:00-05:00</n:expires>

</n:alertcontrol>

</env:Header>

<env:Body>

<m:alert xmlns:m="http://example.org/alert">

<m:msg>Get up at 6:30 AM</m:msg>

</m:alert>

</env:Body>

</env:Envelope>

Модель подключения SOAP показана на рисунке 4.

Интернет

Soap – сервер

Хранилище

Soap – клиент 3

Soap – клиент 1

Soap – клиент 2

Рисунок 4 – Технология SOAP.

Другой технологией, позволяющей обмениваться сообщениями в распределенных системах является язык разметки XML (Extensible Markup Language), позволяющий использовать обычный текст, обрамленный специальными тэгами, тем самым превращая его в информацию, которая может идентифицироваться и сортироваться. По сути, все документы, которые основаны на языках разметки представляют собой текст в совокупности с тэгами. Тэги позволяют правильно обрабатывать и отображать информацию, заложенную в документе. Одним из основных преимуществ XML является то, что в своей основе он имеет текстовый формат, который может быть легко прочитан и понят человеком. Таким образом, даже после выхода из строя системы обработки информации, данные остаются читабельными. Ниже показан пример описания котировок валют в XML формате:

<ValCurs Date="02.03.2002" name="Foreign Currency Market">

<Valute ID="R01010">

<NumCode>036</NumCode>

<CharCode>AUD</CharCode>

<Nominal>1</Nominal>

<Name>Австралийский доллар</Name>

<Value>16,0102</Value>

</Valute>

<Valute ID="R01035">

<NumCode>826</NumCode>

<CharCode>GBP</CharCode>

<Nominal>1</Nominal>

<Name>Фунт стерлингов Соединенного королевства</Name>

<Value>43,8254</Value>

</Valute>

</ValCurs>

Языки разметки прошли путь от первых форм, создававшихся компаниями и госучреждениями, до Стандартного языка обобщенной разметки (Standard Generalized Markup Language - SGML), гипертекстового языка разметки (Hypertext Markup Language - HTML) и в итоге до XML. SGML может показаться сложным, а HTML (который, по сути, сначала был просто набором элементов) оказался недостаточно мощным для идентификации информации [4]. XML разрабатывался как простой в применении и удобный для расширения язык разметки.

ГЛАВА 2. ОСОБЕННОСТИ ОБЛАЧНЫХ СЕРВЕРОВ ПРИЛОЖЕНИЙ

Среди современных применений клиент-серверных архитектур все большее применение находит концепция облачных вычислений. Облачные вычисления можно назвать парадигмой, подразумевающей распределенную и удалённую обработку и хранение информации. Под значением слова «облако» можно понимать дата-центр, обладающий значительными возможностями в области обработки и хранения данных. Дата-центр зачастую представляет собой совокупность взаимосвязанных серверов. К понятию облачного ресурса можно отнести, как ПО (приложение, открывающееся с помощью Web-интерфейса), так и инфраструктуру, такую как сервер [9].

Выделим критерии, характеризующие облачный сервис:

- пользователю предоставляется возможность использовать сервис с помощью Web-браузера или же с помощью API (интерфейс прикладного программирования, использующегося для доступа к Web-сервисам);

- для пользования сервисом не требуется вычислительных ресурсов;

- пользователь оплачивает время использования сервиса.

Облачные сервисы можно разделить на сервисы инфраструктуры и программные сервисы.

Software as a Service (SaaS, программное обеспечение как услуга) — это одна из концепций облачных услуг, которая позволяет пользователю использовать работающее в облаке программное обеспечение. Стоит отметить, что большинство облачных систем на сегодняшний день предоставляют именно SaaS услуги [10]. Следуя концепции SaaS, пользователь берёт программный продукт в аренду, вместо того чтобы покупать его. В отличие от обычных пакетов программного обеспечения, пользователь платит только за те услуги (программы), которые ему необходимы.

Как пример подобных систем, можно привести набор сервисов для работы с документами, в частности Google Docs и Office Web Apps, разработанные компаниями Google и Microsoft соответственно.

Перечислим некоторые характеристики присущие системе SaaS [11]:

- оплата осуществляется только за фактическое использование (только за то время, в которое использовались сервисы);

- требования, предъявляемые к IT инфраструктуре клиента – минимальны;

- доступ осуществляется чаще всего через Web-браузер;

- пользователь получает мгновенный доступ к системе после регистрации на сервисе;

Для пользователя наибольшее преимущество заключается в получении более быстрого доступа к функционалу и относительном уменьшении затрат, необходимых на развертывание и автономное поддержание работы программ.

PaaS, платформа как сервис, предоставляет инфраструктуру, а также функционально полные среды для разработки и последующего обслуживания пользовательских приложений.

Потребители могут использовать ресурсы, размещенные в облаках: операционные системы, системы управления базами данных, прочее ПО. В этой модели вся ИТ - инфраструктура, включая сети, серверы и системы хранения полностью управляется поставщиком услуги. Поставщик определяет тип платформы и набор вариантов хостинга, а потребители используют эту платформу и приложения.

IaaS, инфраструктура как сервис, облачная инфраструктура предоставляется для хранения, управления ресурсами обработки [14]. Это одна из моделей обслуживания в облачных вычислениях, такая, что пользователям, на основе подписки, предоставляются ИТ ресурсы — виртуальные серверы с заданной вычислительной мощностью, операционной системой, как правило, предустановленной поставщиком в виде шаблона и доступом к сети. Популярным программным решением для создания IaaS является OpenStack.

Сравнение классической системы, IaaS, PaaS и SaaS показано на рисунке 5.

Управляется поставщиком

Управляется пользователем

Собственная ИТ инфраструктура

SaaS

Приложение

Данные

Среда исполнения

Операционная система

Виртуализация

Серверы

Хранилища

Сеть

Сеть

Хранилища

Серверы

Виртуализация

Операционная система

Среда исполнения

Данные

Приложение

PaaS

Сеть

Хранилища

Серверы

Виртуализация

Операционная система

Среда исполнения

Данные

Приложение

IaaS

Сеть

Хранилища

Серверы

Приложение

Данные

Среда исполнения

Операционная система

Виртуализация

Рисунок 5 – классическая система, IaaS, PaaS и SaaS.

Рассмотрим модели развёртывания облачных сервисов. Выделяется четыре вида облаков [12]:

- частное,

- публичное,

- общественное,

- гибридное.

Частное облако, как правило, используется одной организацией, имеющей несколько конечных потребителей, в качестве примера таких потребителей можно привести различные подразделения входящие в состав организации.

Публичное облако, как правило, используется широкой публикой со свободным доступом.

Общественное облако, как правило, используется сообществом потребителей из различных организаций, имеющие общие цели.

Гибридное облако – сочетание не меньше двух разных инфраструктур, являющихся уникальными объектами, но взаимосвязанные частными или стандартизованными технологиями передачи данных [13].

Обязательные характеристики облачных вычислений, которые были зафиксированы национальным институтом стандартов и технологий США [15]:

- самообслуживание по требованию,

- универсальный доступ по сети,

- объединение ресурсов,

- эластичность,

- учёт потребления.

Ещё одним немаловажным элементом, использующийся в большей части бизнес-приложений, являются транзакционные вычисления. Под транзакционной системой подразумевают, такую систему, в которой поступающие наборы данных обрабатываются совместно в пределах единой транзакции что обеспечивает целостность данных. Реляционная база данных, как правило является основой транзакционной системы, управляющая взаимоотношениями среди всех данных, образующих систему. Web-сайты и Web-приложения, которые используются в повседневной жизни, в большинстве своём представляют собой ту или иную форму транзакционной системы. Чтобы повысить отказоустойчивость, все эти компоненты способны формировать кластеры, а логика представления данных и бизнес-логика должны управляться балансировщиком нагрузки, который, в свою очередь, уменьшает время вычисления и оптимизирует использование ресурсов, благодаря распределению процессов выполнения заданий между серверами сети.

Теперь рассмотрим две основные модели облачных инфраструктур, такие как Amazon Web Services и Microsoft Azure.

Модель Amazon Web Services имеет широкий диапазон сервисов, каждый из которых содержит в себе концепцию облачной обработки данных. Основными сервисами можно считать:

- Amazon Elastic Cloud Compute (EC2);

- Amazon Simple Storage Service (S3);

- Amazon Simple Queue Service (SQS);

- Amazon CloudFront;

- Amazon SimpleDB.

Из перечисленных сервисов две технологии вызывают наибольший интерес, это технологии Amazon S3 и Amazon EC2.

Web-интерфейс Amazon EC2 предоставляет возможность получить права доступа к вычислительным мощностям и произвести настройку с затратами ресурсов, близкими к минимальным. Пользователь имеет доступную среду для продуктивной работы и полный контроль над вычислительными ресурсами [13].

Amazon S3 даёт возможность получать и хранить данные любого объёма, в какое угодно время из какой угодно точки сети. Сервис позволяет достигнуть высокой надёжности и масштабируемости, при относительно недорогой инфраструктуре хранения данных.

Можно выделить 5 основных ориентиров на которых спроектированы Amazon Web Services. Этот характерный подход можно считать широко используемым у большинства поставщиков облачных услуг и использовать для описания актуального положения рынка облачных услуг.

  • Функциональное совершенство

Компонент функционального совершенства фокусируется на том, как пользователь может постоянно улучшать свою способность управлять системами, создавать более совершенные процессы и получать аналитическую информацию.

При взгляде на операционное превосходство в облаке, полезно взглянуть на него с точки зрения автоматизации. Человеческий фактор - основная причина дефектов и неисправностей. Чем больше операций можно автоматизировать, тем меньше вероятность человеческой ошибки. Автоматизация не только позволяет избежать ошибок, но и помогает постоянно улучшать внутренние процессы. Они продвигают ряд повторяемых передовых практик, которые можно применять в вашей компании.

  • Безопасность

Компонент безопасности фокусируется на том, как пользователь может защитить свою инфраструктуру в облаке. Безопасность и соответствие нормативным требованиям — это общая ответственность AWS и клиента. В этой модели совместной ответственности AWS отвечает за безопасность облака, что включает в себя физическую инфраструктуру, программное обеспечение и сетевые функции облачных сервисов AWS. Заказчик несет ответственность за безопасность в облаке, что включает настройку определенных облачных служб, прикладного программного обеспечения и управление конфиденциальными данными.

При взгляде на безопасность в облаке, полезно принять модель нулевого доверия. В этой модели все компоненты и сервисы приложения рассматриваются как отдельные и потенциально опасные объекты. Это включает в себя базовую структуру сети, любых агентов, которые имеют доступ к ресурсам пользователя, а также программное обеспечение, работающее в службе пользователя.

  • Надежность

Компонент надежности фокусируется на том, как пользователь может создавать сервисы, устойчивые как к сбоям в обслуживании, так и к сбоям инфраструктуры. Подобно эффективности энергопотребления, облако дает вам возможность создавать отказоустойчивые сервисы, которые могут противостоять сбоям, и требует, чтобы пользователь планировал свои сервисы с учетом надежности.

При взгляде на надежность в облаке, полезно продумать "радиус взрыва" - максимальный ущерб, который может быть выдержан в случае отказа системы. Чтобы построить надежные системы, необходимо свести к минимуму "радиус взрыва" отдельных компонентов.

  • Производительность

Компонент производительности фокусируется на том, как пользователь может эффективно и масштабируемо запускать службы в облаке. Хотя облако дает пользователю свободу обрабатывать любой трафик, необходимо выбрать и настроить услуги для масштабирования.

Согласно локальной модели, серверы были дорогими и часто предоставлялись и настраивались вручную. Доставка сервера и его физическое подключение к центру обработки данных могут занять несколько недель.

Облачный образ мыслей о серверах выглядит следующим образом. Серверы — это сырьевые ресурсы, которые можно автоматически сделать доступными за секунды. Ни один конкретный сервер не должен быть необходим для работы сервиса.

  • Оптимизация затрат

Компонент оптимизации затрат помогает достичь бизнес-результатов и в то же время минимизировать затраты.

При взгляде на оптимизацию затрат в облаке, необходимо понимать, что расходы в облаке - OpEx, а не CapEx. OpEx — это постоянная модель оплаты по мере использования, а CapEx — это модель разовой покупки.

Традиционные затраты на ИТ в локальных центрах обработки данных в основном были капитальными. Оплата происходит за всю емкость авансом, независимо от того, используется ли такая емкость в итоге. Покупка новых серверов может оказаться длительным процессом, требующим участия нескольких сторон. Это связано с тем, что капитальные затраты часто были значительными, а иногда и дорогостоящими, поставка после приобретения серверов может занять несколько недель после совершения покупки.

В AWS расходы составляют OpEx. Оплачивается только используемая мощность. Поставка новых серверов может производиться инженерами в реальном времени без необходимости длительного процесса утверждения. Это связано с тем, что операционные расходы намного ниже и могут быть отменены при изменении требований. Поскольку оплачивается только то, что используется, любую избыточную мощность можно легко остановить и прекратить. После выбора услуги ее можно подготовить за секунды и минуты.

Далее коротко рассмотрим Microsoft Azure, являющаяся облачной платформой от компании Microsoft. Сервис даёт возможность разрабатывать и выполнять приложения и хранить данные на серверах, в распределённых ЦОДах.

Из особенностей модели стоит отметить:

- Плата только за использованные ресурсы,

- Абстракция от инфраструктуры,

- Многопоточная структура вычислений.

MS Azure объединяет в себе две облачные модели: IaaS и PaaS. IaaS обеспечивает запуск виртуальной машины для каждого экземпляра приложения, в то время как PaaS обеспечивает функции операционной системы, и другие дополнительные функции.

Производитель предоставляет инструменты для миграции от классической модели ИТ инфраструктуры к гибридной или полной миграции в облако:

- Поддержка ключевых сценариев переноса серверов, данных, баз данных, веб-приложений и виртуальных рабочих столов.

- Комплексные возможности обнаружения, оценки и миграции на базе платформы Azure и средств партнеров.

- Централизованный репозиторий миграции, обеспечивающий комплексное отслеживание и аналитику.

- Экономная миграция с помощью функций и средств оптимизации затрат Azure.

Microsoft заявляет о следующих преимуществах миграции:

- Экономия до 80% на стоимости приобретения лицензий Windows Server.

- Повышение продуктивности ИТ-специалистов до 25 %.

Общий вид типового личного кабинета, панели управления облачным сервисом показан на рисунке 6.

Рисунок 6 – Технология SOAP.

Глобальная облачная инфраструктура AWS, предлагает более 175 полнофункциональных сервисов в центрах обработки данных (ЦОД) по всему миру, охватывая 245 стран и регионов.

Глобальная инфраструктура Azure включает в себя более 160 физических ЦОД.

Благодаря такому географическому распределению ЦОД можно создать облачную инфраструктуру с учетом всех требований. Например, быстро запустить приложение с доступом по всему миру и легко управлять рабочими нагрузками или развернуть приложение ближе к конечным пользователям, чтобы обеспечить задержку не более нескольких миллисекунд.

По состоянию на 2020 год AWS занимает 31% доли облачного рынка, Azure - 20%.

ГЛАВА 3. РАЗРАБОТКА КЛИЕНТ-СЕРВЕРНЫХ ПРИЛОЖЕНИЙ С ИСПОЛЬЗОВАНИЕМ ПРОТОКОЛА UDP

В данной работе были разработаны программы, обеспечивающие обмен данными по сети с помощью протокола UDP. Код написан на языке С. Разработанные программы делятся на сервер (timeserv) и клиент (timecli). Они предназначены для передачи по сети времени сервера.

Этот проект состоит из простого UDP сервера и клиентских программ. Сервер работает на локальном компьютере, ожидая запроса датаграммы с удаленного компьютера, запрашивающего текущее время сервера. Затем сервер возвращает свое текущее время клиенту, который, в свою очередь, отображает его.

UDP означает протокол пользовательских Дейтаграмм. Клиент отправляет датаграмму на сервер, который обрабатывает данные и возвращает ответ. UDP – это минимальный протокол транспортного уровня, ориентированный на сообщениях, который задокументирован в RFC 768. Протокол UDP не предоставляет никаких гарантий передачи. По этой причине UDP иногда называют ненадежным протоколом [3].

Ряд свойств UDP делают его особенно подходящим для определенных приложений.

- Он ориентирован на транзакции, подходит для простых протоколов запроса-ответа, таких как система доменных имен или протокол сетевого времени.

- Подходит для моделирования других протоколов, таких как IP-туннелирования или удаленного вызова процедур и сетевая файловой системы.

- Подходит для загрузки или других целей не требующих полного стека протоколов, таких как DHCP и тривиальный протокол передачи файлов.

- Используется при большом числе клиентов, к примеру в потоковых медиа-приложениях, таких как IPTV.

- Отсутствие задержек ретрансляции делает его подходящем для приложений в режиме реального времени, таких как Voice over IP, онлайн-игры и многие протоколы, построенные на основе протокола потокового вещания в режиме реального времени.

3.1. Серверная программа

Программа-сервер — это простой UDP сервер, который ждет датаграммы от клиентов. Когда он получает датаграмму, содержащую текст "GET TIME\r\n", она возвращает время текущего сервера клиенту.

Прежде чем вызывать какие-либо функции сокета, необходимо сначала открыть подключение Windows. Это делается с помощью функции WSAStartup (рисунок 7).

Рисунок 7 - Фрагмент кода, обеспечивающий открытие соединения Windows на сервере.

Шестнадцатеричное число 0x0101 — это версия используемого winsock, а переменная w является структурой формы WSADATA.

Следующий шаг-открыть сокет датаграмм для UDP. Это делается с помощью функции сокета, которая возвращает дескриптор сокета (рисунок 8).

Рисунок 8 – Фрагмент кода, обеспечивающий открытие сокета датаграмм UDP на сервере.

AF_INET указывает семейство для использования, и SOCK_DGRAM сообщает функции, которые необходимо использовать UDP вместо TCP/IP.

После этого необходимо заполнить некоторую информацию о сервере в структуре типа sockaddr_in. Во-первых, память в структуре очищается (рисунок 7). Затем устанавливается семейство серверов, которое всегда AF_INET. Номер порта задается с помощью функции htons. В зависимости от введенных параметров командной строки сервер либо попытается получить свой IP-адрес, который является предпочтительным методом работы, либо, если это не сработает, его можно указать вручную. Чтобы автоматически получить адрес компьютера-сервера, вызывается функция gethostname, а затем вызовом функции возвращает указатель на структуру типа hostent. Наконец, каждый компонент адреса в ххх.xxx.xxx.xxx копируется в структуру сервера.

Рисунок 9 – Фрагмент кода обеспечивающий назначение IP-адресов на сервере.

Переменные A1, A2, A3 и A4 являются компонентами адреса сервера в форме xxx.xxx.xxx.xxx, введенные в командной строке.

Следующим шагом является привязка адреса сервера к сокету, созданному функцией сокета. Это делается с помощью функции bind, которая возвращает -1, если возникла ошибка (рисунок 10).

Рисунок 10 – Привязка адреса сервера к сокету.

Теперь сервер готов прослушивать датаграммы от клиентов. Это делается с помощью функции recvfrom (рисунок 11). Buffer — это буфер для хранения полученных датаграмм, и BUFFER_SIZE — это максимальное число байт, которое нужно получить. Client — это структура типа sockaddr_in, содержащая сведения о клиенте, отправляющем датаграмму, включая адрес клиента.

Рисунок 11 – Фрагмент кода сервера, обеспечивающий прием данных от клиента.

После того, как дейтаграмма была получена сервером, сервер сравнивает данные в дейтаграмме со строкой "GET TIME\r\n" (рисунок 12). Если эти строки совпадают, сервер возвращает время. В противном случае запрос отклоняется как недопустимый запрос. Время отправляется обратно клиенту с помощью функции "send to".

Рисунок 12 – Фрагмент кода сервера, который обеспечивает обмен данными с клиентом.

После этого сервер возвращается в цикле обратно в функцию recvfrom.

3.2. Клиентская программа

Клиентская программа представляет собой простой UDP клиент, который отправляет запрос на сервер, чтобы получить текущее время. Во-первых, открывается соединение в Windows (рисунок 13). Затем открывается сокет. Далее адрес сервера копируется в структуру server. Этот код похож на код для сервера.

Рисунок 13 – Открытие соединения на клиенте.

В клиенте UDP необходимо знать IP-адрес клиентского компьютера. Это можно сделать автоматически или вручную с помощью аргументов командной строки. Код почти идентичен коду для назначения адреса серверу, за исключением того, что номер порта для клиента равен нулю client.sin_port = htons(0);, где client является структурой типа sockaddr_in (рисунок 14).

Рисунок 14 – Настройка порта на клиенте.

Следующим шагом является привязка адреса клиента к сокету. Этот код почти идентичен коду для сервера (рисунок 15).

Рисунок 15 – Привязка адреса к сокету на клиенте.

Теперь пришло время отправить запрос на сервер на текущее время. Для этого используется функция sendto (рисунок 16):

Рисунок 16 – Фрагмент кода, обеспечивающий отправку запроса на сервер.

send_buffer является строкой, содержащей текст "GET TIME\r\n" и заканчивается нулевым терминатором.

После отправки запроса на время ответ с сервера будет отправлен обратно. Это делается с помощью функции recvfrom:

Рисунок 17- Получение и отображение времени сервера на клиенте.

Сurrent_time - переменная типа time_t, которая хранит время.

Последний шаг заключается в закрытии сокета и подключения Windows. Сокет закрывается с помощью функции closesocket функции, и WSACleanup используется для закрытия подключения Windows.

3.3. Использование серверной программы

Синтаксис серверной программы timeserv [адрес сервера] порт (рисунок 18). Порт-номер порта, для запуска сервера. Рекомендуется выбрать номер порта выше 1023, так как нижние номера портов могут быть назначены другим протоколам. Необязательный параметр адрес_сервера - локальный IP-адрес компьютера, вошел в формате ХХХ.ХХХ.ХХХ.ХХХ. Если этот параметр не указан, программа попытается автоматически получить адрес. Для выхода из программы-сервера необходимо нажать сочетание клавиш Ctrl+C

Рисунок 18 – Запуск программы-сервера.

3.4. Использование клиентской программы

Прежде чем запускать клиентскую программу, необходимо убедиться, что серверная программа запущена на компьютере сервера. Синтаксис для клиента программа timecli адрес_сервера [адрес клиента] порт. Адрес сервера — это адрес компьютера в формате xxx.xxx.xxx.xxx, на котором запущен компьютер сервера. Параметр порт — это порт, на котором запущен сервер. Необязательный параметр адрес клиента переопределяет автоматическое создание локальных адресов для клиентского компьютера и аналогичен приведенной выше серверной программе. Например, чтобы подключиться к серверу с адресом 192.168.1.102, работающему на порту 5000, необходимо ввести timecli 192.168.1.102 5000.

Рисунок 19 – Запуск программы-клиента.

В данном разделе представлена разработка программ, использующих протокол UDP для обмена данными по сети. Программы построены по клиент-серверной архитектуре и обеспечивают передачу данных о системном времени.

ЗАКЛЮЧЕНИЕ

В данной курсовой работе было проведено исследование на тему «Программная архитектура клиент-сервер».

Структура курсовой работы состоит из введения, трех глав, заключения и списка литературы. Также работа содержит приложение с исходными кодами созданных программ.

В первой главе проведен обзор общих понятий о программных системах, классификация их архитектур, вопросы создания.

На сегодняшний день существует довольно большое количество архитектур программных систем. Тем не менее их можно условно разделить на автономные приложения и клиент-серверные приложения. Именно клиент-серверные архитектуры и их модификации составляют основу современной IT индустрии. Использование той или иной их разновидности зависит от конкретных задач, которые решает программная система и бюджета организации, для которой она создается. Наиболее совершенными являются программные системы на основе распределенной архитектуры.

Распределенные архитектуры породили необходимость в новых способах универсальной и простой передачи данных между компьютерами. Наибольшую популярность получил язык разметки XML, благодаря своей простоте и универсальности.

Во второй главе рассматривались вопросы организации облачных сервисов, которые являются одним из подтипов клиент-серверной архитектуры и получили на сегодняшний день значительное распространение.

В третьей главе представлена практическая часть работы. В ней были разработаны демонстрационные программы клиента и сервера, выполняющие обмен данными по сетевому протоколу.

СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ

1. Мартин, Дж. Вычислительные сети и распределенная обработка данных: программное обеспечение, методы и архитектура / Дж. Мартин. - М.: Финансы и статистика, 1985. - 525 c

2. Поль, М. Дюваль Непрерывная интеграция. Улучшение качества программного обеспечения и снижение риска / Поль М. Дюваль, Стивен Матиас, Эндрю Гловер. - Москва: ИЛ, 2016. - 240 c.

3. Дюваль Непрерывная интеграция. Улучшение качества программного обеспечения и снижение риска / Дюваль, М. Поль. - М.: Вильямс, 2012. - 240 c.

4. Котляров, В. П. Основы тестирования программного обеспечения / В.П. Котляров, Т.В. Коликова. - М.: Интернет-университет информационных технологий, Бином. Лаборатория знаний, 2013. - 288 c.

5. Котляров, В.П. Основы тестирования программного обеспечения / В.П. Котляров. - М.: Интернет-Университет Информационных Технологий (ИНТУИТ), 2015. - 579 c.

6. Абельсон, Х.; Сассман, Дж. Структура и интерпретация компьютерных программ; М.: Добросвет - Москва, 2012. - 608 c.

7. Баррон, Дэвид Введение в языки программирования; М.: Мир - Москва, 2011. - 192 c

8. Ерофеев, В.И.; Меркушов, Ю.П. и др. Средства отладки программ в ОС ЕС; Статистика - Москва, 2012. - 245 c.

9. Зелковиц, М. Принципы разработки программного обеспечения / М. Зелковиц, А. Шоу, Дж. Гэннон. - Москва: РГГУ, 1982. - 364 c.

10. Роббинс, Джон Отладка приложений для Microsoft .NET и Microsoft Windows (+CD-ROM); М.: Microsoft Press. Русская Редакция - Москва, 2015. - 736 c

11. Робинсон, С.; Корнес, О.; Глинн, Д. и др. C# для профессионалов; М.: Лори - Москва, 2012. - 996 c.

12. Семашко, Г.Л.; Салтыков, А.И. Программирование на языке Паскаль; М.: Наука - Москва, 2010. - 128 c.

13. Фролов, А.В.; Фролов, Г.В. Локальные сети персональных компьютеров. Работа с сервером Novell NetWare; Диалог-Мифи - Москва, 2010. - 168 c.

14. Холл, П. Вычислительные структуры: Введение в нечисленное программирование; М.: Мир - Москва, 2010. - 214 c.

15. Иванова Г.С. Основы программирования: Учебник для вузов. - М.: Изд-во МГТУ им. Н.Э. Баумана, 2002. - 416 с.

16. Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. - М.: МЦНМО, 2009. - 960с.

17. Левитин В. Алгоритмы: введение в разработку и анализ.: Пер. с англ. - М.: Вильяме, 2006.

18. Окулов С.М. Основы программирования. - 3-е изд. - М.: БИНОМ. Лаборатория знаний, 2006. - 440с.

19. Орлов С. Технологии разработки программного обеспечения. - СПб.: Питер, 2005

20. Сырецкий Г. Информатика. Фундаментальный курс. Том 1. Основы информационной и вычислительной техники.: БХВ-Петербург, 2005 - 832 с.

ПРИЛОЖЕНИЕ

Исходный код программы timecli

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <winsock.h>

#define SIZE 500

void usage(void);

int main(int argc, char **argv)

{

WSADATA w;

unsigned short port_number;

SOCKET sd;

int server_length;

char send_buffer[SIZE] = "GET TIME\r\n";

time_t current_time;

struct hostent *hp;

struct sockaddr_in server;

struct sockaddr_in client;

int a1, a2, a3, a4;

int b1, b2, b3, b4;

char host_name[256];

/* Проверяем аргументы командной строки */

if (argc != 3 && argc != 4)

{

usage();

}

if (sscanf(argv[1], "%d.%d.%d.%d", &a1, &a2, &a3, &a4) != 4)

{

usage();

}

if (sscanf(argv[2], "%u", &port_number) != 1)

{

usage();

}

if (argc == 4)

{

if (sscanf(argv[3], "%d.%d.%d.%d", &b1, &b2, &b3, &b4) != 4)

{

usage();

}

}

/* Открываем соединение Windows */

if (WSAStartup(0x0101, &w) != 0)

{

fprintf(stderr, "Could not open Windows connection.\n");

exit(0);

}

/* Открываем сокет */

sd = socket(AF_INET, SOCK_DGRAM, 0);

if (sd == INVALID_SOCKET)

{

fprintf(stderr, "Could not create socket.\n");

WSACleanup();

exit(0);

}

/* Очищаем структуру server */

memset((void *)&server, '\0', sizeof(struct sockaddr_in));

/* Устанавливаем семейство и порт */

server.sin_family = AF_INET;

server.sin_port = htons(port_number);

/* Устанавливаем адрес сервера */

server.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)a1;

server.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)a2;

server.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)a3;

server.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)a4;

/* Очищаем структуру client */

memset((void *)&client, '\0', sizeof(struct sockaddr_in));

/* Устанавливаем семейство и порт */

client.sin_family = AF_INET;

client.sin_port = htons(0);

if (argc == 3)

{

/* Получаем имя компьютера */

gethostname(host_name, sizeof(host_name));

hp = gethostbyname(host_name);

/* Проверяем указатель */

if (hp == NULL)

{

fprintf(stderr, "Could not get host name.\n");

closesocket(sd);

WSACleanup();

exit(0);

}

/* Назначаем адрес */

client.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0];

client.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];

client.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];

client.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];

}

else

{

client.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)b1;

client.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)b2;

client.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)b3;

client.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)b4;

}

/* Привязываем адрес к сокету */

if (bind(sd, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1)

{

fprintf(stderr, "Cannot bind address to socket.\n");

closesocket(sd);

WSACleanup();

exit(0);

}

/* Передаем запрос на получение времени */

server_length = sizeof(struct sockaddr_in);

if (sendto(sd, send_buffer, (int)strlen(send_buffer) + 1, 0, (struct sockaddr *)&server, server_length) == -1)

{

fprintf(stderr, "Error transmitting data.\n");

closesocket(sd);

WSACleanup();

exit(0);

}

/* Получаем время */

if (recvfrom(sd, (char *)&current_time, (int)sizeof(current_time), 0, (struct sockaddr *)&server, &server_length) < 0)

{

fprintf(stderr, "Error receiving data.\n");

closesocket(sd);

WSACleanup();

exit(0);

}

/* Отображаем время */

printf("Current time: %s", ctime(&current_time));

closesocket(sd);

WSACleanup();

return 0;

}

void usage(void)

{

fprintf(stderr, "Usage: timecli server_address port [client_address]\n");

exit(0);

}

Исходный код программы timeserv

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <winsock.h>

#include <time.h>

#define BUFFER_SIZE 4096

void usage(void);

int main(int argc, char **argv)

{

WSADATA w; /* Used to open windows connection */

unsigned short port_number;

int a1, a2, a3, a4;

int client_length;

int bytes_received;

SOCKET sd;

struct sockaddr_in server

struct sockaddr_in client;

char buffer[BUFFER_SIZE];

struct hostent *hp;

char host_name[256];

time_t current_time

if (argc == 2)

{

if (sscanf(argv[1], "%u", &port_number) != 1)

{

usage();

}

}

else if (argc == 3)

{

if (sscanf(argv[1], "%d.%d.%d.%d", &a1, &a2, &a3, &a4) != 4)

{

usage();

}

if (sscanf(argv[2], "%u", &port_number) != 1)

{

usage();

}

}

else

{

usage();

}

/* Открытие соединения Windows */

if (WSAStartup(0x0101, &w) != 0)

{

fprintf(stderr, "Could not open Windows connection.\n");

exit(0);

}

/* Открытие сокета */

sd = socket(AF_INET, SOCK_DGRAM, 0);

if (sd == INVALID_SOCKET)

{

fprintf(stderr, "Could not create socket.\n");

WSACleanup();

exit(0);

}

/* Очистка структуры */

memset((void *)&server, '\0', sizeof(struct sockaddr_in));

/* Установка семейства и порта */

server.sin_family = AF_INET;

server.sin_port = htons(port_number);

/* Автоматическая установка адресов при необходимости */

if (argc == 2)

{

/* Получение имени компьютера */

gethostname(host_name, sizeof(host_name));

hp = gethostbyname(host_name);

/* Проверка указателя */

if (hp == NULL)

{

fprintf(stderr, "Could not get host name.\n");

closesocket(sd);

WSACleanup();

exit(0);

}

/* Назначение адресов */

server.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0];

server.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];

server.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];

server.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];

}

/* В противном случае назначаем адреса вручную */

else

{

server.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)a1;

server.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)a2;

server.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)a3;

server.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)a4;

}

/* Присоединение адреса к сокету */

if (bind(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1)

{

fprintf(stderr, "Could not bind name to socket.\n");

closesocket(sd);

WSACleanup();

exit(0);

}

printf("Server running on %u.%u.%u.%u\n", (unsigned char)server.sin_addr.S_un.S_un_b.s_b1,

(unsigned char)server.sin_addr.S_un.S_un_b.s_b2,

(unsigned char)server.sin_addr.S_un.S_un_b.s_b3,

(unsigned char)server.sin_addr.S_un.S_un_b.s_b4);

printf("Press CTRL + C to quit\n");

while (1)

{

client_length = (int)sizeof(struct sockaddr_in);

/* Получение данных от клиента */

bytes_received = recvfrom(sd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client, &client_length);

if (bytes_received < 0)

{

fprintf(stderr, "Could not receive datagram.\n");

closesocket(sd);

WSACleanup();

exit(0);

}

/* Проверка запроса времени */

if (strcmp(buffer, "GET TIME\r\n") == 0)

{

/* Получение текущего времени */

current_time = time(NULL);

/* Отправление данных */

if (sendto(sd, (char *)&current_time, (int)sizeof(current_time), 0, (struct sockaddr *)&client, client_length) != (int)sizeof(current_time))

{

fprintf(stderr, "Error sending datagram.\n");

closesocket(sd);

WSACleanup();

exit(0);

}

}

}

closesocket(sd);

WSACleanup();

return 0;

}

void usage(void)

{

fprintf(stderr, "timeserv [server_address] port\n");

exit(0);

}