Tomcat笔记

Tomcat笔记

1.1 java运行环境简介

java程序有着一次编译,随处运行的特性,此特性主要与java的运行环境jre有关。jre中的bin文件夹对应java虚拟机即jvm;jre中的lib文件夹则包含jvm运行java类文件所需的各种库文件,两者共同组成了java程序的运行环境。jdk则是java程序的开发环境,其内包含jre。

1.2 java代码运行过程

Java代码的运行:

    *.java(source code) --> javac --> *.class(bytecode) -->jre运行

java源码由javac编译器编译为class类文件(字节码)再交由jre环境运行。

1.3 jsp与serverlet(本段引自博客园——骏马金龙)

在web应用程序上,早期Java的实现方式是服务器端放置应用程序,客户端访问时将其下载到客户端本地并执行,这样不仅不安全,而且要求客户有java运行环境,这种实现方式是applet。

与applet相对的是servlet,但它是服务端程序。后来,java将应用程序放在服务器端,客户端请求此应用程序时,服务端通过servlet类库分析http协议,将请求的应用程序在服务端执行,然后将结果组织起来返回给客户端,但此时servlet能分析的http协议非常简单,且和html的组织方式非常不友好,它要求java程序员首先得懂html开发(实际上现在还是如此,java程序员至少要懂简单的html/css/javascript等前端技术),于是后来出现了JSP类库。

JSP可以简单的将java代码嵌入在html文档中,它们能够很友好地结合,结合后的文档类型为.jsp文件。当客户端请求应用程序资源时,JSP类库负责解析.jsp文件中的jsp部分并通过jasper组件将其翻译成servlet的java源代码,然后再编译成class文件并交给JVM来执行。实际上,jsp的本就就是servlet,jsp类只不过是继承于servlet类并添加了一些和html友好结合的特性,最终它还是要翻译成servlet代码。

JSP的本质还是Servlet,每个JSP页面就是一个Servlet对象(当然也可能引用了其他servlet对象),Servlet再负责响应用户的动态请求数据(其实也包括静态数据,因为jasper翻译jsp代码时,静态标签也被翻译到servlet的java源文件中以待输出)。对于Tomcat而言,JSP页面生成的Servlet放在work路径对应的Web应用下。

考虑到tomcat和httpd、nginx等http服务程序的对比,有两点需要明确:

(1).一个java程序只有一个进程,但是可以有多个线程,也就是说java程序的开发是基于线程的。那唯一的进程就是JVM进程,每个应用程序都开启一个JVM进程,根据开发时设计的多线程代码,在这个JVM进程中会启动多个线程。它不像httpd或nginx,能开启多进程(对于tomcat而言,这意味着多个不同的应用程序甚至意味着开启多个tomcat实例)。

(2).tomcat可以处理动态请求,也可以处理静态资源请求。但无论是动态资源,还是静态资源的请求,都是经过servlet处理并响应给客户端的,只不过请求静态资源时使用的是默认的servlet。虽然它能像httpd和nginx一样处理静态资源,但显然,它既要处理动态请求,又要处理静态请求,压力会很大。因此tomcat前一般使用httpd或nginx专门处理静态请求,而动态请求则通过反向代理的方式代理至tomcat。

1.4 tomcat简介

1.4.1 tomcat结构:(本段引自博客园——骏马金龙)

tomcat是jdk+servlet(严格地说是+jsp)实现的精简版的java ee,由于它只在jdk的基础上附加了jsp和servlet类库,所以它的应用范围主要是web应用。tomcat项目目前由apache软件基金会维护。

  • server是顶级类,一个server算是一个tomcat实例,在此层次中可定义tomcat服务的监听端口。
  • service是server下的子组件,用于封装绑定connector和containor,并为它们提供一个名称属性。有了service就可以提供相关的服务,如监听TCP连接请求、处理http请求。注意server是管理整个tomcat实例的层次,它和提供服务没有关系。
  • connector是连接器,定义http协议(默认)以及该协议的监听端口。连接器用于接收客户端请求并将containor处理的数据返回给客户端
  • containor称为容器,它和connector连接器进行绑定。该容器内有4个子容器,包括:engine容器、host容器、context容器、Wrapper容器。容器用于分析、处理请求,并构建响应给connector以发送给客户端。它和connector是tomcat的心脏组件。
  • engine容器定义servlet引擎,用于定义引擎的名称、默认的虚拟主机。引擎用于分析http请求并将请求转发给对应的虚拟主机。
  • host容器用于定义虚拟主机。
  • context容器用于定义webapp,一个context定义一个webapp。它是真正管理servlet容器的层次。
  • wrapper容器对应的是真正的servlet容器,一个wrapper代表一个servlet,它负责管理一个Servlet,包括的Servlet的装载、初始化、执行以及资源回收。Wrapper是最底层的容器,一个context只能包含一个wrapper。在配置文件中,无法配置该容器的属性。

一个server可以有多个service。一个service可以有多个connector和唯一的containor。containor是容器类,从containor层次开始,真正进入servlet容器相关的过程。它包含了唯一的engine容器,engine容器中包含了一个或多个host容器,host容器中包含了一个或多个context容器,context容器中包含了唯一的wrapper。它们的组织结构大致如下:

1.4.2 tomcat的目录结构:
        bin:脚本,及启动时用到的类;

        conf:配置文件目录;

        lib:库文件,Java类库,jar;

        logs:日志文件目录;

        temp:临时文件目录;

        webapps:webapp的默认目录;

        work:工作目录;
1.4.3 rpm包安装的程序环境:
        配置文件目录:/etc/tomcat

            主配置文件:server.xml

        webapps存放位置:/var/lib/tomcat/webapps/

            examples

            manager

            host-manager

            docs

        Unit File:tomcat.service

        环境配置文件:/etc/sysconfig/tomcat
1.4.4 tomcat的配置文件构成:
        server.xml:主配置文件;

        web.xml:每个webapp只有“部署”后才能被访问,它的部署方式通常由web.xml进行定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认部署相关的配置;

        context.xml:每个webapp都可以专用的配置文件,它通常由专用的配置文件context.xml来定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认配置;

        tomcat-users.xml:用户认证的账号和密码文件;

        catalina.policy:当使用-security选项启动tomcat时,用于为tomcat设置安全策略;

        catalina.properties:Java属性的定义文件,用于设定类加载器路径,以及一些与JVM调优相关参数;

        logging.properties:日志系统相关的配置;
1.4.5 JSP WebAPP的组织机构

/: webapps的根目录

            index.jsp:主页;

            WEB-INF/:当前webapp的私有资源路径;通常用于存储当前webapp的web.xml和context.xml配置文件;

            META-INF/:类似于WEB-INF/;

            classes/:类文件,当前webapp所提供的类;

            lib/:类文件,当前webapp所提供的类,被打包为jar格式;
    webapp归档格式:

        .war:webapp

        .jar:EJB的类打包文件;

        .rar:资源适配器类打包文件;

        .ear:企业级webapp;
1.4.6 部署webapp的相关操作

deploy:将webapp的源文件放置于目标目录(网页程序文件存放目录),配置tomcat服务器能够基于web.xml和context.xml文件中定义的路径来访问此webapp;将其特有的类和依赖的类通过class loader装载至JVM;

        部署有两种方式:

            自动部署:auto deploy

            手动部署:

                冷部署:把webapp复制到指定的位置,而后才启动tomcat;

                热部署:在不停止tomcat的前提下进行部署;

                    部署工具:manager、ant脚本、tcd(tomcat client deployer)等;                    

    undeploy:反部署,停止webapp,并从tomcat实例上卸载webapp;

    start:启动处于停止状态的webapp;

    stop:停止webapp,不再向用户提供服务;其类依然在jvm上;

    redeploy:重新部署;

2.1 tomcat的安装

2.1.1 安装JDK
OpenJDK:

        java-VERSION-openjdk:

            The OpenJDK runtime environment.

        java-VERSION-openjdk-headless:

             The OpenJDK runtime environment without audio and video support.

        java-VERSION-openjdk-devel:

            The OpenJDK development tools. #服务端必须安装开发环境用于编译java代码
        注意:多版本并存时,可使用 alternatives命令设定默认使用的版本;

    Oracle JDK:

        安装相应版本的rpm包;或者从官网下载对应版本tar包

            jdk-VERSION-OS-ARCH.rpm

            例如:jdk-1.8.0_25-linux-x64.rpm
   注意:yum/rpm安装完成后不需要设置环境变量;二进制tar包展开后要配置JAVA_HOME环境变量,指向java的安装路径;

echo 'export JAVA_HOME=/usr/java/latest' > /etc/profile.d/jdk.sh
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile.d/jdk.sh
. /etc/profile.d/jdk.sh
设置完成后可以使用java命令查看version确定设置正确与否
[root@storm ~]# java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
2.1.2 安装tomcat

同样的tomcat如果使用yum安装不需要配置环境变量,下载tar包展开后需要设置如下:

echo "export CATALINA_HOME=/usr/local/tomcat" > /etc/profile.d/tomcat.sh
echo 'export PATH=$CATALINA_HOME/bin:$PATH' >> /etc/profile.d/tomcat.sh
. /etc/profile.d/tomcat.sh

yum安装tomcat.noarch、tomcat-admin-webapps.noarch(webgui管理功能包) 、tomcat-docs-webapp.noarch(web文档包),安装命令指明这三个包即可,其他包由yum依据依赖关系安装。

1535249107040

安装完成后试运行可以发现8080、8005、8009端口均已监听。

访问8080端口可以看到tomcat的欢迎界面

1535249260902

如上图所示,app与host的web管理功能由tomcat-admin-webapps.noarch提供,帮助文档则由tomcat-docs-webapp.noarch提供。健康检测页面与另外两个管理功能均需要在配置文件中设置用户验证才能访问。

点击这三个页面的任意按钮,会提示验证,取消后转到tomcat自带的401页面,此页面提示如下:

You are not authorized to view this page. If you have not changed any configuration files, please examine the file "conf/tomcat-users.xml" in your installation. That file must contain the credentials to let you use this webapp. 
For example, to add the manager-gui role to a user named tomcat with a password of s3cret, add the following to the config file listed above. 
<role rolename="manager-gui"/>
<user username="tomcat" password="s3cret" roles="manager-gui"/>
Note that for Tomcat 7 onwards, the roles required to use the manager application were changed from the single manager role to the following four roles. You will need to assign the role(s) required for the functionality you wish to access. 
manager-gui - allows access to the HTML GUI and the status pages
manager-script - allows access to the text interface and the status pages
manager-jmx - allows access to the JMX proxy and the status pages
manager-status - allows access to the status pages only
The HTML interface is protected against CSRF but the text and JMX interfaces are not. To maintain the CSRF protection: 
Users with the manager-gui role should not be granted either the manager-script or manager-jmx roles.
If the text or jmx interfaces are accessed through a browser (e.g. for testing since these interfaces are intended for tools not humans) then the browser must be closed afterwards to terminate the session.
For more information - please see the Manager App HOW-TO. 

注意:yum安装的用户配置文件在/etc/tomcat/tomcat-users.xml ,且配置用户后需要重启tomcat服务。

2.2 tomcat常用组件配置

Server组件:

代表tomcat instance,即表现出的一个java进程;监听在8005端口,只接收“SHUTDOWN”。各server监听的端口不能相同,因此,在同一物理主机启动多个实例时,需要修改其监听端口为不同的端口;一个server可以有多个engine;

Service组件:

用于实现将一个或多个connector组件关联至一个engine组件;一个sever可以有多个service;一个service只能有一个engine;

Connector组件:

一个连接器只能有一个service,也就只能有一个engine;

        负责接收请求,常见的有三类http/https/ajp;

        进入tomcat的请求可分为两类:

            (1) standalone : 请求来自于客户端浏览器;

            (2) 由其它的web server反代:来自前端的反代服务器;

                nginx --> http connector --> tomcat

                httpd(proxy_http_module) --> http connector --> tomcat

                httpd(proxy_ajp_module) --> ajp connector --> tomcat

                httpd(mod_jk) --> ajp connector --> tomcat   

        属性:

            port="8080"

            protocol="HTTP/1.1"

            connectionTimeout="20000"

            address:监听的IP地址;默认为本机所有可用地址;

            maxThreads:最大并发连接数,默认为200;

            enableLookups:是否启用DNS查询功能;

            acceptCount:等待队列的最大长度;

            secure:

            sslProtocol:

Engine组件:

Servlet实例,即servlet引擎,其内部可以一个或多个host组件来定义站点; 通常需要通过defaultHost来定义默认的虚拟主机;一般来说,仅使用基于主机名的虚拟主机;

        属性:

            name=

            defaultHost="localhost"

            jvmRoute=    

Host组件:

位于engine内部用于接收请求并进行相应处理的主机或虚拟主机,示例:

         <Host name="localhost"  appBase="webapps"

            unpackWARs="true" autoDeploy="true">

        </Host>

        常用属性说明:

            (1) appBase:此Host的webapps的默认存放目录,指存放非归档的web应用程序的目录或归档的WAR文件目录路径;可以使用基于$CATALINA_BASE变量所定义的路径的相对路径;

            (2) autoDeploy:在Tomcat处于运行状态时,将某webapp放置于appBase所定义的目录中时,是否自动将其部署至tomcat;

            示例:
             <Host name="[tc1.magedu.com](http://tc1.magedu.com/)" appBase="/appdata/webapps" unpackWARs="true" autoDeploy="true">

             </Host>

手动提供一测试类应用,并冷部署:

mkidr -pv /usr/local/tomcat/webapps/test/{classes,lib,WEB-INF}

创建文件/usr/local/tomcat/webapps/test/index.jsp

 <%@ page language="java" %>

            <%@ page import="java.util.*" %>
    
            <html>
    
                <head>
    
                    <title>Test Page</title>
    
                </head>
    
                <body>
    
                    <% out.println("hello world");
    
                    %>
    
                </body>
    
            </html>       

Context组件:

        示例:

            <Context path="/PATH" docBase="/PATH/TO/SOMEDIR" reloadable=""/>       

    综合示例:

        <Host name="[node1.magedu.com](http://node1.magedu.com/)" appBase="/web/apps" unpackWARs="true" autoDeploy="true">

            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

                prefix="node1_access" suffix=".log"

                pattern="%h %l %u %t &quot;%r&quot; %s %b" />

            <Context path="/test" docBase="test" reloadable="">

                <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

                prefix="node1_test_access_" suffix=".log"

                pattern="%h %l %u %t &quot;%r&quot; %s %b" />

            </Context>

        </Host>                   

Valve组件:
Valve存在多种类型:

定义访问日志:org.apache.catalina.valves.AccessLogValve

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

定义访问控制:org.apache.catalina.valves.RemoteAddrValve

<Valve className="org.apache.catalina.valves.RemoteAddrValve" deny="172\.16\.100\.67"/>

2.3 tomcat的被代理模式

AT模式: Apache(httpd) + Tomcat,如果使用Nginx+Tomcat则仅能使用HTTP协议。

    httpd的代理模块:

        proxy_module

        proxy_http_module:适配http协议客户端;

        proxy_ajp_module:适配ajp协议客户端;

    Client (http) --> httpd (proxy_http_module)(http) --> tomcat  (http connector)

    Client (http) --> httpd (proxy_ajp_module)(ajp) --> tomcat  (ajp connector)

proxy_http_module代理配置示例:

            <VirtualHost *:80>

                ServerName      [tc1.magedu.com](http://tc1.magedu.com/)

                ProxyRequests Off

                ProxyVia        On

                ProxyPreserveHost On

                <Proxy *>

                    Require all granted

                </Proxy>

                ProxyPass / <http://tc1.magedu.com:8080/>

                ProxyPassReverse / <http://tc1.magedu.com:8080/>

                <Location />

                    Require all granted

                </Location>

            </VirtualHost>

proxy_ajp_module代理配置示例:

            <VirtualHost *:80>

                ServerName      [tc1.magedu.com](http://tc1.magedu.com/)

                ProxyRequests Off

                ProxyVia        On

                ProxyPreserveHost On

                <Proxy *>

                    Require all granted

                </Proxy>

                    ProxyPass / <ajp://tc1.magedu.com:8009/>

                    ProxyPassReverse / <ajp://tc1.magedu.com:8009/>

                <Location />

                    Require all granted

                </Location>

            </VirtualHost>

3.1 Tomcat的常用优化配置:

3.1.1 内存空间参数

内存空间:单java进程最大可用使用32G内存

内存空间:单java进程最大可用使用32G内存

        /etc/sysconfig/tomcat
            JAVA_OPTS="-server -Xms32g -Xmx32g -XX:NewSize= -XX:MaxNewSize= -XX:PermSize= -XX:MaxPermSize="
                -server:hotspot jvm的server模式默认占用64M内存,如果是client则是32M;
                -Xms:堆内存初始化大小,建议与Xmx一致,即开始就分配所有内存;
                -Xmx:堆内存空间上限;
                -XX:NewSize=:新生代空间初始化大小;                    
                -XX:MaxNewSize=:新生代空间最大值;建议不设定,由程序自行决定。
                -XX:PermSize=:持久代空间初始化大小;
                -XX:MaxPermSize=:持久代空间最大值;
3.1.2 线程池设置:

对于tomcat来说,线程池参数主要在connector中设置。

        <Connector port="8080" protocol="HTTP/1.1"  connectionTimeout="20000" redirectPort="8443" />        

        常用属性:

            maxThreads:最大线程数;

            minSpareThreads:最小空闲线程数;

            maxSpareThreads:最大空闲线程数;

            acceptCount:等待队列的最大长度;

            URIEncoding:URI地址编码格式,建议使用UTF-8;

            enableLookups:是否启用dns解析,建议禁用;

            compression:是否启用传输压缩机制,建议“on";

            compressionMinSize:启用压缩传输的数据流最小值,单位是字节;

            compressableMimeType:定义启用压缩功能的MIME类型;

                text/html, text/xml, text/css, text/javascript      
3.1.3 禁用8005端口;
        <Server port="-1" shutdown="SHUTDOWN">
3.1.4 隐藏版本信息:
        <Connector port="8080" protocol="HTTP/1.1"  connectionTimeout="20000" redirectPort="8443" />

        Server="SOME STRING"

3.2 常用检查工具

    jstat:对jvm应用程序的资源和性能进行实时监控;

    jstack:查看所有线程的运行状态;

    jconsole:图形工具

    jvisualvm:图形工具

jps:Java virutal machine Process Status tool,用来查看运行的所有jvm进程;

        jps [-q] [-mlvV] [<hostid>]

            -q:静默模式;

            -v:显示传递给jvm的命令行参数;

            -m:输出传入main方法的参数;

            -l:输出main类或jar完全限定名称;

            -V:显示通过flag文件传递给jvm的参数;

            [<hostid>]:主机id,默认为localhost;

jinfo:输出给定的java进程的所有配置信息;

        jinfo [option] <pid>

            -flags:to print VM flags

            -sysprops:to print Java system properties

            -flag <name>:to print the value of the named VM flag

jstack:查看指定的java进程的线程栈的相关信息;

        jstack [-l] <pid>

        jstack -F [-m] [-l] <pid>

            -l:long listings,会显示额外的锁信息,因此,发生死锁时常用此选项;

            -m:混合模式,既输出java堆栈信息,也输出C/C++堆栈信息;

            -F:当使用“jstack -l PID"无响应,可以使用-F强制输出信息;

jstat:输出指定的java进程的统计信息

        jstat -help|-options

        jstat -<option> [-t][-h] <vmid> [<interval> [<count>]]

        \# jstat -options

            -class:class loader

            -compiler:JIT

            -gc:gc

            -gccapacity:统计堆中各代的容量

            -gccause:

            -gcmetacapacity

            -gcnew:新生代

            -gcnewcapacity

            -gcold:老年代

            -gcoldcapacity

            -gcutil

            -printcompilation

        [<interval> [<count>]]

            interval:时间间隔,单位是毫秒;

            count:显示的次数;

        -gc:

            YGC:新生代的垃圾回收次数;

            YGCT:新生代垃圾回收消耗的时长;

            FGC:Full GC的次数;

            FGCT:Full GC消耗的时长;

            GCT:GC消耗的总时长;
posted @ 2018-08-26 16:27  望月胡杨  阅读(177)  评论(0编辑  收藏  举报