Tomcat(今天看到有一篇總結比較好的帖子轉一下,後續忘了可以回來看看)

原文鏈接:https://blog.51cto.com/13570193/2165362

https://blog.51cto.com/13570193/2165362

 

目錄

  • 部署tomcat
  • 主配置文件
  • Nginx+Tomcat實現動靜分離
  • Nginx+Tomcat+memcache實現高可用會話集羣

一、部署tomcat

第一步:安裝JDK
tomcat在處理客戶端請求的jsp文件的時候,會將jsp文件中的java程序提取出來並且運行,java程序能夠運行是需要JDK的支持的。
目前jdk存在兩個分支,一個是Oracle公司負責維護的jdk,一個是開源界維護的openjdk,並且openjdk軟件在CentOS的光盤中會提供。
方法一:使用Oracle的分支,進入Oracle官網下載jdk10版本,網址是https://www.oracle.com/technetwork/java/javase/downloads/jdk10-downloads-4416644.html
會看到Linux相對應的兩個文件,一個.rpm文件,一個.tar.gz文件(綠色版),.rpm文件就是普通rpm軟件包的正常安裝方式即可,.tar.gz文件下載下來之後直接解壓至指定目錄就可以使用。
Tomcat
然後安裝,安裝之後的文件目錄會存放在/usr/java目錄下。

[root@Web1 src]# pwd
/usr/local/src
[root@Web1 src]# ls jdk-10.0.2_linux-x64_bin.rpm 
jdk-10.0.2_linux-x64_bin.rpm
[root@Web1 src]# yum -y localinstall jdk-10.0.2_linux-x64_bin.rpm 
[root@Web1 src]# cd /usr/java/
[root@Web1 java]# ls
default  jdk-10.0.2  latest

可以看到生成了三個目錄,在jdk-10.0.2目錄下的bin目錄下存在一個java命令。需要將bin目錄下的命令配置到系統的PATH變量中。配置如下:

[root@Web1 ~]# vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/jdk-10.0.2
export PATH=$JAVA_HOME/bin:$PATH
# 重載環境變量
[root@Web1 ~]# source /etc/profile.d/java.sh
[root@Web1 ~]# which java
/usr/java/jdk-10.0.2/bin/java

到此爲止,JDK的安裝和PATH變量的配置已經完成,可以使用java -version命令查看安裝的JDK版本。
Tomcat
方法二:使用openjdk分支,openjdk在CentOS的本地光盤中就會提供,因此使用yum直接安裝即可。

[root@Web2 ~ ]# yum list all *openjdk*

執行上面的命令之後,會看到很多openjdk版本和各個版本的各個組件,假如使用java-1.8.0-openjdk這個版本,另外還需要關注相對應版本的java-1.8.0-openjdk-devel這個組件。他們的關係如下:
java-1.8.0-openjdk    java程序的運行環境
java-1.8.0-openjdk-devel java程序的編譯開發環境
僅安裝openjdk之後,只存在一個jre下的java命令,但是繼續安裝openjdk-devel之後,就會多出一個javac命令。
安裝這兩個組件,

[root@Web2 ~]# yum -y install java-1.8.0-openjdk.x86_64 java-1.8.0-openjdk-devel.x86_64

安裝後我們不知道bin目錄在什麼位置,這樣就無法配置系統的PATH變量。可以使用命令rpm來查看軟件包安裝後每個文件的位置:

[root@Web2 ~]# rpm -ql java-1.8.0-openjdk-devel |grep /bin$
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/bin

配置PATH變量

[root@Web2 ~]# vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64
export PATH=$JAVA_HOME/bin:$PATH
[root@Web2 ~]# source /etc/profile.d/java.sh
[root@Web2 ~]# which java
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/bin/java

Tomcat
第二步:安裝tomcat
方法一:tomcat在CentOS的本地光盤中就會提供,因此直接yum倉庫安裝即可。

[root@Web2 ~]# yum -y install tomcat tomcat-admin-webapps tomcat-webapps

其中tomcat-admin-webapps是一個tomca應用程序t的管理組件,tomcat-webapps是一個提供tomcat的默認歡迎首頁文件的組件。
tomcat安裝完成之後,會提供一個管理命令/usr/sbin/tomcat,而且還會提供相應的tomcat服務(CentOS6--/etc/init.d/tomcat start、CentOS7--systemctl start tomcat)。
啓動tomcat

[root@Web2 ~]# /usr/sbin/tomcat start

tomcat默認工作在非特權用戶下,因此tomcat就無法監聽80端口,因此tomcat默認監聽8080端口。
測試
瀏覽器中輸入ip:8080,出現下圖界面表示tomcat啓動成功。
Tomcat
方法二:在tomcat的官網下載安裝。網址爲:https://tomcat.apache.org/
下載成功後如下,然後解壓至/usr/local目錄下就可以使用。

[root@Web1 src]# pwd
/usr/local/src
[root@Web1 src]# ls apache-tomcat-8.5.32.tar.gz 
apache-tomcat-8.5.32.tar.gz
[root@Web1 src]# tar -zxvf apache-tomcat-8.5.32.tar.gz -C /usr/local/
[root@Web1 local]# ls -d /usr/local/apache-tomcat-8.5.32/
/usr/local/apache-tomcat-8.5.32/

這樣/usr/local目錄下的apache-tomcat-8.5.32太長,因此使用軟鏈接的方式,

[root@Web1 local]# pwd
/usr/local
[root@Web1 local]# ln -sv apache-tomcat-8.5.32/  tomcat8

解壓後的bin目錄下提供了一套tomcat的管理腳本,例如啓動tomcat的startup.sh,關閉tomcat的shutdown.sh,查看tomcat版本信息的version.sh等等。
Tomcat


二、主配置文件

tomcat的主配置文件server.xml文件的整體結構如下,而且文件結構也符合tomcat的架構層次。

<Server port="8005" shutdown="SHUTDOWN">
        <Service name="Catalina">
                <Connector port="8080" />
                <Connector  />
                ...
                <Engine name="Catalina" defaultHost="localhost">
                        <Host name="localhost">
                        ...
                        </Host>
                </Engine>
        </Service>
</Server>

tomcat是java語言開發的,因此配置文件也相符合於面向對象的思想,例如,文件中的每個元素創建“對象”,併爲屬性賦值實例化對象。
Tomcat
該配置文件中的元素都是大寫字母開頭。
Server
配置文件中的頂層元素,代表一個tomcat實例,並且配置文件中僅能有一個Server。

屬性 備註 屬性值
classname 實現server的類名  
port 接受關閉tomcat請求的端口,僅能綁定至127.0.0.1 8005
shutdown 定義關閉tomcat的字符串指令 SHUTDOWN

Tomcat
Listener
表示一個事件的監聽器

屬性 備註 屬性值
clsssname 實現該監聽器的類名  
SSLEngine 是否使用SSL on或者off

GlobalNamingResources
全局JNDI資源,該元素沒有任何屬性,所有的應用程序都可以引用全局JNDI資源。那什麼是JNDI資源呢?JNDI多用於java的數據庫連接中,到這裏我們首先要想到的是JDBC,在JDBC中,連接數據庫需要用戶名、用戶名密碼和數據庫名稱等參數,將來如果這三個參數中的任何一個修改,則整個程序中相關的地方都需要修改,簡直是牽一髮而動全身,因此出現JNDI技術,在JNDI中,將連接數據庫需要的用戶、用戶密碼和數據庫名稱等JDBC引用的參數定義爲一個整體(即這個整體中包含JDBC要用到類庫、數據庫驅動程序、用戶、用戶密碼等),然後爲這個整體設置一個名稱,這樣以後連接數據庫的時候直接在程序中引用這個整體的名稱即可,無論用戶、用戶密碼怎麼變換,只要這個整體的名稱不變,我們僅要修改這個整體的用戶和用戶密碼,而無需修改整個程序。這裏的這個整體就是JNDI數據源(JNDI資源)。
雖然GlobalNamingResources沒有定義任何的屬性,但是可以在<GlobalNamingResources>...</GlobalNamingResources>中嵌套Resource元素。
Resource
定義JNDI數據源

屬性 備註 默認值
name 定義的JNDI資源的名稱  
auth 指定管理Resource的管理器 有Container和Application兩種
type 使用的類名
description 描述信息 ---

示例:

  <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>

示例表示定義了一個名爲UserDataBase的全局JNDI數據源,使用容器管理該Resource,該數據源爲加載tomcat-users.xml文件至內存中而定義的用於用戶授權的數據庫。然後在認證文件tomcat-users.xml中添加如下幾行。表示用戶名爲admin,用戶密碼爲centos的認證用戶分別以manager-gui和admin-gui的角色登錄manager和host-manager的應用程序。
Tomcat
Tomcat
Service
包含一個或多個Connector和一個Engine的服務組件。屬性name表示該Service的名稱,默認保持 Catalina即可。<Service>...</Service>中可以嵌套Connector元素和Engine元素。
Connector
代表一個接受客戶端請求的連接器。

屬性 備註 屬性值
accepCount 等待隊列的長度 10
port 連接器監聽的端口
protocol 連接器應用的協議類型 http/https/ajp
connectionTimeout 連接的超時時間,單位爲毫秒 20000
address 連接器監聽的IP地址 默認爲所有地址,0.0.0.0
maxThreads 最大併發連接數 http連接器默認200,https連接器默認150
enableLookups 是否開啓DNS反解 true或false
clientAuth tomcat是否需要認證客戶端 默認false
redirectPort 重定向至指定端口的Connector 8443
scheme 如果爲SSL連接器,則爲https http/https
secure SSL連接器則爲true true或false
SSLEnabled 是否開啓SSL true或false
sslProtocol TLS

其中ajp協議應用在Apache在反向代理tomcat的場景,Apache和tomcat之間就是使用ajp協議通信,它是一種二進制協議。
Engine
代表一個servlet實例,用於處理Connector接受並傳遞過來的請求。

屬性 備註 屬性值
name 定義Engine的名稱 Catalina
defaultHost 定義Engine的默認虛擬主機 默認爲localhost
jvmRoute 應用於tomcat集羣中的session共享,會在一次會話中添加該值,獲得session sticky ---

Host
嵌套在<Engine name="Catalina" defaultHost="localhost"> ... </Engine>中的元素,代表一個虛擬主機,一個Engine可以有多個Host。

屬性 備註 屬性值
name 虛擬主機名
appBase 虛擬主機的站點根目錄 webapps
unpackWARs tomcat是否解開WAR歸檔文件,默認爲true,自動解開 true或false
autoDeploy 是否自動部署追加到根目錄下的新應用程序,默認爲true true或false

示例:
在Engine中新嵌套一個Host,也就是新增加一個虛擬主機,配置內容如下

      <Host name="Web1.linux.com" appBase="/data/webapps"
            unpackWARS="true" autoDeploy="true" />

創建appBase目錄,並且tomcat虛擬主機中的每個應用程序都是單獨放在一個目錄內,因此創建ROOT目錄,

[root@Web1 ~]# mkdir -p /data/webapps/ROOT
放入jsp測試頁面
[root@Web1 ~]# vim /data/webapps/ROOT/index.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>  
        <title>My JSP 'first.jsp' starting page</title>   
  </head>

  <body>
        <!-- 在JSP的頁面中以表格的形式打印九九乘法表 -->
     <h1>九九乘法表</h1>
     <%
         for(int i=1;i<=9;i++) {
             for(int j=1;j<=i;j++) {
                 out.println(i+"*"+j+"="+(i*j)+"  ");
        }
        out.println("<br/>");
      }
      %>
    </body>
</html>

然後hosts文件中添加Web1.linux.com記錄,瀏覽器中訪問。
Tomcat
Realm
訪問應用程序的時候需要安全認證,即需要輸入用戶和用戶密碼,Realm就是指定存儲驗證信息(用戶和用戶密碼)的數據源。

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>

表示通過UserDatabaseRealm的方式獲取驗證信息,並且該數據源爲GlobalNamingResources元素定義的全局JNDI資源UserDatebase。Realm元素嵌套的位置代表驗證的範圍,例如嵌套在Engine中,則Engine中所有的Host虛擬主機都共用這個認證信息。嵌套在Host中,則Host中所有的應用程序都共用這個認證信息。嵌套在Context中,則該應用程序使用這個認證信息。
Valve
可以嵌套在Engine、Host、Context元素中的組件,不同的類型可以實現特定的功能,例如AccessLogValve可以實現生成訪問日誌的功能,RemoteAddrValve可以實現控制遠程IP地址的訪問。
示例:

      <Host name="Web1.linux.com" appBase="/data/webapps"
            unpackWARS="true" autoDeploy="true">
<!--
    directory表示日誌存放的目錄,prefix和suffix分別表示生成的日誌文件名的前綴和後綴,pattern表示記錄日誌的格式
-->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="Web1_access_log" suffix=".log"
               pattern="%h %l %u %t "%r" %s %b" />
        <Valve className="org.apache.catalina.valves.RemoteAddrValve" 
               deny="192.168.239.1" />
         </Host>

繼續訪問Web1.linux.com,結果沒有返回頁面內容,並且在logs目錄下生成了訪問日誌。
Tomcat
Tomcat
Context
嵌套在Host中的元素,代表某個虛擬主機中的應用程序。常用屬性如下

屬性 備註
docBase 對應的web應用程序的目錄
path 指定該應用程序映射爲服務器根目錄的URI路徑,即host+path
reloadable 是否重新加載web應用程序類,默認爲false

注:tomcat虛擬主機中的每個應用程序必須單獨存在一個目錄中,docBase可以使用相對路徑和絕對路徑,相對路徑是相對於Host虛擬主機的appBase目錄。
如果path屬性值爲空字符串,則表示該應用程序爲根web應用,即ROOT目錄。
示例:

<Host name="Web1.linux.com" appBase="/data/webapps"
            unpackWARS="true" autoDeploy="true">
    <Context path="/test" docBase="test" reloadable="true" />
</Host>

然後創建web應用程序的jsp代碼,URL地址列中輸入http://web1.linux.com:8080/test ,查看訪問結果。

[root@Web1 ~]# mkdir -p /data/webapps/test
[root@Web1 test]# vim index.jsp 

<HTML>
    <HEAD>
        <TITLE>JSP test</TITLE>
    </HEAD>
    <BODY>
        <%
        out.println("<h1>Hello World!!</h1>");
        %>
    </BODY>
</HTML>

Tomcat


三、Nginx+Tomcat實現動靜分離

tomcat能夠處理用戶的web請求(包括動態資源和靜態資源),但是tomcat在處理靜態資源的時候性能並不是很好,更多的時候是讓tomcat只處理動態資源請求,因此使用tomcat大多是使用如下的架構:
Tomcat
在tomcat的前端加一個Nginx反向代理,Nginx接受用戶發來的Web請求,當請求的是靜態資源的時候,Nginx自己處理,當請求的動態資源的時候,則Nginx將請求代理到後面的tomcat實例。這樣來實現tomcat的性能最大化。
Nginx的反向代理配置如下:
當用戶請求的是除了jsp|do以外的靜態資源的時候,則Nginx自己到/data/webapps/html目錄下響應請求,但用戶請求的是jsp|do的動態資源的時候,則Nginx將請求代理到後邊的tomcat。因此來實現動靜分離。

[root@Web1 ~]# vim /etc/nginx/conf.d/proxy.conf
server {
    listen 80;
    server_name Web1.linux.com;
    index   index.jsp;

    location / {
        root /data/webapps/html;
        expires 30d;
    }
    location ~* \.(jsp|do)$ {
        proxy_pass http://localhost:8080;

    }
}

tomcat的sever.xml的主要配置如下:

      <Host name="localhost"  appBase="/data/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" />
        <Context path="" docBase="test" reloadable="true"/>
      </Host>

然後在/data/webapps/html目錄下編輯一個測試靜態資源,在/data/webapps/test目錄下編輯一個測試jsp動態代碼。

[root@Web1 ~]# cat /data/webapps/html/index.html 
<h2>This is static resource!</h2>
[root@Web1 ~]# cat /data/webapps/test/index.jsp 
<%@ page language="java" %>
<HTML>
    <HEAD>
        <TITLE>JSP test</TITLE>
    </HEAD>
    <BODY>
        <%
        out.println("<h1>This is dynamic resource!</h1>");
        %>
    </BODY>
</HTML>

測試:
在瀏覽器中輸入Nginx的IP地址。
Tomcat
Tomcat


四、Nginx+Tomcat+memcached實現高可用會話集羣

通過前端負載均衡器調度到後端不同Tomcat服務器的時候,會出現session不一致的問題。爲了解決這個問題,目前實現會話保持的方式主要一下三種:
① stickysession,會話綁定,通過前端調度器特定的算法,將同一個客戶端總是調度到後端同一臺服務器,例如Nginx做負載均衡的ip_hash算法。
② session replication,會話複製,這個操作在服務器自身上邊進行,服務器之間通過複製會話來實現會話同步,例如Tomcat自帶的會話集羣功能Cluster。
③ session server,會話服務器,通過將session存儲在特定的主機之上,服務器通過統一地訪問session主機實現會話同步,例如redis、memcached就是這種會話服務器。
環境拓撲:

主機 IP地址 功能
Master.linux.com 192.168.239.137 負載均衡調度器
Web1.linux.com 192.168.239.129 Nginx+tomcat1主機兼memcached1主機
Web2.linux.com 192.168.239.140 Nginx+tomcat2主機兼memcached2主機

注:Nginx+tomcat主機實現的tomcat的動靜分離。

第一步:安裝memcache
CentOS本地光盤中提供

[root@Web1 ~]# yum -y install memcached
[root@Web2 ~]# yum -y install memcached

然後開啓memcached服務,查看memcached的端口監聽狀態,
Tomcat
第二步:安裝tomcat的第三方類庫memcached-session-manager(簡稱msm)。
該項目在GitHub上。地址爲:https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration
需要下載 memcached-session-manager-${version}.jar,memcached-session-manager-tc8-${version}.jar(具體的tc版本要和tomcat版本相同,catalina.sh腳本的 version選項可以查看tomcat的版本信息) 和 spymemcached-${version}.jar。
Tomcat
使用msm還依賴serializer序列化工具,msm提供了四種序列化工具,選擇其中一種即可。
這四種連接memcached的序列化工具,分別爲kryo-serializer,javolution-serializer,xstream-serializer,flexjson-serializer。
Tomcat
這裏以javolution-serializer爲例,其下的兩個小組件的下載地址如下:
http://www.java2s.com/Code/JarDownload/javolution/javolution-5.5.1.jar.zip
該文件需要解壓成jar文件。
http://repo1.maven.org/maven2/de/javakaffee/msm/msm-javolution-serializer/2.1.1/msm-javolution-serializer-2.1.1.jar

所有的jar文件(這裏是5個)下載完成之後,將這些jar文件複製到$CATALINA_BASE/lib目錄下,該目錄下存放着tomcat調用的類庫文件(jar文件),我這裏的CATALINA_BASE爲/usr/local/tomcat8,即安裝目錄。
第三步:配置Context
在兩個tomcat主機的server.xml指定的應用程序下邊(即Context),添加Manager元素。具體信息如下:

<Host name="localhost"  appBase="/data/webapps"
            unpackWARs="true" autoDeploy="true">
            <Context path="" docBase="ROOT" reloadable="true">
             <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
                memcachedNodes="n1:192.169.239.129:11211,n2:192.168.239.140:11211"
                failoverNodes="n1"
                requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
                transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"/>
            </Context>
</Host>

memcachedNodes屬性指定每個memcache的節點信息,格式爲<節點標誌符:hostname:port>;
failoverNodes屬性指定哪一個memcache節點爲備用節點;
requestUriIgnorePattern屬性指定無需將靜態資源實現會話保持,因爲會話本來就是針對動態資源的;
transcoderFactoryClass屬性指定序列化工具。
第四步:實現前端的Nginx負載均衡

[root@Master ~]# vim /usr/local/nginx/conf/conf.d/balance.conf
    upstream webserver {
    # tomcat1
        server 192.168.239.129:80 weight=1;
    # tomcat2
        server 192.168.239.140:80 weight=2;
    }

    server {
        listen       80;
        server_name  web.linux.com;
        root    /data/html;
        index    index.php index.html index.htm;

        location / {
            proxy_set_header Host $host;
            proxy_set_header X-Forward-For $remote_addr;
            proxy_pass http://webserver;
        }
    }

到此整個配置已經完成,重啓tomcat重新加載新的server.xml文件。
添加測試代碼文件index.jsp。

[root@Web1 ~]# vim /data/webapps/ROOT/index.jsp 

<%@ page language="java" %>
 <html>
      <head><title>Tomcat 1</title></head>
          <body>
             <h1><font color="red">Tomcat1.linux.com</font></h1>
           <table align="centre" border="1">
            <tr>
                <td>Session ID</td>
            <% session.setAttribute("linux.com","linux..com"); %>
            <td><%= session.getId() %></td>
            </tr>
            <tr>
            <td>Created on</td>
           <td><%= session.getCreationTime() %></td>
           </tr>
      </table>
    </body>
</html>

在瀏覽器中輸入調度器的IP地址,一直刷新,可以看到調度到不同的tomcat,但是session卻保持不變。另外也可以看到連接的是n2的memcache。後邊的-n2表示session-id的後綴。
Tomcat
Tomcat
現在暫停n2的memcached服務,繼續刷新,session保持不變,但是連接的memcache變成了備用節點n1。實現了memcache的高可用。
Tomcat
Tomcat

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章