2004 г.
Интеграция Tomcat с Apache. Развертывание веб-приложений Java2 на Linux-платформе
Олег Ремизов, "Комиздат"
Итак - ваше веб-приложение готово для развертывания на сервере. Заказчик оповещен о том, что все работает и осталось только несколько штрихов, - и он просит продемонстрировать это веб-приложение, разместив его на вашем сервере или на сервере заказчика. Как правило, это Linux. Пока проект жил и творился под бдительным контролем RAD-среды, например JBuilder, все было хорошо. К счастью, эта или аналогичная ей среда может без труда сгенерировать строку со всеми необходимыми атрибутами для запуска вашего веб-приложения. И теперь вам нужно показать ваше приложение миру :-).
Начнем с некоторых определений, которые понадобятся нам в дальнейшем.
Что такое v1.X JK?
Самое простое объяснение - это модули (библиотеки), которые являются реализацией своеобразных каналов общения между веб-серверами и Tomcat (являющимся самым популярным на сегодня JSP/servlet-контейнером). Они заменяют предшествующие серверные модули - mod_jserv, имевшие много недостатков. Новые модули JK предусматривают поддержку более широкого ряда веб-серверов, лучше взаимодействуют со SSL, реализуют протокол AJP13, а также осуществляют поддержку более широкой линейки Tomcat, начиная с версии 3.2.x и вплоть до 5.x.
Инсталляция Tomcat и Apache
Прежде чем продолжить эксперименты, необходимо убедиться, что у вас есть все компоненты, необходимые для конфигурации Tomcat. Вам нужно будет инсталлировать следующее:
- Apache 1.3.xx;
- Jakarta-Tomcat 4.1.xx;
- mod_jk v1.x
Убедитесь, что вы загружаете соответствующие бинарники именно для вашей операционной системы. Вы можете, конечно, загрузить бинарники для всех операционных систем, но мы не будем обсуждать настройку Tomcat для их всех. Наша цель - научиться это делать именно для Linux. Хотя для большинства операционных систем процесс будет очень похожим, если не сказать одинаковым.
Обратите внимание, что версии, в названии которых присутствует LE (light edition), не включают документации и примеров приложений. Кроме того, там отсутствуют некоторые библиотеки - и, как следствие, соответствующие возможности. Эти версии специально оптимизированы для работы с JDK 1.4. Лучше загрузите полную версию.
Если в качестве сервера используется Linux-система с поддержкой rpm, то rpm-пакет с Tomcat можно скачать по адресу.
После инсталляции этого дистрибутива вам будет предложено активизировать tomcat-сервис с помощью Linux-утилиты snsys. Лично на меня этот факт произвел очень благоприятное впечатление. В RedHat-дистрибутивах вместо этой утилиты можно использовать setup.
Как только вы загрузите все указанные компоненты, переходите к следующим шагам:
- Установите Apache, как указано в его документации (скорее всего, он у вас уже установлен. Даже если это не так, то его инсталляция с rpm-пакета не должна вызвать у вас каких-либо затруднений);
- Протестируйте Apache, стартуйте его (обычно это происходит автоматически после инсталляции). Если старта не произошло, используйте утилиту snsys для активации Apache как сервиса, после чего перезапустите Linux или просто запустите демон как обычное приложение.
Если у вас нет утилиты snsys или setup для активизации сервисов, а вы все же собираетесь инсталлировать ваши сервера как сервисы, то не отчаивайтесь - все это не так уж сложно прописать и вручную (ниже этот процесс будет описан более подробно).
Откройте окно вашего браузера: http://localhost - в случае локального тестирования, или соответствующий адрес вашей Linux-машины - если вы тестируете Apache с вашего рабочего места (я, например, делал это с использованием ssh). Вы должны теперь увидеть нечто подобное тому, что показано на рис. 1.
Установить Tomcat не сложно - просто следуйте документации. Собственно, его инсталляция сводится либо к запуску rpm-пакета, либо (если вы скачали архив) к простой разархивации в выбранную вами директорию. Установите переменную среды окружения JAVA_HOME (указывающую на корневую директорию, где была установлена JDK) и CATALINA_HOME (указывающую на корневую директорию, которую вы выбрали для установки Tomcat).
Теперь проверяем, заработал ли Tomcat. Запустите его и, используя ваш браузер, перейдите на станицу http://localhost:8080 - или страницу с соответствующим адресом вашей Linux-машины. Не забудьте добавить:8080 - Tomcat прослушивает запросы не на стандартном HTTP-порту 80, а на порту 8080.
Вы увидите что-то вроде изображенного на рис. 2.
Теперь остановите Apache и Tomcat, прежде чем мы перейдем к следующим секциям.
Если на данный момент для ваших целей хватит Tomcat и интеграция с Apache вам не нужна - пропустите следующую главу и сразу переходите к инсталляции (развертыванию на сервере) вашего приложения.
Интеграция между Tomcat и Apache
Пришло время, чтобы начать фактическую интеграцию между Apache и Tomcat. Этот процесс может быть условно разбит в две части: конфигурирование Tomcat и конфигурирование Apache.
Конфигурирование Tomcat
Чтобы научить ваш Tomcat понимать Apache, нужно сначала сообщать ему, что он должен начать слушать запросы от Apache. Для этого служит протокол AJP13 - для связи с Tomcat его используют как JK, так и JK2. Для установки этой связи в настройках нужно добавить дополнительный <CONNECTOR>-элемент в CATALINA_HOME/server.xml (файл Tomcat). Добавьте следующую секцию к server.xml, убедитесь в том, что эта секция находится внутри тега <SERVICE> и следует сразу за любыми определенными до этого <CONNECTOR>-элементами.
Как правило, эта секция уже определена в server.xml - и во время старта Tomcat начинает прослушивать запросы как от HTTP-клиентов на порту 8080, так и от Apache на порту 8009. Если вы нашли в вашем server.xml что-то подобное, пропустите этот шаг. Проверьте также наличие самого файла класса внутри пакета, и если он называется не так, скорректируйте его название в записи. Выглядеть она должна следующим образом:
<CONNECTOR CLASSNAME="org.apache.ajp.tomcat4.Ajp13Connector" PORT="8009" MINPROCESSORS="5" MAXPROCESSORS="75" ACCEPTCOUNT="10" DEBUG="0" />
Атрибут port сообщает Tomcat, что ему нужно открыть новый Connector, который слушает порт 8009 для входящих запросов. Атрибут className сообщает Tomcat, что все запросы, приходящие на этот порт, должны обслуживаться java-классом "org.apache.ajp.tomcat4.Ajp13Connector", который также использует протокол AJP 1.3.
Конфигурирование Apache
Теперь, когда Tomcat сконфигурирован, чтобы слушать на порту 8009 для обслуживания запросов AJP13, давайте сообщим Apache, что мы хотим, чтобы он поговорил с Tomcat, используя этот порт и протокол. Этот процесс относительно прост - немногим сложнее аналогичного конфигурирования Tomcat.
Начнем конфигурацию Apache с того, что создадим Tomcat worker definition - определение для Tomcat worker. Это определение сообщит Apache, как и когда говорить с Tomcat. Для этого создадим Tomcat-working-файл, содержащий необходимые определения хотя бы для одного такого Tomcat worker'а. Tomcat worker - это процесс, создающий коммуникационный линк между Apache и Tomcat. Процесс-посредник необходим в данном случае для того, чтобы внутри него создать клиентский сокет, который будет посылать запросы к коннектору Tomcat и получать ответы.
В нашем примере назовем файл конфигурации workers.properties и скопируем его в <CATALINA_HOME>/conf-директорию Tomcat. (<CATALINA_HOME> - это базовая директория вашей установки Tomcat.). Теперь добавьте туда следующие строчки:
worker.list=myWorker
worker.myWorker.port=8009
worker.myWorker.host=localhost
worker.myWorker.type=ajp13
Эти данные определяют имя посредника - myWorker. Он находится на том же Linux box, что и сервер Apache, localhost, и слушает порт 8009 для клиента, использующего протокол AJP13.
worker.list - определяет список рабочих (перечисляемых через запятую), посредством которых он будет общаться с Apache. Этот список может определять любoe количество рабочих Tomcat.
В данном примере определяем единственного рабочего - myWorker. Как только мы назвали рабочего, можем модифицировать его атрибуты, явно используя следующий синтаксис:
worker.myWorker + Имя атрибута = Значение
Все, что мы модифицировали в этом примере, это три атрибута нашего рабочего: порт, хост и тип протокола. Все они достаточно понятны, а потому не требуют дополнительного объяснения.
Хотелось бы отметить, что на самом деле сохранение файла описания workers в <CATALINA_HOME>/conf является скорее хорошей традицией, чем правилом. Это совсем не обязательно - и вы можете сохранить этот файл где угодно. Но традиции лучше не нарушать.
Далее скопируйте коннектор в поддиректорию libexec/ сервера Apache.
Модификация httpd.conf конфигурационного файла Apache
Откройте этот файл для редактирования и добавьте в его конец следующие строки:
# загружаем модуль:
# for windows box:
# LoadModule jk_module libexec/mod_jk-1.3.26.dll
# for Linux box:
LoadModule jk_module libexec/mod_jk2-1.3-noeapi.so
AddModule mod_jk.c
#JkWorkersFile C:/Tomcat4_1_12/conf/workers.properties
JkWorkersFile /var/tomcat4/conf/workers.properties
# for windows box:
# JkLogFile C:/Tomcat4_1_12/logs/mod_jk.log
# for Linux box:
JkLogFile /var/tomcat4/logs/mod_jk.log
JkLogLevel debug
# for windows box:
# Alias /examples C:/Tomcat4_1_12/webapps/examples
# for linux box:
Alias /examples /var/tomcat4/webapps/examples
JkMount /examples/servlet/* myWorker
JkMount /examples/*.jsp myWorker
<LOCATION examples web-inf ?>
AllowOverride None
deny from all
</LOCATION>
Tеперь посмотрим, что происходит при старте Apache.
Apache находит запись о том, что ему необходимо загрузить дополнительный модуль. Модуль, загрузившись, сам начинает читать все необходимые ему настройки. Прежде всего, он определяет количество и характеристики рабочих, которых ему надо создать. Далее определяются маски файлов (пути указываются абсолютно - от корня вашего сервера). Рабочие будут переадресовывать Tomcat запросы с соответствующими расширениями и получать ответы, передавая их обратно в Apache. Выглядят эти ответы так:
JkMount /examples/servlet/* myWorker
JkMount /examples/*.jsp myWorker
Обратите внимание: для каждой такой маски в соответствие ставится определенный рабочий.
Все остальные записи сами объясняют свое назначение и в дополнительных разъяснениях не нуждаются. Для наглядности приведен рисунок, поясняющий работу серверов в связке (рис. 3).
Хотелось бы еще отметить стандартный для Apache тег <LOCATION> - он создает виртуальный каталог для Apache (используется терминология Microsoft, но более точного определения не подобрать), для того чтобы обслуживать запросы к страницам, которые не попали в маски файлов для JK,- то есть к статическим файлам или файлам, обрабатываемым другими серверными препроцессорами (например, PHP), минуя при этом сервис рабочих JK.
Теперь запустите Tomcat и Apache.
Развертывание веб-приложения на Tomcat
Если все работает, можно приступать к развертыванию вашего веб-приложения на Tomcat.
Предположим, что JBuilder автоматически создал файл report.war вашего проекта, где report - имя проекта, заданное в визарде при создании скелета приложения.
Для того чтобы приложение стало доступно для Tomcat, скопируйте этот файл в CATALINA_HOME/webapps/.
Теперь все, что остается сделать, это прописать необходимые сведения в файл CATALINA_HOME/conf/server.xml.
Найдите то место, где начинается описание контекста приложения examples. Эта запись должна начинаться со строки вида:
<CONTEXT DEBUG="0" PATH="/examples"
DOCBASE="examples" >
reloadable="true" crossContext="true">
Перед ней создайте свой контекст приложения. При этом новая запись будет выглядеть примерно так:
<CONTEXT DEBUG="0" PATH="/report"
DOCBASE="report.war" >
reloadable="true" crossContext="true">
</CONTEXT>
Теперь несколько коротких пояснений по этому примеру.
Как можно заметить, имя нашего файла приложения в этом примере - report.war. Относительный адрес хоста приложения при этом "./report/" от корня сервера, то есть полный адрес вашего приложения - http://host/report/index.jsp (при условии, что первая страница - это index.jsp).
reloadable="true" - сообщает, что приложение не нуждается в перезапуске сервера и автоматически будет обновлено, если вы скопируете на место старого файла *.war его новую версию.
crossContext="true" - сообщает серверу, что этот каталог будет доступен также и из других веб-приложений.
Запустите Tomcat - и увидите, что архив вашего приложения автоматически развернулся в папку в CATALINA_HOME/webapps/.
Если вы хотите, чтобы этого не происходило, найдите запись:
<HOST DEBUG="0" ><BR NAME="localhost"
APPBASE="webapps">
unpackWARs="true" autoDeploy="true">
- и присвойте параметру unpackWARs значение "false".
Еще один очень важный момент при развертывании вашего приложения на сервере - необходимо помнить: если Tomcat не видит какой-либо библиотеки, но при этом в вашей среде разработки все прекрасно работало, то это может быть обусловлено тремя причинами:
- WEB-INF/lib-директория в вашем *.war-файле не содержит оных библиотек.
- Названия библиотек оканчиваются расширением *.zip. Странно, но Tomcat в таком случае не видит их. Измените расширение этих файлов на *.jar и перезапустите сервер.
- Точные копии ваших библиотек находятся еще в каком-то каталоге /lib Tomcat.
Впрочем, стоит заметить, что для последних версий Tomcat эта проблема была устранена.
В ближайшем будущем мы рассмотрим также некоторые тонкости и подходы при создании Java веб-приложений на примере создания простого веб-приложения с использованием технологии Java2.
Надеюсь, эта статья окажется полезной для всех, кто собирается разрабатывать собственные веб-приложения с использованием технологии Java на Linux-сервере.
AJP 13
AJP 13 - это протокол, который позволяет веб-серверу общаться с Tomcat JSP/servlet контейнером посредством TCP-соединения. Все, что нам необходимо знать для наших целей, это то, что AJP13 является более эффективным протоколом, чем его предшественники, и включает лучшую поддержку для SSL.
Более подробная информация доступна по адресу.
Как сделать ваш Tomcat сервисoм на Linux без помощи утилиты nsys и setup
Для того чтобы запустить ваши серверы как сервисы (daemons), необходимо модифицировать файл в вашей Linux-системе:
- Откройте файл /etc/inetd.conf c помощью vi или другого доступного вам редактора и пропишите там строку вида:
tomcat stream tcp nowait root /var/tomcat4/bin/tomcat in.tomcat
- Перезапустите Linux. Если у вас Linux более поздней версии, чем 7x,- то вместо inetd.conf вам необходимо будет редактировать xinetd.conf (в этих системах в каталоге /etc не существует inetd.conf). Скорее всего, вам нужно будет добавить строку вида:
/var/tomcat4/bin/tomcat