7 Ноябрь 2017

Comments

0
 Ноябрь 7, 2017
 0

Пролог

Если вы разрабатываете web-ориентированные приложения, то вероятно сталкивались с контейнером сервлетов Tomcat. Я буду описывать здесь настройку tomcat 8, однако это всё подходит и для предыдущих версий, например tomcat 7.
Итак, что такое виртуальный хост? Виртуальный хост, это выделенное пространство http сервера, которое предназначено для обслуживания запросов предназначенных для этого хоста, иными словами это доменное имя, за которое отвечает наш сервер.
У каждого http сервера, есть хост по умолчанию и называется он localhost. Его вполне бы хватало, если бы наш сервер был предназначен для одного приложения, но обычно один сервер обслуживает несколько хостов. Вот об этом мы сейчас и поговорим.

Начало пути

Допустим, мы зарегистрировали несколько доменных имён, пусть это будет example.ru и sample.ru Приложения под эти домены у нас так же имеются. А так же у нас имеется сервер tomcat запущеный на нашем сервере. Но с какой стороны к нему подойти, чтобы он стал обслуживать несколько доменов мы не знаем. Попробуем разобраться. И первое что мы сделаем, приведём структуру каталогов кота:

 

  • bin — содержит скрипты для управления сервером
  • conf — конфирурационные файлы сервера
  • lib — стандартные библиотеки java se
  • logs — сюда кот складыает эммм … . ну вобщем вы поняли, лооооги
  • temp — этот каталог сугубо для нужд сервера, здесь будут хранится временные файлы, такие как данные сессии и тому подобное
  • webapps — это директория локального виртуального хоста
  • work — тут сервер хранит скомпилированные файлы jsp, вобщем продукт жизнедеятельности наших приложений

 

Отлично, с директориями мы познакомились. Предлагаю заглянуть в директорию conf, ведь именно с ней нам сегодня работать.
В этой директории находятся, как мы уже говорили, конфигурационные файлы сервера. Все файлы мы конечно не будем рассматривать, но в один нам точно придётся залезть. Предлагая вашему вниманию: server.xml Давайте его откроем и посмотри.
До чего же он большой и непонятный, скажете вы 🙂 Но не стоит пугаться, не так страшен зверь, как его рисуют. Первым делом, что мы сделаем, очистим его от всех коментариев. После этих манипуляций мы получим что то оченл похожее на это:

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" 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"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

 

Спешу сообщить, что мы будем работать с секцией Host. Он на строке 25. И первое, что сделаем, поясним некоторые параметры тега host

 

appBase

Этот параметр указывает в какой директории будет расположен наш хост. В этом параметре можно указать путь абсолютный, например, /var/www/example/ или относительный, example. в последнем случае, сервер будет искать путь к хосту в главной директории сервера, а точнее на одном уровне с webapps, так указав appBase=»example» сервер будет ожидать, что каталог $CATALINA_BASE/example существует. Параметр является обязательным.

xmlBase

Этот параметр говорит серверу, эй, пойди ка в такой то каталог, там может находится информация о настройках моего приложения. А что сделает сервер? Он таки пойдёт и посмотрит, есть там что то или нет. Так по указанному пути может лежать подобный xml:
example.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="/home/example/target/example" path=""/>

 

В основном этот параметр можно оставить без изменений, так как он «хорошо» работает и без нас 🙂 Но в некоторых случаях может понадобиться его менять. По умолчанию же, эти каталогом будет: $CATALINA_BASE/conf/<enginename>/<hostname>
Про enginename скажу только то, что это строка 21 в нашем файле server.xml и именуется он Catalina, следовательно путь будет $CATALINA_BASE/conf/Cataline/<hostname> По hostname — это имя нашего хоста заданное в атрибуте name тега host. Мы ниже ещё будет говорить о нём. Сейчас же просто приведу простой пример. Допустим наш хост имеет имя example, следовательно путь будет $CATALINA_BASE/conf/Catalina/example

 createDirs

Этот параметр сообщает серверу, что если указанного каталога по имени указанному в атрибуте appBase нет, то сервер автоматически создаст этот каталог. Вобщем атрибут принимает булевое значение true каталог может быть создан автоматически, и false — запретить создание. По умолчаниу значение стоит в true. Вобщем в большенстве случаев менять этот параметр не требуется.

autoDeploy

Этот параметр сообщает серверу, нужно ли автоматически деплоить проект, если в директории произошли изменения или нет. Так же как и предыдущий атрибут, этот атрибут принимает булевое значение, true — деплоить автоматически и false не деплоить. По умолчанию стоит true. Вы спросите, а как же проект будет запущен если сервер не будет производить деплой? Отвечу, сервер произведёт деплой только при старте сервера, остальное время он будет игнорировать изменения произведённые в директории.

className

Этот параметр будет полезен продвинутым пользователям кота, если нужно изменить поведение создания и деплоя приложения. Так в этом параметре будет указан класс который должен реализовать интерфейс org.apache.catalina.Host Этот интерфейс по большому счёту просто определяет set/get методы. перечисляемые в этой статье. В большинстве случаев менять его не следует.

deployIgnore

Этот атрибут может оказаться весьма полезным тем, кто решил установить свою директорию для разработки в качестве хоста. Так допустим делают большинство ide, такие как eclipse, intellij, netbeans etc. В общей сложности этот параметр позволяет задать регулярное выразение, которое позволяет игнорировать файлы или директории при их изменении. Так, если мы указали autoDeploy=»true» и appBase (или xmlBase) сообщает серверу, что директория хоста это директория в которой мы ведём разработку, а в большинстве случаев разработка связана с git или svn, то этот атрибут позволит игнорировать каталог svn, просто указав deployIgnore=»\.svn» Этим мы сообщили серверу, что если произойдёт изменение в директории .svn, то не инициировать пересборку проекта.

deployOnStartup

Этот атрибут является своего рода противоположностью autoDeploy. Если тот позволяет выполнять деплой проекта «на гарячую», то этот атрибут сообщает серверу, нужно ли деплоить проект при старте сервера или взять существующую версию. Вобщем, если у вас в каталоге appBase находится файл чтототам.war, то аттрибут deployOnStartup=»false» запретит запуск распаковки war файла. По умолчанию этот атрибут установлен в true

name

Вот собственно имя вашего хоста. Атрибут является обязательным. Так, если мы хотим создать хост example.ru то, в атрибуте name должно быть прописано именно это имя. Когда в кота придёт запрос в заголовке Host которого указано имя example.ru, кот в первую очередь будет искать хост с таким именем и если не найдёт, передаст управление хосту по дефолту, в нашем случае это localhost, кстати он указан в теге Engine, атрибут defaultHost

Остальные атрибуты хоста я пока опущу.

Настройка виртуального хоста

Итак, теперь мы знаем какими атрибутами обладает виртуальных хост в коте, настало время создать свой первый виртуальный хост.
Приступим:

<Host name="example.com" appBase="example" unpackWARs="true" autoDeploy="true"></Host>

Что же мы сделали? А сделали мы следующее: сказали коту, теперь у тебя есть новый виртуальный хост, который ты найдёшь в $CATALINA_BASE/example/, а также, если будут приходить запросы с заголовком Host: example.com будь так любезен, передай управление приложению которое расположено в этой директории, что он собственно и сделает. Всё? Да, на этом можно было бы закончить, но осталось ещё несколько открытых вопросов. Допустим вот, если мы имеет в dns запись www.example.com, что будет, если в кота залезет запрос с таким именем? Отвечу, кот перенаправит запрос к localhost. Почему? Да потому, что нет совпадения ни с одним из перечисленных виртуальных хостов. Тогда что же делать? Ответ прост. У этого тега есть дочерние элементы, Одним из таких элементов является тег Alias, он не принимает никаких аргументов и выглядит очень просто,

<Alias>www.example.com</Alias>

Теперь, когда будут приходить запросы вида example.com или www.example.com кот будет перенаправлять их в наш хост.

Добавим наш хост в server.xml

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" 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"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
      <Host name="example.com"  appBase="example" unpackWARs="true" autoDeploy="true">
        <Alias>www.example.com</Alias>
      </Host>
    </Engine>
  </Service>
</Server>

Теперь, когда мы будем подкидывать собранный проект example.war в tomcat, укажем путь: $CATALINA_BASE/example/ например:

cp example.war $CATALINA_BASE/example/

При копировании статьи ссылка на статью обязательна.

Добавить комментарий