Привет, дорогие читатели!
Apache Tomcat — это открытое программное обеспечение, реализующее спецификации Java Servlet, JSP и Java WebSocket, предоставляя таким образом платформу для запуска веб-приложений, написанных на языке Java. Разработанный и поддерживаемый Apache Software Foundation, Tomcat служит контейнером сервлетов, который позволяет веб-приложениям использовать Java для создания динамичных веб-страниц.
Tomcat может работать как самостоятельный веб-сервер, где он обрабатывает как статические страницы, так и динамические запросы через Servlets и JSP. Однако часто Tomcat используется в сочетании с традиционными веб-серверами, такими как Apache HTTP Server или Nginx, для обработки статического контента, в то время как динамический контент обрабатывается через Tomcat.
В этой статье мы рассмотрим основной функционал Tomcat.
Установим
Скачиваем Apache Tomcat с официального сайта. Выбираем версию, подходящую под ОС. После скачивания распаковываем архив.
Открываем терминал, переходим в директорию bin
внутри распакованного каталога Tomcat и запускаем startup.sh
(на Linux) или startup.bat
(на Windows). Если все сделано правильно, ваш сервер поднимется, и вы увидите приветственную страницу Tomcat, открыв localhost:8080
в вашем браузере.
Настройка Tomcat
Файл server.xml
управляет всей конфигурации.
Рассмотрим конфигурацию connector, которая часто используется для HTTP/1.1:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="150" minSpareThreads="25"/>
maxThreads
и minSpareThreads
— параметры для оптимизации. Увеличение maxThreads
позволяет обрабатывать больше параллельных запросов, но требует больше ресурсов.
Для усиления безопасности можно внести изменения в тот же файл server.xml
, ограничив доступ к определенным функциям:
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="^.*[your-trusted-ip].*$" />
Настройка гарантирует, что доступ к вашему серверу разрешен только с определенных IP-адресов.
Apache Tomcat использует пулы соединений JDBC для улучшения производительности при работе с БД. Пример настройки пула соединений в context.xml
:
<Resource name="jdbc/YourDB"
auth="Container"
type="javax.sql.DataSource"
maxTotal="100"
maxIdle="30"
maxWaitMillis="10000"
username="dbuser"
password="dbpassword"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/yourdb"/>
JMX — это стандарт, который позволяет в реальном времени мониторить и управлять приложением. Для включения JMX в Tomcat, нужно будет запустить его с определенными параметрами JVM:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
Tomcat использует JULI, расширение стандартного логирования Java, но его можно интегрировать с более крутыми системами логированиями, такими как Log4j или SLF4J:
Добавляем файл log4j.properties
в класспат.
Указываем log4j
в качестве фабрики логирования, добавив следующие параметры JVM при запуске Tomcat:
-Dorg.apache.catalina.logging.log4j.Log4jContextFactory
-Dlog4j.configurationFile=path/to/log4j.properties
Производительность Tomcat напрямую зависит от настроек JVM. Можно оптимизировать некоторые параметры:
Xmx и Xms:
устанавливают максимальный и начальный размер кучи соответственно
-Xmx4G -Xms4G
XX:+UseG1GC
: включает сборщик мусора G1
XX:+UseStringDeduplication:
сокращает кол-во дублирующихся строк в куче
Безопасность
Реализация SSL/TLS для защиты данных
Для начала нужен Keystore с ключом и сертификатом, это можно сделать keytool
, встроенный в JDK:
keytool -genkey -alias tomcat -keyalg RSA -keystore /path/to/your/keystore.jks
В процессе создания Keystore, keytool
задаст несколько вопросов для идентификации. Запомните пароль Keystore; он понадобится далее.
Открываем файл conf/server.xml
и находим конфигурацию Connector. Модифицируем его, чтобы включить SSL, как показано ниже:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" keystoreFile="/path/to/your/keystore.jks"
keystorePass="your_keystore_password" />
Заменяем keystoreFile
и keystorePass
на путь к Keystore и пароль соответственно.
Настройка фильтров безопасности и CORS
Редактируеи файл web.xml
приложения или глобальный conf/web.xml
в Tomcat для добавления фильтра CORS:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,Authorization</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Это базовая настройка CORS, позволяющая запросы с любого источника. В продакшене конечно, рекомендуется установить более строгие правила.
Для дополнительной приложения, можно использовать<security-constraint>
в web.xml
:
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
Теперь все запросы будут требовать аутентификацию и использование SSL.
Безопасные заголовки
Можно добавить безопасные HTTP заголовки с помощью фильтра web.xml
:
<filter>
<filter-name>HttpHeaderSecurityFilter</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<init-param>
<param-name>antiClickJackingOption</param-name>
<param-value>SAMEORIGIN</param-value>
</init-param>
<init-param>
<param-name>xssProtectionOption</param-name>
<param-value>1; mode=block</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>HttpHeaderSecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Также не забывайте ограничивать доступ к /manager
и /host-manager
с помощью строгих правил в conf/tomcat-users.xml
.
Масштабирование
Конфигурирование кластеров Tomcat
Кластеризация в Tomcat – это процесс объединения нескольких экземпляров Tomcat для обработки запросов к одному и тому же веб-приложению как единое целое.
Все экземпляры Tomcat на разных серверах должны иметь одинаковую версию и конфигурацию веб-приложений.
В файле conf/server.xml
каждого экземпляра Tomcat нужно будет настроить кластер. Вставьте следующий фрагмент в элемент <Engine>
:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
Эта конфигурация активирует механизм кластеризации с использованием простого TCP кластера.
Балансировка нагрузки с Apache HTTP или Nginx
Можно использовать Apache HTTP Server или Nginx в качестве обратного прокси для распределения входящих запросов между узлами кластера Tomcat.
Настройка Apache HTTP с mod_jk:
Нужно установить mod_jk
и настроить workers.properties
для указания узлов кластера:
worker.list=loadbalancer
worker.tomcat1.type=ajp13
worker.tomcat1.host=server1.example.com
worker.tomcat1.port=8009
worker.tomcat2.type=ajp13
worker.tomcat2.host=server2.example.com
worker.tomcat2.port=8009
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=tomcat1,tomcat2
Добавьте конфигурацию в httpd.conf
для перенаправления запросов на балансировщик:
LoadModule jk_module modules/mod_jk.so
JkWorkersFile conf/workers.properties
JkMount /* loadbalancer
В конфигурационном файле Nginx (nginx.conf
) нужно определить upstream для узлов Tomcat и настроить сервер для перенаправления запросов:
upstream tomcat_cluster {
server server1.example.com:8080;
server server2.example.com:8080;
}
server {
listen 80;
location / {
proxy_pass http://tomcat_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Сессионное реплицирование и sticky sessions
В кластеризованных средах сессионное реплицирование обеспечивает синхронизацию данных сессий между узлами.
В файле conf/server.xml
добавляем конфигурацию кластера с DeltaManager
для репликации сессий:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<!-- можно включить прочие настройки кластера и канала -->
</Cluster>
DeltaManager
реплицирует только изменения в сессии, делая репликацию эффективной по ресурсам.
Sticky sessions позволяют "прилепить" сессию пользователя к определенному серверу, чтобы обеспечить согласованность данных. В Apache или Nginx это достигается через настройки балансировщика.
Nginx:
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky;
}
server {
location / {
proxy_pass http://backend;
}
}
}
Apache HTTP Server с mod_proxy_balancer:
<Proxy "balancer://mycluster">
BalancerMember "http://backend1.example.com" route=1
BalancerMember "http://backend2.example.com" route=2
ProxySet stickysession=JSESSIONID
</Proxy>
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
Apache ZooKeeper
ZooKeeper может использоваться для управления конфигурацией и состоянием кластера.
Установим ZooKeeper на отдельный сервер или группу серверов и создадим файл конфигурации conf/zoo.cfg
с основными настройками:
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=zk1.example.com:2888:3888
server.2=zk2.example.com:2888:3888
Для интеграции можно Apache Curator. Зарегистрируем узел:
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, new ExponentialBackoffRetry(1000, 3));
client.start();
String path = "/tomcat/nodes/" + nodeId;
byte[] payload = "Some node data".getBytes();
client.create().creatingParentsIfNeeded().forPath(path, payload);
Код создает узел в ZooKeeper для каждого экземпляра Tomcat.
Интеграция Apache Tomcat с веб-серверами
Интеграция с Tomcat часто осуществляется с использованием модуля mod_jk
, который позволяет HTTP Server коммуницировать с Tomcat через AJP.
Установим mod_jk
и загрузим соответствующий ОС бинарный файл или соберем его из исходников, а затем добавьте в конфигурацию Apache:
LoadModule jk_module modules/mod_jk.so
Файл workers.properties
определяет, как сервер будет взаимодействовать с экземплярами Tomcat. Создадим этот файл и настройте в нем worker:
worker.list=worker1
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009
В httpd.conf
или в отдельном файле конфигурации добавим указание на workers.properties
и настроим маршрутизацию:
JkWorkersFile /path/to/your/workers.properties
JkMount / worker1
Это перенаправит все запросы к Apache HTTP Server на Tomcat через AJP.
Больше практических навыков по архитектуре приложений вы можете получить в рамках практических онлайн-курсов от экспертов отрасли.