Серия Dead Tomcat (1) - общая архитектура
На многих высококлассных должностях в области разработки от интервьюеров в большей или меньшей степени требуется изучение исходного кода некоторого общего промежуточного программного обеспечения. Это связано с тем, что все секреты скрыты в исходном коде. Чтение исходного кода может дать нам более глубокое понимание фреймворка или промежуточного программного обеспечения, а также мы можем получить некоторые из отличных методов проектирования в исследовании исходного кода. И у нас так много промежуточного программного обеспечения и исходного кода, с чего нам начать? На самом деле большинство промежуточного программного обеспечения или фреймворков имеют некоторые общие части, такие как сетевое программирование, многопоточность, отражение и загрузка классов и другие технологии. Так что если досконально изучить один-два мидлпрайса, а потом оглянуться на другие мидлвары, то будет несложно понять используемые в нем технологии и принципы. Как старомодный веб-фреймворк, Tomcat, будь то общий дизайн архитектуры или некоторые из присущих ему технических гибких приложений, заслуживает внимания.
Когда я изучаю фреймворк, у меня обычно есть общее представление о фреймворке. Зная, как это работает в целом, а затем углубляясь в некоторые его части, можно сделать больше с меньшими затратами.
Общая структура
Если мы хотим понять структуру, мы должны сначала понять, что она делает.Все мы знаем, что Tomcat используется для обработки подключенных запросов Socket. Тогда у Tomcat будет две функции:
- Обработайте соединение извне и преобразуйте полученный поток байтов в нужные вам объекты запроса и ответа.
- Внутренне обрабатывать сервлеты и распределять соответствующие запросы запроса на соответствующие сервлеты.
Затем выходит наш общий скелет Tomcat фактически разделен на две части, одна часть — это коннектор (Connector), который обрабатывает внешние соединения, а контейнер (Container) управляет внутренним сервлетом. Общая схема отношений выглядит следующим образом
Крайний прямоугольник представляет службу Tomcat, а служба Tomcat может соответствовать нескольким службам. Каждая служба имеет соединители и контейнеры. Эти соответствующие отношения также можно открыть в файле конфигурации каталога Tomcat.server.xml
видел в.
<Server port="8006" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
</Host>
</Engine>
</Service>
</Server>
Здесь я удалил некоторый контент из файла конфигурации и упростил его Здесь мы видим, что коннектор на самом делеConnector
, Сервис может иметь несколько коннекторов, а контейнер на самом деле соответствуетEngine
.
Общая архитектура Tomcat является именно таким соответствием. Далее мы кратко представим общую архитектуру коннектора и общую архитектуру контейнера.
Соединитель
Мы можем видеть, что то, что коннектор передает в контейнер на приведенном выше рисунке,ServletRequest
объект, и то, что контейнер передает соединителю,ServletResponse
Объекты, это определенно невозможно во время передачи по сети из-за потока байтов, передаваемого при передаче по сети. Таким образом, мы, вероятно, можем резюмировать функциональные требования к разъему следующим образом.
- Гнездовое соединение
- Чтение потока байтов в сети запроса
- Проанализируйте поток байтов в соответствии с соответствующим протоколом (Http/AJP) для создания унифицированного
Tomcat Request
объект - будет
Tomcat Reques
передан в контейнер - контейнер возвращается
Tomcat Response
объект - будет
Tomcat Response
Преобразовать объект в поток байтов - Вернуть поток байтов клиенту
Фактически, приведенное выше подразделение можно свести к следующим трем пунктам.
- Телекоммуникации
- Анализ протоколов прикладного уровня
- Кот
Request/Response
а такжеServletRequest/ServletResponse
преобразование объекта
В Tomcat он также использует три класса для реализации трех вышеуказанных функций, которые соответствуют следующим
- EndPoint
- Processor
- Adapter
Вот так их можно изобразить графически
контейнер
Контейнеры, как следует из названия, являются инструментами для хранения вещей, так что же вмещает этот контейнер Tomcat? На самом деле главное — установить Servlet. Итак, как устроен контейнер? Дизайн контейнера Tomcat фактически использует шаблон комбинированного проектирования (если вы не понимаете шаблон комбинированного проектирования, вы можете прочитать мою предыдущую статьюНе учить бесчисленное количество - комбинированный режим). На самом деле изServer.xml
Мы также можем видеть его взаимосвязь.
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
</Host>
</Engine>
Здесь мы видим только два модуля в контейнере, один из которых является модулем верхнего уровня.Engine
, другойHost
, на самом деле есть два модуля, одинContext
Соответствует каждой папке приложения в нашем веб-приложении, и каждая папка соответствуетContext
, и модульWrapper
соответствует намContext
все сервлеты вWrapper
Он управляет соответствием между отношением доступа и конкретным сервлетом. На схеме показано следующее.
Все модули контейнера в Tomcat реализованыContainer
интерфейса, а смысл режима композиции состоит в том, чтобы сделать использование пользователем одиночного объекта и составного объекта согласованным, то есть независимо от того, сколько добавленоContext
Его использование состоит в том, чтобы найти сервлет ниже него, и независимо от того, сколько хостов добавлено, он также должен найти сервлет ниже. С таким количеством модулей, разработанных в контейнере, как Tomcat находит соответствующий сервлет для обработки запроса?
Как найти запрос
Возьмем самый простой пример: мы запустили Tomcat в нашем родном приложении, и есть приложение, которое мы развернули под веб-приложением.buxuewushu
. Входим в браузереhttp://localhost:8080/buxuewushu/add.do
Как найти соответствующий сервлет для обработки?
Когда мы запускаем Tomcat, коннектор инициализируется и прослушивает настроенный номер порта.Здесь мы настраиваем протокол, соответствующий порту 8080, — HTTP.
- Запрос отправляется на порт 8080 локального компьютера и принимается коннектором HTTP/1.1. Коннектор прослушивает его.
- Соединитель Соединитель преобразует поток байтов в то, что нужно контейнеру.
ServletRequest
возражать против сверстниковService
Модуль под контейнер Engine для обработки - Двигатель получает адрес
http://localhost:8080/buxuewushu/add
. Совпадение с хозяином хоста под ним - Соответствовать хосту с именем localhost (даже если в данный момент запрос представляет собой определенный IP-адрес, а соответствующий хост не настроен, он будет передан для обработки хосту с именем localhost, поскольку он является хостом по умолчанию)
- Хост соответствует пути как
/buxuewushu
Контекст, то есть найти соответствующую папку под веб-приложением - Контекст соответствует сервлету, правилом URL которого является *.do, что соответствует классу сервлета.
- назовите его
doGet
илиdoPost
метод - После выполнения сервлета объект возвращается в контекст.
- Контекст возвращается хосту
- Хост возвращается в Engine
- Двигатель возвращается к разъему Разъем
- Соединитель Соединитель анализирует объект в поток байтов и отправляет его клиенту
Предыдущие статьи о Tomcat
- Странная поездка в поисках вопросов StackOverflowError
- Как поставить точку останова при отладке исходного кода Tomcat