вторник, 8 апреля 2008 г.

Apache Tomcat 6.0 во FreeBSD 7.0

Apache Tomcat как Web-сервер? Почему нет?

Контейнер JavaServer Pages и Java Servlets по совместительству может выполнять функции Web-сервера. То есть нативные Web-сервера, получается, не так уж нужны, учитывая потенциальную небезопасность кода C/C++, на котором они написаны.

Предпосылки

Итак, Apache Tomcat, написанный на 100% pure-Java ЯП, вполне способен справиться с возложенными на него функциями Web-сервера.

Пока же мне нужно ввести в опытную эксплуатацию Web-сервер на домашней машине — Локалхосте — как любят выражаться прадвинутые одмины. Ну что ж, за дело!

Решение

1. Установка Apache Tomcat 6.0 во FreeBSD не должна вызвать трудностей. Порт ports/www/tomcat6 устанавливается обычным образом.

2. Для обеспечения удалённого управления Apache Tomcat нужно отредактировать файл /usr/local/apache-tomcat6.0/conf/tomcat-users.xml
Задание аккаунта менеджера сервера:

< ?xml version='1.0' encoding='utf-8'?>
< tomcat-users>
< role rolename="manager"/>
< user username="tomadmin" password="secretword" roles="manager"/>
< /tomcat-users>


3. Чтобы Apache Tomcat прослушивал порт 8080 и обеспечивал обработку запросов через пул, необходимо в файле /usr/local/apache-tomcat6.0/conf/server.xml раскомментировать блок

< Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />


Возможно, также понадобиться добавить в файл /usr/local/apache-tomcat6.0/bin/catalina.sh переменные окружения JAVA_HOME и CATALINA_HOME с абсолютными путями к каталогам JDK и Tomcat, соответственно, если Tomcat почему-либо не может быть запущен системой. Можно также задать переменную CATALINA_TMPDIR с каталогом /tmp в качестве местоназначения, чтобы переопределить путь по умолчанию $CATALINA_BASE/temp. Мне понадобилось внести в файл catalina.sh только эти две строки с переменными:

JAVA_HOME=/usr/local/jdk1.6.0/
CATALINA_TMPDIR=/tmp


4. Автозапуск Apache Tomcat можно обеспечить, если в файл /etc/rc.conf прописать следующую строчку:

tomcat60_enable="YES"


Также можно прописать дополнительные опции:

tomcat60_java_opts="-server"
tomcat60_java_home="/usr/local/jdk1.6.0"

Опция -server обеспечивает запуск Tomcat с серверной версией JVM, которая отличается более агрессивным сборщиком мусора GC, несколько другой стратегией управления памятью и JIT. Вторая строчка задаёт домашний каталог рабочего JDK.

После этого можно перезагрузить машину и проверить, запустился ли сервер:

> sockstat
...
www java 697 28 tcp4 *:8180 *:*
www java 697 30 tcp4 *:8080 *:*
www java 697 39 tcp4 *:8009 *:*
www java 697 40 tcp4 127.0.0.1:8005 *:*
...

Как видите, Web-сервер запущен и прослушивает порты 8180, 8080, 8009 и 8005.

Чтобы просмотреть стартовую страничку Apache Tomcat, в любом браузере на локальной машине достаточно ввести URL:

http://127.0.0.1:8080/


5. Apache Tomcat запускается и прослушивает входящие соединения на непривелегированных интернет-портах, что несколько неуклюже для настоящего Web-сервера. Запуск Tomcat на порту 80 возможен только от имени root'а.

Решение проблемы прослушивания служебного порта HTTP :80 Tomcat возможно с использованием механизма перенаправления IP-пакетов, доступного в IPFW и PF. Я выбрал PF в качестве перенаправителя пакетов со служебных портов на порты, которые прослушивает Tomcat в обычном состоянии.

PF доступен в системе в виде модуля ядра. Для автоматического запуска PF при старте системы необходимо в файле /etc/rc.conf прописать следующие строчки:

pf_enable="YES"
pf_rules="/etc/pf.conf"


Запуск пакетного фильтра в работающей системе осуществляется командой:

% pfctl -e

(Останов, соответственно — pfctl -d).

В файл /etc/pf.conf достаточно добавить правила перенаправления для известных портов (всего две строчки):

rdr on nve0 proto tcp from any to any port 80 -> 127.0.0.1 \
port 8080
rdr on nve0 proto tcp from any to any port 81 -> 127.0.0.1 \
port 8081

(здесь: nve0 — сетевой интерфейс, на котором ожидаются HTTP-соединения с Tomcat)

Проверка новых правил на пакетном фильтре выполняется командой:

% pfctl -nf /etc/pf.conf

И, если нет никаких ошибок в правилах, их можно активировать:

% pfctl -f /etc/pf.conf


Apache Tomcat будет откликаться из Интернет на URL вида:
http://<внешний inet-address>/


Возможные проблемы

Проблемы могут возникнуть с выполнением JSP из-за невозможности изменения содержимого рабочего каталога /usr/local/apache-tomcat6.0/work/, так как Tomcat имеет непривелегированные права пользователя www.
В этом случае достаточно удалить содержимое каталога командой:
% rm -rf /usr/local/apache-tomcat6.0/work/*

Впоследствии кэш будет создан заново самим Tomcat без особых проблем.

Также встречалась проблема с невозможностью ответа сервера Tomcat на клиентский http-запрос. Пересборка Sun J2SE JDK 1.6 из порта ports/java/jdk16 без опции поддержки IPv6 решило данную проблему.

Послесловие

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

Безусловно, эта статья не претендует на точность изложения всех аспектов развёртывания и конфигурирования Apache Tomcat и PF, а лишь отражает общие принципы работы этой связки.

Пока на этом всё.

Sun WTK 2.2 в окружении JDK 1.6 на FreeBSD 7.0

Комплект разработчика Sun WTK портировался и тестировался для работы в Linux-окружении JDK версии 1.4.2 и выше. Его удавалось завести под Diablo JDK 1.5, нативной версией Sun J2SE SDK 1.5, но при этом нужно было обеспечить поддержку Linux ABI со стороны ядра FreeBSD — загружать модуль linux.ko и держать каталог /usr/compat/linux с так называемой linux_base.

Все компоненты, необходимые для работы эмулятора определены, осталось правильно их настроить.

Оказалось, что устаревшая версия Diablo JDK 1.5 в принципе заменима новой версией Sun J2SE SDK 1.6 из порта ports/java/jdk16 и не надо держать две версии JDK. Так что проблема запуска эмулятора Sun WTK упирается только в используемую linux_base, а с ней не так просто.

В дистрибутив FreeBSD 7.0-RELEASE входит бинарный пакет linux_base, который устанавливается по желанию. Я устанавливал систему с boot-only CD по сети, так что от пакета linux_base пришлось отказаться до последнего момента, когда понадобилось поработать с эмулятором Sun WTK. Выяснил, что из доступного набора дистрибутивов linux_base, которые можно поставить на FreeBSD из соответствующих портов ветки ports/emulators, оригинальным бинарным пакетом является сборка из порта ports/emulators/linux_base-fc4. Чтобы обеспечить работу графических Linux-приложений в Xorg под FreeBSD, нужно также инсталлировать набор библиотек из порта ports/x11/linux-xorg-libs.

Итак, последовательность шагов по установке ПО определена весьма чётко:
% cd /usr/ports/java/jdk16 && make install clean && rehash
% cd /usr/ports/java/sun-wtk && make install clean
% kldload linux.ko
% cd /usr/ports/emulators/linux_base-fc4 && make install clean && rehash
% cd /usr/ports/x11/linux-xorg-libs && make install clean && rehash
% mount -t linprocfs linprocfs /compat/linux/proc

После этого можно открыть ktoolbar и запустить демонстрационные j2me-приложения из поставки Sun WTK. Для создания и редактирования проектов в самом ktoolbar необходимо иметь соответствующие права доступа к подкаталогам /usr/local/sun-wtk.

Чтобы запускать поддержку Linux ABI при старте системы, необходимо в файл /etc/rc.conf добавить строчку:
linux_enable="YES"

В конец файла /etc/fstab добавить строчку автомонтирования файловой системы linuxprocfs:
...
linprocfs /compat/linux/proc linprocfs rw 0 0


В общем, на этом проблемы с запуском можно считать решёными.