Чем большую популярность завоевывает Web, тем сложнее становятся Web-узлы. Статические гипертекстовые страницы, подготовленные средствами HTML, встречаются все реже. Практически на каждой домашней странице можно встретить счетчик посещений или часы; большинство сайтов позволяют получить доступ к статистике посещения как отдельных страниц, так и всей их совокупности; многие организации включают в свои страницы формы регистрации пользователей или формы заказов на услуги. Все перечисленные функции не реализованы в Web-серверах. И счетчик посещений, и работа с формой предполагают использование внешней по отношению к серверу программы. Работа Web-мастера все в большей степени состоит из программирования и все в меньшей - из подготовки HTML-страниц. Еще более актуальной тема программирования в Web становится при обсуждении способов создания сетей intranet. Дело в том, что в этом случае сопряжение Web-сервера с системами управления базами данных имеет решающую роль, и без программирования здесь просто не обойтись.
При разработке прикладных программ для Web, кроме столь популярного языка программирования Java можно использовать три технологии: CGI-скрипты, FCGI-приложения и API-интерфейсы. Каждый из этих подходов имеет свои преимущества, равно как и определенные недостатки. Рассмотрим их более подробно.
Common Gateway Interface
Спецификация CGI, разработанная в NCSA, впервые была включена в свободнораспространяемые серверы NCSA. В то время это был колоссальный шаг вперед по сравнению с механизмами подключения внешних программ к серверу CERN. Разработчики сайтов получили простую возможность включить в свои страницы практически все локальные информационные ресурсы организации и таким образом обеспечить удаленный доступ к ним по сети.
Интересно, что параллельно с появлением спецификации CGI в стандарт HTML были введены формы. Собственно, формы и CGI - две стороны одной медали. И формы, и CGI были первоначально предназначены для обмена данными между прикладной программой и программой просмотра гипертекстовых страниц. При этом CGI предполагалось использовать не только в Web, но и для расширения возможностей других информационных технологий Internet.
Вот как в данном случае выглядит взаимодействие с сервером. Программа-браузер отправляет запрос серверу. В качестве URL в запросе используется адрес CGI-скрипта. При этом данные могут содержаться как в самой спецификации URL (компонент пути в схеме HTTP), так и в теле HTTP-сообщения (в случае использования методов POST или PUT). Сервер определяет тип URL, то есть то, что это именно скрипт, а не HTML-страница, либо по маршрутному имени ресурса (обычно - каталог cgi-bin), либо по расширению имени файла (обычно *.cgi). После этого сервер порождает процесс-потомок, передает в него значения переменных окружения, которые порождаются в соответствии со спецификацией CGI, загружает CGI-скрипт и передает ему управление. CGI-скрипт анализирует окружение; если необходимо, считывает данные из потока стандартного ввода, который организован сервером; производит обработку информации, определенную алгоритмом, реализованным в скрипте; и возвращает результат вычислений через свой стандартный вывод в форме, определенной в спецификации CGI. После этого процесс, в котором исполнялся скрипт, завершается. Взаимодействие браузера, сервера и скрипта в этом случае носит разовый характер и по своей природе не ориентировано на длительный диалог, т. е. сессию.
Перечислим основные преимущества такого решения: простота, независимость, выполнение в отдельном адресном пространстве, открытый стандарт, архитектурная независимость.
Простота заключается в том, что прикладному программисту, знакомому с основами программирования для ОС Unix, не требуется изучать каких-либо еще спецификаций. Все взаимодействие прикладной программы с сервером основывается на знании окружения, в котором функционирует программа, и правил ввода/вывода данных через стандартные ввод/вывод. Фактически надо просто, используя функцию getenv(), получить значение переменной окружения и вывести всю информацию через стандартные функции форматной печати - printf(). Если программа работает в режиме обмена данными через командную строку и стандартный вывод, то для ее подключения к серверу необходимо затратить минимум усилий. Сложнее подключать программы с развитым графическим пользовательским интерфейсом, но обычно в "грамотно" написанных программах интерфейсный модуль выделен и допускает простую замену.
Независимость подразумевает возможность написания программы на любом из универсальных языков программирования или скриптов на языках программирования сценариев, например командных языках. В этом случае абсолютно не имеет значения язык, на котором написан сервер. Взаимодействие, организованное через переменные окружения, командную строку и стандартные ввод/вывод, осуществляется всегда одинаково в конкретной операционной среде.
С точки зрения влияния прикладной программы на операционную среду или на сервер спецификация CGI также выглядит безупречно. Скрипт запускается в своем адресном пространстве и никак не влияет на другие компоненты, которые система исполняет одновременно со скриптом.
Спецификация CGI является открытым стандартом. Это означает, что скрипт, написанный для одного сервера, будет прекрасно работать и с другими серверами, поддерживающими спецификацию. В этом легко может убедиться любой, кто пожелает мигрировать, скажем, с сервера NCSA или CERN на Apache или обратно. Единственное исключение составляют продукты Microsoft. Но даже в этом случае, как правило, переносимость скриптов от одного сервера к другому сохраняется.
Спецификация CGI не зависит от платформы. Действительно, в любой операционной среде есть переменные окружения и понятия стандартных потоков ввода, вывода и ошибок. В частности, это позволяет выполнять скрипты, разработанные для ОС Unix, в среде MS-DOS. Типичным примером является скрипт Imagemap. Любопытно, что при переносе его на MS-DOS сохранилась даже ошибка с обработкой конца файла при просмотре описаний разбиения графического образа на фрагменты.
Естественно, что при всех своих несомненных достоинствах CGI имеет и недостатки. Главным из них является низкая скорость реакции на запрос пользователя. В то время, когда NCSA ввел в обращение CGI, количество обращений к сайту было невелико. О масштабах AltaVista или Lycos не могло быть и речи. В этих условиях можно было пренебречь скоростью в угоду простоте и надежности. Главной причиной медленного отклика является порождение полноценного процесса при обращении к скрипту. Это тем более выглядит нелепо, если даже Apache для повышения своей "реактивности" при старте запускает сразу несколько серверов-потомков, ускоряющих обработку запросов пользователей. Если при этом через данных потомков обращаются к CGI-скриптам, то весь выигрыш оказывается потерян.
Другим недостатком скриптов является тот факт, что использовать их можно только для ответа клиенту. Провести их обработку стандартными средствами сервера перед отправкой клиенту уже нельзя. Для этого приходится пользоваться отложенным обращением к результатам работы скрипта, которые предварительно помещаются в файл.
API-интерфейсы
Низкая производительность CGI вызвала к жизни спецификации API-интерфейсов. Суть API-интерфесов заключается в повышении производительности работы сервера за счет того, что новых полноценных процессов не порождается, и либо порождаются потоки, либо сам сервер выполняет необходимые операции по обработке запросов. Наиболее известным API на русскоязычных серверах является модуль автоматической перекодировки раскладок кириллицы, написанный Крюковым для сервера Apache. Этот модуль применяется многими отечественными провайдерами на своих серверах. Его идея состоит в том, что реально хранится только одно дерево документов, а не четыре (cp1251, cp866, koi-8, ISO). Кроме повышения производительности API позволяет повысить мощь сервера за счет добавления новых свойств.
В настоящее время известны NSAPI (API для Netscape), ISAPI (API для IIS), API для Apache и ряд других. Достоинства этого механизма мы уже перечислили. Остановимся на его недостатках.
Серьезнейший недостаток API - это его сложность. Для написания API-приложения необходимы глубокие знания архитектуры сервера и ее реализации. Например, модуль Крюкова кроме компиляции вместе с сервером требует еще и накладывания соответствующих "заплаток" на модули сервера.
Совершенно очевидно, что при программировании API-приложений появляется языковая зависимость. Приложение нельзя написать на командных языках, например PERL.
Выполняется приложение в адресном пространстве сервера. Это значит, что неотлаженное приложение может в случае ошибки привести к сбою в работе сервера. Плохо это и с точки зрения обычной безопасности.
Написанное для определенного сервера приложение не может быть перенесено на другую платформу. Слишком тесно оно завязано на другие компоненты. Кроме этого, многие механизмы обеспечения синхронизации работы частей сервера или его взаимодействия со средой функционирования, как правило, зависят от ОС. Но именно они и используются в API для повышения эффективности работы.
Таким образом, можно сказать, что при несомненно более высокой производительности приложения, реализованные согласно спецификации API, теряют многие замечательные качества CGI-скриптов.
FAST CGI
В этих условиях совершенно естественным шагом стало появление спецификации FAST CGI ("Быстрый" CGI). Заложенная в ней идея довольно проста: совместить преимущества обычного CGI и API. Для этого скрипт должен быть загружен либо в момент старта сервера, либо по требованию клиента и оставаться в памяти так долго, как это необходимо для обслуживания запросов. Нет необходимости создавать полновесный процесс при каждом обращении к скрипту - процесс создается один раз и потом только получает управление и данные от сервера.
Но Fast CGI не только позволяет увеличить производительность приложений, но разрешает включить дополнительную обработку информации, отправляемой клиенту, и расширяет возможности сервера. Для этой цели в спецификацию включено понятие фильтра.
Чисто внешне программы, выполненные в соответствии с требованиями Fast CGI, ничем, кроме включения в начало программы цикла обработки запросов сервера, не отличаются от CGI-скриптов. Канал приложение-сервер циклически опрашивается на предмет наличия запроса от сервера. Конечно, девственность CGI сохранить в Fast CGI не удалось. Сервер должен иметь модуль, который поддерживает взаимодействие с этим типом приложений. Сами приложения также обязаны быть откомпилированы с библиотекой функций Fast CGI. (Это самый простой способ получения нужного результата, так как в противном случае придется писать взаимодействие с сервером по протоколу Fast CGI вручную.)
Сведем теперь преимущества Fast CGI воедино. Производительность Fast CGI существенно выше, чем у CGI, и немногим уступает API. Существуют даже примеры, когда Fast CGI работает быстрее API-приложения. Мигрировать от CGI к Fast CGI гораздо проще, чем к API. Кроме того, Fast CGI можно использовать и просто как обычный CGI. Fast CGI-скрипт можно написать и на простом командном языке. Существуют соответствующие компоненты для Perl и shell. FCGI-скрипт запускается в своем собственном адресном пространстве и не влияет на работу сервера.
Спецификация доступна для широкого спектра как коммерческих, так и свободно распространяемых серверов, что делает скрипты мобильными. Кроме того, FCGI позволяет организовать распределенные вычисления, то есть работать с удаленными информационными ресурсами самостоятельно без сервера, установленного на вычислительной установке, на которой исполняется скрипт.
Некоторые итоги
Выше мы перечислили основные способы расширения возможностей сервера протокола HTTP, которые имеются у разработчика Web-узлов. Однако на самом деле на проблему необходимо взглянуть несколько шире. Решить проблемы конкретного Web-узла можно, используя различные способы, которые предлагают разработчики сервера, избранного в качестве основы для сайтов. Другое дело - распределенная информационная система. Здесь, имея в виду "зоопарк" аппаратных и программных возможностей, придется решать много задач, которые не встают обычно перед администрацией Website. Но где появляются эти системы? Ответ на самом деле один: в системах intranet. Здесь сервер представляет собой только центр, который связывает разные информационные технологии, основной из которых безусловно является ведение корпоративной базы данных. Насколько эффективно будет решаться данная задача, зависит от разработчиков системы и ее жизненного цикла, но выбирать все равно придется только из вышеперечисленных трех вариантов.
Павел Храмцов - руководитель группы РНЦ "Курчатовский Институт". С ним можно связаться по телефону (095) 196-9124 или по электронной почте paul@kiae.su.