Tomcat
Apache Tomcat — web-server и Jakarta Servlet container. Он принимает сетевые соединения, создаёт servlet request/response, управляет web-приложением и вызывает его servlet-компоненты.
Tomcat работает постоянно после запуска, а не только в момент запроса. Потоки и служебные компоненты ожидают соединения, выполняют фоновые задачи и управляют жизненным циклом приложений.
Основные компоненты
- Coyote — connectors и HTTP/AJP-взаимодействие;
- Catalina — servlet container, lifecycle и маршрутизация внутри web-приложения;
- Jasper — компиляция JSP в servlet;
- Engine / Host / Context / Wrapper — иерархия контейнеров от виртуального хоста до servlet.
Упрощённый путь:
flowchart LR A["TCP connection"] --> B["Coyote Connector"] B --> C["Engine / Host"] C --> D["Context: web application"] D --> E["Filter chain"] E --> F["Servlet"] F --> B
В Spring MVC servlet — это обычно DispatcherServlet.
Потоковая модель
Для обычного blocking request connector выдаёт worker thread из пула. Поток занят, пока приложение читает запрос, ждёт БД/HTTP и формирует ответ.
Если внешняя зависимость зависла, растёт число занятых threads, затем очередь и latency. Поэтому согласуют:
maxThreadsи очередь соединений;- connection/read/write timeouts;
- размер JDBC/HTTP connection pools;
- лимиты request body и headers;
- timeout внешних вызовов.
Большой thread pool не лечит медленную зависимость: он может лишь создать больше одновременной нагрузки и расхода памяти.
Жизненный цикл приложения
Tomcat создаёт ServletContext, регистрирует listeners, filters и servlets, затем переводит context в рабочее состояние. При остановке вызывает lifecycle callbacks и должен дать приложению закрыть пулы, executors и клиенты.
Если web-приложение создаёт non-daemon thread и не завершает его, redeploy может оставить classloader и вызвать утечку памяти.
Внешний и embedded Tomcat
Классический вариант: собрать WAR и развернуть в установленный Tomcat.
Spring Boot чаще упаковывает Tomcat внутрь executable JAR:
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}Это тот же servlet container, но конфигурацией и lifecycle управляет приложение. Для замены на другой embedded server меняют starter и проверяют совместимость API/настроек.
HTTP и TLS
Connector может завершать TLS сам, но в production TLS часто завершается на reverse proxy или ingress. Тогда Tomcat получает внутренний HTTP и должен доверять forwarded headers только от известного proxy.
Если TLS настроен в Tomcat, keystore должен содержать private key и цепочку сертификатов. См. SSL.
Диагностика
- thread dump показывает занятые worker threads и место ожидания;
- access log помогает связать path, status, duration и объём;
- JMX/метрики показывают active threads, queue и connections;
- heap dump помогает искать удержанный classloader после redeploy;
- логи запуска показывают конфликт port и ошибки deployment.
На собеседовании
Tomcat — полноценный Jakarta EE server? Нет. Он прежде всего реализует servlet/web-спецификации; дополнительные enterprise-возможности требуют библиотек или другого runtime.
Чем connector отличается от servlet? Connector работает с сетью и HTTP, container маршрутизирует запрос, servlet реализует обработку на уровне приложения.
Связанные заметки: Сервлет, MVC, Spring Boot, Http протокол.