Привет, дорогие читатели!

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.


Больше практических навыков по архитектуре приложений вы можете получить в рамках практических онлайн-курсов от экспертов отрасли.

Комментарии (0)