1、基本的环境准备

#在主机上安装jdk和tomcat完成环境的准备
root@ubuntu:~# ls
apache-tomcat-9.0.62.tar.gz  install_tomcat.sh  jdk-8u291-linux-x64.tar.gz
root@ubuntu:~# cat install_tomcat.sh 
#!/bin/bash

DIR=`pwd`
JDK_FILE="jdk-8u291-linux-x64.tar.gz"
TOMCAT_FILE="apache-tomcat-9.0.62.tar.gz"
JDK_DIR="/usr/local"
TOMCAT_DIR="/usr/local"

color () {
    RES_COL=60
    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
    SETCOLOR_FAILURE="echo -en \\033[1;31m"
    SETCOLOR_WARNING="echo -en \\033[1;33m"
    SETCOLOR_NORMAL="echo -en \E[0m"
    echo -n "$2" && $MOVE_TO_COL
    echo -n "["
    if [ $1 = "success" -o $1 = "0" ] ;then
        ${SETCOLOR_SUCCESS}
        echo -n $"  OK  "    
    elif [ $1 = "failure" -o $1 = "1"  ] ;then
        ${SETCOLOR_FAILURE}
        echo -n $"FAILED"
    else
        ${SETCOLOR_WARNING}
        echo -n $"WARNING"
    fi
    ${SETCOLOR_NORMAL}
    echo -n "]"
    echo                                                                                                                              
}

install_jdk () {
if !  [  -f "$DIR/$JDK_FILE" ];then
    color 1 "$JDK_FILE 文件不存在" 
    exit; 
elif [ -d $JDK_DIR/jdk ];then
    color 1  "JDK 已经安装" 
    exit
else 
    [ -d "$JDK_DIR" ] || mkdir -pv $JDK_DIR
fi
tar xvf $DIR/$JDK_FILE  -C $JDK_DIR
cd  $JDK_DIR && ln -s jdk1.8.* jdk 

cat >  /etc/profile.d/jdk.sh <<EOF
export JAVA_HOME=$JDK_DIR/jdk
export JRE_HOME=\$JAVA_HOME/jre
export CLASSPATH=\$JAVA_HOME/lib/:\$JRE_HOME/lib/
export PATH=\$PATH:\$JAVA_HOME/bin
EOF
.  /etc/profile.d/jdk.sh
java -version && color 0 "JDK 安装完成" || { color 1  "JDK 安装失败" ; exit; }

}

install_tomcat () {
if ! [ -f "$DIR/$TOMCAT_FILE" ];then
    color 1 "$TOMCAT_FILE 文件不存在" 
    exit; 
elif [ -d $TOMCAT_DIR/tomcat ];then
    color 1 "TOMCAT 已经安装" 
    exit
else 
    [ -d "$TOMCAT_DIR" ] || mkdir -pv $TOMCAT_DIR
fi
tar xf $DIR/$TOMCAT_FILE -C $TOMCAT_DIR
cd  $TOMCAT_DIR && ln -s apache-tomcat-*/  tomcat
echo "PATH=$TOMCAT_DIR/tomcat/bin:"'$PATH' > /etc/profile.d/tomcat.sh
id tomcat &> /dev/null || useradd -r -s /sbin/nologin tomcat

cat > $TOMCAT_DIR/tomcat/conf/tomcat.conf <<EOF
JAVA_HOME=$JDK_DIR/jdk
EOF

chown -R tomcat.tomcat $TOMCAT_DIR/tomcat/

cat > /lib/systemd/system/tomcat.service  <<EOF
[Unit]
Description=Tomcat
#After=syslog.target network.target remote-fs.target nss-lookup.target
After=syslog.target network.target 

[Service]
Type=forking
EnvironmentFile=$TOMCAT_DIR/tomcat/conf/tomcat.conf
ExecStart=$TOMCAT_DIR/tomcat/bin/startup.sh
ExecStop=$TOMCAT_DIR/tomcat/bin/shutdown.sh
RestartSec=3
PrivateTmp=true
User=tomcat
Group=tomcat

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now tomcat.service &> /dev/null
systemctl is-active tomcat.service &> /dev/null && color 0 "TOMCAT 安装完成" || { color 1 "TOMCAT 安装失败" ; exit; }
}

install_jdk 
install_tomcat
root@ubuntu:~# bash -n install_tomcat.sh
root@ubuntu:~# bash install_tomcat.sh

2、多虚拟主机配置

  • name 必须是主机名,用主机名来匹配
  • appBase 当前主机的网页根目录,是相对于$CATALINA_HOME,也可以使用绝对路径
  • unpackWARs 是否自动解压war格式
  • autoDeploy 热部署,自动加载并运行应用

2.1、修改Tomcat的配置文件,实现基于主机名的虚拟主机

#这个是默认的tomcat的server.xml配置
root@ubuntu:~# grep -v '\-\-' /usr/local/tomcat/conf/server.xml
<?xml version="1.0" encoding="UTF-8"?>
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.security.SecurityListener" />
  <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" />

       Documentation at /docs/jndi-resources-howto.html
  <GlobalNamingResources>
         UserDatabaseRealm to authenticate users
    <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>

       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
  <Service name="Catalina">

    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>


         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443" />

         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).

    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    <Engine name="Catalina" defaultHost="localhost">

          /docs/cluster-howto.html  (simple how to)
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

      <Realm className="org.apache.catalina.realm.LockOutRealm">
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />

             Documentation at: /docs/config/valve.html
        <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>
#修改server.xml配置文件
root@ubuntu:~# tail /usr/local/tomcat/conf/server.xml
        <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段指的就是两个基于域名的虚拟主机
      <Host name="web1.stars.org" appBase="/data/webapps1/" unpackWARs="True" autoDeploy="false"/>
      <Host name="web2.stars.org" appBase="/data/webapps2/" unpackWARs="True" autoDeploy="false"/>
    </Engine>
  </Service>
</Server>
#在准备好两个基于域名的虚拟主机需要的目录和文件
root@ubuntu:~# mkdir /data/webapps{1,2}/ROOT -pv
mkdir: created directory '/data/webapps1'
mkdir: created directory '/data/webapps1/ROOT'
mkdir: created directory '/data/webapps2'
mkdir: created directory '/data/webapps2/ROOT'
root@ubuntu:~# vim /data/webapps1/ROOT/index.jsp
<%@ page import="java.util.*" %>                                                                     
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>tomcat test</title>
</head>
<body>
 Tomcat Website1 
<div>On  <%=request.getServerName() %></div>
<div><%=request.getLocalAddr() + ":" + request.getLocalPort() %></div>
<div>SessionID = <span style="color:blue"><%=session.getId() %></span></div>
<%=new Date()%>
</body>
</html>
root@ubuntu:~# vim /data/webapps2/ROOT/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Tomcat Website2</title>
</head>
<body>
后面的内容是服务器端动态生成字符串,最后拼接在一起
<%
out.println("hello jsp");
%>
<br>
<%=request.getRequestURL()%>                                                                         
</body>
</html>
root@ubuntu:~# tree /data/
/data/
├── webapps1
│   └── ROOT
│       └── index.jsp
└── webapps2
    └── ROOT
        └── index.jsp

4 directories, 2 files
#创建的目录和文件所属主的修改
root@ubuntu:~# chown -R tomcat.tomcat /data/webapps{1,2}/
#修改完后就可以重启一下服务了
root@ubuntu:~# systemctl restart tomcat.service 
root@ubuntu:~# systemctl status tomcat.service 
● tomcat.service - Tomcat
   Loaded: loaded (/lib/systemd/system/tomcat.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2022-05-07 05:52:29 UTC; 2s ago
  Process: 21076 ExecStop=/usr/local/tomcat/bin/shutdown.sh (code=exited, status=0/SUCCESS)
  Process: 21136 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 21144 (java)
    Tasks: 29 (limit: 2284)
   CGroup: /system.slice/tomcat.service
           └─21144 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/log

May 07 05:52:29 ubuntu systemd[1]: Starting Tomcat...
May 07 05:52:29 ubuntu systemd[1]: Started Tomcat.

2.2、通过浏览器访问测试(TCP:8080)

tomcat访问默认使用的端口是8080端口,所以刚刚建的两个网站也是要通过8080端口访问的

#在本地window主机修改好本地的hosts文件做好域名解析,hosts文件路径C:\Windows\System32\drivers\etc\
10.0.0.100 web1.stars.org web2.stars.org

image.png image.png image.png

2.3、修改tomcat实现多虚拟主机的端口为(TCP80)

#这里改端口也是修改那个server.xml文件
root@ubuntu:~# vim /usr/local/tomcat/conf/server.xml
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
#不过这还要修改一下一下tomcat.service这个文件,当时我们指定了tomcat用户启动这个服务,非root用户不能使用1024以下的端口。
root@ubuntu:~# vim /lib/systemd/system/tomcat.service
[Unit]
Description=Tomcat
#After=syslog.target network.target remote-fs.target nss-lookup.target
After=syslog.target network.target 

[Service]
Type=forking
EnvironmentFile=/usr/local/tomcat/conf/tomcat.conf
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
RestartSec=3
PrivateTmp=true
#需要把这两行注释掉,才可以绑定到80端口
#User=tomcat
#Group=tomcat

[Install]
WantedBy=multi-user.target
root@ubuntu:~# systemctl daemon-reload
root@ubuntu:~# systemctl restart tomcat.service 
root@ubuntu:~# systemctl status tomcat.service 
● tomcat.service - Tomcat
   Loaded: loaded (/lib/systemd/system/tomcat.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2022-05-07 06:21:32 UTC; 2s ago
  Process: 21413 ExecStop=/usr/local/tomcat/bin/shutdown.sh (code=exited, status=0/SUCCESS)
  Process: 21438 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 21446 (java)
    Tasks: 29 (limit: 2284)
   CGroup: /system.slice/tomcat.service
           └─21446 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/log

May 07 06:21:32 ubuntu systemd[1]: Starting Tomcat...
May 07 06:21:32 ubuntu startup.sh[21438]: Tomcat started.
May 07 06:21:32 ubuntu systemd[1]: Started Tomcat.

2.4、通过浏览器访问测试(TCP:80)

image.png image.png image.png 注意:在这个测试是可以改端口的,在生产中一般不会修改成80端口,生产中一般都不会让用户直接访问tomcat服务,一般都是通过代理到tomcat让用户访问,一般用的多的是nginx和haproxy这两个多一点,也可以加上keepalived实现高可用的场景。