Серия Dead Tomcat (1) - общая архитектура

Tomcat

Серия 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

Ссылаться на