Tomcat应用容器安装和使用

2022-09-29 14:28:14 浏览数 (1)

[TOC]

1.前言简述

描述:Apache Tomcat是美国Apache软件基金会的一款轻量级Web应用服务器,该程序实现了对Servlet和JSP的支持。 Tomcat是在Sun公司推出的小型Servlet/JSP调试工具的基础上发展起来的一个优秀的Servlet容器,已成为目前开发企业JavaWeb应用的最佳Servlet容器选择之一。 Tomcat本身完全用java语言编写,所以tomcat的运行需要java的支持,所以要先安装JDK才能运行;

目前是Apache开源软件组织的一个软件项目它的官网 :http://tomcat.apache.org

使用范围:在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 JSP 程序的首选

用途:

  • Tomcat 服务器可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。
  • Tomcat 是apache的一个中间件软件,其可以提供jsp或者php的解析服务。

特点:

  • Tomcat 服务器是一个免费的开放源代码的Web
  • Tomcat 是一个Servlet(独立的进程单独运行的)和JSP容器;
  • Tomcat 由一系列可配置的组件构成保证了扩展性;

Tomcat的组成结构:

Tomcat本身由一系列可配置的组件构成,其中核心组件是Servlet容器组件,它是所有其他Tomcat组件的顶层容器。

每个组件都可以在Tomcat安装目录/conf/server.xml文件中进行配置,且每个Tomcat组件在该文件中对应一种配置元素。 下面用XML的形式展示各种Tomcat组件之间的关系

代码语言:javascript复制
<Server>代表整个Servlet容器组件,是最顶层元素,可以包含一个或多个元素<Service>
  <Service>包含一个<Engine>元素以及一个或多个<Connector>元素,这些<Connector>共享一个<Engine>
    <Connector/>代表和客户程序实际交互的组件,负责接收客户请求,以及向客户返回响应
    <Engine>每个<Service>元素只能包含一个<Engine>元素,它处理在同一个<Service>中所有<Connector>接收到的客户请求
      <Host>在一个<Engine>中可以包含多个<Host>,它代表一个虚拟主机(即一个服务器程序可以部署在多个有不同IP的服务器主机上),它可以包含一个或多个应用
          <Context>使用最频繁的元素,代表了运行在虚拟主机上的单个web应用
      </Host>
    </Engine>
  </Service>
</Server>

Tomcat体系结构图

WeiyiGeek.体系结构图

JavaWeb应用的发布方式:

  • 开放式目录方式:将应用复制到webapp/ROOT目录之中进行部署;
  • 利用war包部署方式:使用 Jar -cvf *.war 打包成为war包,然后采用manager进行部署或者采用IDEA直接部署;

常常使用场景:

WeiyiGeek.

补充:

  • Tomcat处理静态HTML的能力不如Apache服务器。
  • Tomcat不能直接支持和作为负载均衡。

2.安装介绍

2.1 环境安装

  • JDK全称是 Java Development Kit,是SUN公司免费提供的java语言的软件开发工具包,其中包含Java虚拟机(JVM),编写好的java源程序经过编译可生产java字节码,利用JVM解释这些字节码文件从而保证了Java的跨平台性。
    • JDK下载地址
  • Tomcat下载地址:http://tomcat.apache.org

安装环境:

代码语言:javascript复制
Centos7.x 3.10.0-957.12.2.el7.x86_64 
JDK 1.8 
Tomcat 8.x

安装操作步骤:

代码语言:javascript复制
#1.卸载系统自带的openjdk并安装jdk
rm -rf $(which java)
tar xf jdk-7u80-linux-x64.tar
mv jdk1.7.0_80/ /usr/local/java

#2.解压安装Tomcat
tar xf apache-tomcat-8.5.20.tar.gz
mv apache-tomcat-8.5.20 /usr/local/tomcat8

#3.设置JAVA与TOMCAT环境变量
$cat >> /etc/profile.d/javaEnv.sh<<END
#设置java根目录
export JAVA_HOME=/opt/tomcat/jdk8
export JRE_HOME=/opt/tomcat/jdk8/jre
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$CATALINA_HOME/lib/servlet-api.jar
#Tomcat路径设置
export TOMCAT_HOME=/opt/tomcat/apache-tomcat-8.5.45
export CATALINA_HOME=/opt/tomcat//apache-tomcat-8.5.45
#在PATH环境变量中添加java跟目录的bin子目录
export PATH=$PATH:$JAVA_HOME/bin:$TOMCAT_HOME/bin
END

$. /etc/profile #将java.sh 脚本导入到环境变量,使其生效

#4.运行 java -version 或者 javac -version 命令查看java版本
$java -version
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

#5.查看tomcat的安装情况
catalina.sh version
Using CATALINA_BASE:   /opt/tomcat//apache-tomcat-8.5.45
Using CATALINA_HOME:   /opt/tomcat//apache-tomcat-8.5.45
Using CATALINA_TMPDIR: /opt/tomcat//apache-tomcat-8.5.45/temp
Using JRE_HOME:        /opt/tomcat/jdk8/jre
Using CLASSPATH:       /opt/tomcat//apache-tomcat-8.5.45/bin/bootstrap.jar:/opt/tomcat//apache-tomcat-8.5.45/bin/tomcat-juli.jar
Server version: Apache Tomcat/8.5.45
Server built:   Aug 14 2019 22:21:25 UTC
Server number:  8.5.45.0
OS Name:        Linux
OS Version:     3.10.0-957.12.2.el7.x86_64
Architecture:   amd64
JVM Version:    1.8.0_211-b12
JVM Vendor:     Oracle Corporation


#6.启动Tomcat
$/usr/local/tomcat7/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat7
Using CATALINA_HOME: /usr/local/tomcat7
Using CATALINA_TMPDIR: /usr/local/tomcat7/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat7/bin/bootstrap.jar:/usr/local/tomcat7/bin/tomcat-juli.jar
Tomcat started.
Tomcat 默认运行在8080端口

$netstat -anpt |grep :8080
tcp 0 0 :::8080 :::* LISTEN 3318/java

#7.关闭Tomcat浏览器访问测试 http://IP:端口
/usr/local/tomcat7/bin/shutdown.sh

WeiyiGeek.

Docker 方式安装运行 描述:tomcat映像有多种样式,每一种都是针对特定的用例设计的。

  • tomcat:<version> : 基础镜像基于Debian
  • tomcat:<version>-slim : 此映像不包含默认标记中包含的公共包,只包含运行tomcat所需的最小包。除非您工作的环境中只部署tomcat映像,并且您有空间限制,否则我们强烈建议使用此存储库的默认映像。

此处以 tomcat:8.5.57-jdk8-openjdk-slim 为例进行安装使用:

代码语言:javascript复制
$ docker pull tomcat:8.5.57-jdk8-openjdk-slim
# 在实际有上传或者存储其它文件的应用情况下不建议采用直接挂载单个War包
$ docker run -it -v /apps/webapps/Hello.war:/usr/local/tomcat/webapps/Hello.war --rm -p 8888:8080 tomcat:8.5.57-jdk8-openjdk-slim 
# Run the default Tomcat server (CMD ["catalina.sh", "run"]):

Tomcat 8.x 镜像中文与时区支持

代码语言:javascript复制
# 版本修改情况:
# 1.镜像源以及中文字符集和东八区时区设置
FROM tomcat:8.5.64-jdk8
MAINTAINER  weiyigeek - <master@weiyigeek.top> - Tomcat env Support zh_CN UTF-8
RUN curl -s http://192.168.12.107:8080/sources.list -o /etc/apt/sources.list && 
    apt-get update && 
    apt-get install -y locales && 
    localedef -i zh_CN -c -f UTF-8 zh_CN.UTF-8 && 
    export LANG=zh_CN.UTF-8 && 
    cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && 
    echo "Asia/shanghai" > /etc/timezone
CMD ["catalina.sh", "run"]

2.2 常用命令

代码语言:javascript复制
$ tree /opt/tomcat/apache-tomcat-8.5.45/bin
├── bootstrap.jar
├── catalina.bat  #windows下的启动停止文件
├── catalina.sh   #Linux下启动停止文件
├── catalina-tasks.xml
├── ciphers.bat
├── ciphers.sh
├── commons-daemon.jar
├── commons-daemon-native.tar.gz
├── configtest.bat
├── configtest.sh
├── daemon.sh  #守护进程方式
├── digest.bat
├── digest.sh
├── setclasspath.bat
├── setclasspath.sh
├── shutdown.bat  #停止tomcat
├── shutdown.sh
├── startup.bat   #启动tomcat
├── startup.sh
├── tomcat-juli.jar
├── tomcat-native.tar.gz
├── tool-wrapper.bat
├── tool-wrapper.sh
├── version.bat
└── version.sh  #版本信息

2.3 Tomcat 镜像构建

描述: 自定义构建Tomcat镜像能更好的适应实际应用环境。

2.3 TomEE 镜像构建

描述: 自定义构建TomEE镜像能更好的适应实际应用环境。

代码语言:javascript复制
FROM openjdk:8-slim-buster
LABEL MAINTAINER=WeiyiGeek 
      EMAIL=master@weiyigeek.top 
      DESC=Build Debian OpenJDK Tomee container images
ENV CATALINA_HOME=/usr/local/tomee 
    PATH=/usr/local/tomee/bin:$PATH 
    TOMEE_VER=8.0.6 
    TOMEE_BUILD=webprofile 
    TZ=Asia/Shanghai 
    LANG=zh_CN.UTF-8

RUN set -ex 
  && mkdir -p "$CATALINA_HOME" 
  && ulimit -HSn 65535 
  && sed -i "/# End/i *  soft  nproc   65535" /etc/security/limits.conf 
  && sed -i "/# End/i *  hard  nproc   65535" /etc/security/limits.conf 
  && sed -i -e 's#http://deb.debian.org#https://mirrors.huaweicloud.com#g' -e 's|deb http:|#deb http:|g' /etc/apt/sources.list 
  && apt-get update 
  && apt-get install -y curl apt-transport-https locales 
  && localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8 
  && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 
  && apt-get clean && apt-get autoclean && apt-get -y autoremove 
  && rm -rf /var/lib/apt/lists/*

WORKDIR $CATALINA_HOME

# curl -fsSL 'https://www.apache.org/dist/tomee/KEYS' | awk -F ' = ' '$1 ~ /^  Key fingerprint$/ { gsub(" ", "", $2); print $2 }' | sort -u
RUN set -x 
    # for key in 
    #   223D3A74B068ECA354DC385CE126833F9CF64915 
    #   7A2744A8A9AAF063C23EB7868EBE7DBE8D050EEF 
    #   82D8419BA697F0E7FB85916EE91287822FDB81B1 
    #   9056B710F1E332780DE7AF34CBAEBE39A46C4CA1 
    #   A57DAF81C1B69921F4BA8723A8DE0A4DB863A7C1 
    #   B7574789F5018690043E6DD9C212662E12F3E1DD 
    #   B8B301E6105DF628076BD92C5483E55897ABD9B9 
    #   DBCCD103B8B24F86FFAAB025C8BB472CD297D428 
    #   F067B8140F5DD80E1D3B5D92318242FE9A0B1183 
    #   FAA603D58B1BA4EDF65896D0ED340E0E6D545F97 
    #   ; do 
    #   gpg --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys "$key" || 
    #   gpg --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys "$key" || 
    #   gpg --batch --keyserver hkp://pgp.mit.edu:80 --recv-keys "$key" ; 
    # done 
    && curl -fSL https://mirrors.aliyun.com/apache/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz -o tomee.tar.gz 
    # && curl -fSL https://dist.apache.org/repos/dist/release/tomee/tomee-${TOMEE_VER}/apache-tomee-${TOMEE_VER}-${TOMEE_BUILD}.tar.gz.asc -o tomee.tar.gz.asc 
    # && gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz 
    && tar -zxf tomee.tar.gz 
    && mv apache-tomee-${TOMEE_BUILD}-${TOMEE_VER}/* /usr/local/tomee 
    && mv ${CATALINA_HOME}/webapps/ROOT ${CATALINA_HOME}/webapps/Demo 
    && cp ${CATALINA_HOME}/conf/web.xml ${CATALINA_HOME}/conf/web.xml.bak 
    && cp ${CATALINA_HOME}/conf/server.xml ${CATALINA_HOME}/conf/server.xml.bak 
    && curl http://soft.weiyigeek.top:8000/web.xml -o ${CATALINA_HOME}/conf/web.xml 
    && curl http://soft.weiyigeek.top:8000/server.xml -o ${CATALINA_HOME}/conf/server.xml 
    && rm tomee.tar.gz 
    && rm bin/*.bat 
    && rm bin/*.exe 
    && rm -rf apache-tomee-${TOMEE_BUILD}-${TOMEE_VER} 
    && rm -rf ${CATALINA_HOME}/webapps/manager ${CATALINA_HOME}/webapps/docs ${CATALINA_HOME}/webapps/host-manager 
    && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* 
    && find /var/log/ -type f -exec truncate -s 0 {} ; 
    && find ${CATALINA_HOME}/ -maxdepth 1 -type f -delete 
    && useradd -g root tomee 
    && chown -R tomee:root /usr/local/tomee 
    && chmod -R g=u /usr/local/tomee

USER tomee
EXPOSE 8080
CMD ["catalina.sh", "run"]

执行docker build构建镜像,然后使用该镜像进行创建容器。

代码语言:javascript复制
$ docker build -t weiyigeek/tomee-8.0.6:latest -f Dockerfile .
$ docker run -d --name hello-world -p 8080:8080 
  -v /app/hello-world.war:/usr/local/tomee/webapps/ROOT.war  
  weiyigeek/tomee-8.0.6:latest

Tips : 自定义的安装软件时,当从远程http服务器中拉取时推荐采用自定义域名的方式。


3.配置部署

(1)虚拟目录的映射方式 从Tomcat6开始支持自动映射,即tomcat服务器会自动管理webapps目录下的所有web应用,并把它映射成虚拟目录,换句话说只需把web应用放在webapps目录下,不需要配置Context,外界可以直接访问

代码语言:javascript复制
#如果是放入非webapps目录下是放在其他地方,还是需要配置Context
#比如我的tomcat在C盘,我的项目在D盘,则需要在Host下增加如下虚拟目录映射语句。
<Context path="/myapp" docBase="D:/work/myapp"></Context>

(2)Context元素配置 tomcat在加载一个web应用时,会一次按照以下五种方式查找web应用中的元素,优先级异常降低直到找到为止

1.到Tomcat安装目录/conf/Context.xml文件中查找元素。

到Tomcat安装录/conf/[enginename]/[hostname]/context.xml.default文件中查找元素。

代码语言:javascript复制
[enginename]:表示的name属性
[hostname]:表示d的那么属性

3.到Tomcat安装目录/conf/[enginename]/[hostname]/[contextpath].xml文件中查找元素

代码语言:javascript复制
[contextpath]:表示单个Web应用的URL入口

4.到Web应用的META-INF/context.xml文件中查找元素

5.到Tomcat安装目录/conf/server.xml文件中查找元素。只适用于单个Web应用

(3)web.xml文件 该文件必须放在/WEB-INF目录下,但是从7.0版本开始Tomcat可以不使用web.xml文件,而是使用注解方式。

(4)将项目部署为Tomcat默认应用 即访问 http://localhost:8080 时出来的是tomcat自带的欢迎页面,改为登录到自己的项目主页。

方法一: 在Tomcat默认安装后,tomcat的主目录是webapps/root目录,所以如果想改变tomcat的主目录的话可以如下所做:

在/conf/server.xml文件的之间加入代码

代码语言:javascript复制
<Context path="" docBase="C:tomcat7webappsmyapp" reloadable="true" debug="0"></Context>
<!--
docBase改为自己需要的项目路径
如果建立了Apache和tomcat集群,Apache server 的默认端口是80 ,IE访问的方法只需输入:http://localhost,就可以自动定位到xx工程下面去
-->

方法二: 将tomcat安装目录下的ROOT下的所有文件删除,换成自己项目的文件,此法有点暴力。

方法三: Tomcat5.0以下版本在C:/Tomcat/conf/Catalina/localhost目录下会自动生成了一个ROOT.Xml,但是5.0以上版本不再生成此文件。

所以可以新建个ROOT.xml,在里面加入如下代码:

代码语言:javascript复制
<!--但是我自己在7.0版本上测试好像未成功,推荐方式1-->
<?Xml version='1.0' encoding='utf-8'?>
<Context crossContext="true" docBase="C:tomcat7webappsmyapp" path="" reloadable="true">
</Context>

Context元素的属性解释

  • path: 指定访问该Web应用的URL入口
  • docBase: 指定Web应用的文件路径,可以写绝对路径,也可以写相对于appBase属性的相对路径
  • className: 指定实现Context组件的Java类的名字,这个类必须实现org.apache.catalina.Contex接口,该属性默认值为org.apache.catalina.core.StandardContext(不建议大家改动)
  • reloadable:
    • true:Tomcat服务器在运行状态下回监视在WEB-INF/classes和WEB-INF/lib目录下的class文件的改动,以及监视Web应用的WEB-INF/web.xml文件的改动,如果检测到有更新,服务器会自动更新加载web应用。
    • false:Tomcat可以降低Tomcat的运行负荷,提高Tomcat的运行性能
  • 元素都会使用默认的标准Context组件,即className属性采用默认值org.apache.catalina.core.StandardContext,它除了拥有上面介绍到的属性外,还有自身专有的属性:
    • cachingAllowed:是否允许启用静态资源(HTML、图片、声音等)的缓存。默认值为true。
    • cacheMaxSize:设置静态资源缓存的最大值,单位为K。
    • workDir:指定Web应用的工作目录。
    • uppackWAR:默认值为true会把war文件展开为开放目录后再运行;为false时候直接运行war文件。

4.监控运行

4.1 Tomcat 配置 JMX 连接

描述:开启 JMX 远程连接以后,就可以通过 jconsole 和 jvisualvm 两个 JDK 内置工具连接 JMX 从而查看当前主机的 JVM 相关信息。 JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。

  • Jconsole 是 JDK 自带的监控工具,在 JDK/bin 目录下可以找到。它用于连接正在运行的本地或者远程的 JVM,对运行在 java 应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。
  • jvisualvm 同样是 JDK 内置的工具,使用方法与 jconsole 类似。功能上要比 jconsole 强大一些。推荐使用。
代码语言:javascript复制
$ cd /usr/local/tomcat/bin/
#默认情况下,$CATALINA_HOME/bin 目录下是没有 setenv.sh,可以自己新建此文件
$ vim setenv.sh
CATALINA_OPTS="-Djava.rmi.server.hostname=10.100.4.169
-Dcom.sun.management.jmxremote.port=8686
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false"
:wq

#重新设置setenv.sh进行认证
CATALINA_OPTS="-Djava.rmi.server.hostname=10.10.107.222 -Dcom.sun.management.jmxremote.port=8686 -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.access='admin' -Dcom.sun.management.jmxremote.password='weiyigeek' -Dcom.sun.management.jmxremote.ssl=false"


JMX 配置说明:
-Dcom.sun.management.jmxremote
# 通过哪个 IP 访问本机的 JMX 
-Djava.rmi.server.hostname=10.100.4.169

# JMX 监听的端口,默认 8686
-Dcom.sun.management.jmxremote.port=8686

# 是否需要用户名密码认证,默认 false这里进行认证
-Dcom.sun.management.jmxremote.authenticate=true
#密码
-Dcom.sun.management.jmxremote.password.file=/opt/…/jmxremote.password
#登录用户
-Dcom.sun.management.jmxremote.access.file=/opt/…/jmxremote.access

# 是否启用 SSL
-Dcom.sun.management.jmxremote.ssl=false

#jmxremote.password模板:
[用户名] [密码]
mtct ct.meituan
test test

#jmxremote.access模板:
[用户名] [权限]
mtct readwrite
test readonly

注意事项:

  • jmxremote.password和jmxremote.access文件只允许启动用户名对该文件拥有读写权限,chmod 600 jmxremote.password & jmxremote.access
  • 文件路径${JAVA_HOME}/jre/lib/management/jmxremote.access

使用 jconsole 工具连接 JMX 配置 JMX 的时候没有启用 SSL 所以会提示不安全,点击『不安全的连接』

$jconsole

WeiyiGeek.

展现效果:

WeiyiGeek.

使用 jvisualvm 工具连接 JMX 描述:远程 –> 添加主机 –> 添加 JMX 连接

WeiyiGeek.

展示效果:

WeiyiGeek.

4.2 jmap工具

描述:jmap 可以输出 Java 进程 内存中对象的工具。 jmap 一般和 jhat 或者 MAT 配合使用,以图像的形式直观的展示当前内存是否有问题。

参数说明:

代码语言:javascript复制
-dump:[live,]format=b,file=<filename>
    以hprof二进制格式转储Java堆到指定filename的文件中。
    live子选项是可选的,如果指定了live子选项,堆中只有活动的对象会被转储。
    想要浏览heap dump,你可以使用 jhat(Java堆分析工具) 或者 MAT 读取生成的文件。
-finalizerinfo 打印等待终结的对象信息。
-heap 打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和generation wise heap usage。
-histo[:live] 打印每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。
    打印的虚拟机内部的类名称将会带有一个'*'前缀。
    如果指定了live子选项,则只计算活动的对象。
-permstat 打印Java堆内存的永久保存区域的类加载器的智能统计信息。
    对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。
    此外,包含的字符串数量和大小也会被打印。
-F 强制模式。如果指定的pid没有响应,请使用jmap -dump或jmap -histo选项。此模式下,不支持live子选项。
-h | -help 打印帮助信息。
-J<flag> 指定传递给运行jmap的JVM的参数。

示例1.jmap-histo 打印每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。

代码语言:javascript复制
$jmap -histo 14110
 num     #instances         #bytes  class name
----------------------------------------------
   1:         50994        7789848  [C
   2:         22160        6263680  [B
   3:          8527        1437176  [I
   4:         49099        1178376  java.lang.String
   5:            63         936248  [J
   6:         19118         611776  java.util.HashMap$Node
   7:          6243         549384  java.lang.reflect.Method
   8:          8948         509464  [Ljava.lang.Object;
   9:         10588         423520  java.util.TreeMap$Entry
  10:          3696         417952  java.lang.Class
  11:          1372         230544  [Ljava.util.HashMap$Node;
  12:          4760         228480  java.util.HashMap
  13:          4789         191560  java.util.HashMap$ValueIterator
  14:          5851         187232  java.io.File

#表示含义
B byte
C char
D double
F float
I int
J long
Z boolean
[ 数组,如[I表示int[]
[L 类名 其他对象

示例2.jmap-heap 查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况

代码语言:javascript复制
$jmap -heap 14110
Attaching to process ID 14110, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13

示例 3.jmap-dump:format=b,file= 用jmap把进程内存使用情况dump到文件中

代码语言:javascript复制
$ jmap -dump:format=b,file=/tmp/123.hprof 14110
Dumping heap to /tmp/123.hprof ...
Heap dump file created

4.3 jhat工具

描述:jhat 可以对 dump 出来的堆信息进行处理,以 html 页面的形式展示出来。 执行 jhat/tmp/123.hprof即可,默认端口是 7000,访问 http://localhost:7000 即可查看结果,通过 -port 指定端口。

WeiyiGeek.


5.高可用扩展

5.1 Tomcat运行模式

Tomcat的3种运行状态:

  1. bio:默认的模式,性能非常低下,没有经过任何优化处理和支持.
  2. nio:(new I/O)是Java SE 1.4及后续版本提供的一种新的I/O操作方式(即java.nio包及其子包);Java nio是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,因此nio也被看成是non-blocking I/O的缩写。它拥有比传统I/O操作(bio)更好的并发运行性能。
  3. apr:安装起来最困难,但是从操作系统级别来解决异步的IO问题,大幅度的提高性能.

(1)安装 apr 和 apr-util Apache Portable Runtime 是一个高度可移植的库,是 Apache HTTP Server 2.x 的核心。APR 有许多用途,包括访问高级 IO 功能(如sendfile,epoll 和 OpenSSL),操作系统级功能(随机数生成,系统状态等)和本机进程处理(共享内存,NT 管道和 Unix 套接字)。

代码语言:javascript复制
$ cd /usr/local/src/
$ wget http://mirrors.tuna.tsinghua.edu.cn/apache//apr/apr-1.6.5.tar.gz
$ wget http://mirrors.tuna.tsinghua.edu.cn/apache//apr/apr-util-1.6.1.tar.gz
$ tar xf apr-1.6.5.tar.gz
$ cd apr-1.6.5
$ /configure --prefix=/usr/local/apr
$ make -j 2 && make install 
$ cd ../
$ tar xf apr-util-1.6.1.tar.gz
$ cd apr-util-1.6.1
$ ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/

(2)安装 tomcat-native 描述:tomcat-native 不用单独下载,解压缩 tomcat 程序包后再 bin/ 目录下存在该程序的源码包。

代码语言:javascript复制
$ tar xf apache-tomcat-8.5.38.tar.gz -C /usr/local/
$ ln -sv /usr/local/apache-tomcat-8.5.38/ /usr/local/tomcat
$ cp /usr/local/tomcat/bin/tomcat-native.tar.gz /usr/local/src/
$ tar xf tomcat-native.tar.gz
$ cd tomcat-native-1.2.21-src/
$ cd native/
$ ./configure --prefix=/usr/local/apr --with-java-home=/usr/local/jdk1.8.0_121/
$ make -j 2 && make install
$ vim /etc/profile
export LD_LIBRARY_PATH=/usr/local/apr/lib ##添加apr path
$ source /etc/profile

(3) 修改 Tomcat 配置文件 修改 protocol 值 Tomcat 默认是 “HTTP/1.1” ,如果运行 apr 模式需要把 protocol 值修改成 apr 模式: org.apache.coyote.http11.Http11AprProtocol

代码语言:javascript复制
#1.修改为apr模式
$ cd /usr/local/tomcat/conf/
$ vim server.xml
<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
               connectionTimeout="20000"
               redirectPort="8443" />

#2.修改 SSLEngine

启动 Tomcat 验证查看 catalina.out 日志中最下面三行

补充说明:

  • APR 模式文档链接:http://tomcat.apache.org/tomcat-8.5-doc/apr.html

5.2 负载均衡配置

描述:LVS负载均衡是提高应用负载量和容错的有效手段,可以结合Nginx与Tomcat实现Nginx是一款性能优异的反向代理服务器。

(1)负载均衡配置实现 反向代理原理示意图

WeiyiGeek.反向代理原理示意图

负载均衡示意图:

WeiyiGeek.

负载均衡策略:

  • Nginx 提供轮询(round robin)
  • 用户IP哈希(client IP)
  • 指定权重 3 种方式weight

(2)负载均衡时Session的处理策略 描述:Session是Tomcat服务器上的内存空间,如果一个用户发出多个请求,却发到了多个tomcat服务器中,那么就会出现Session不同步的问题;

解决方案1

  • 将一个用户的请求锁定到某一台服务器上,简单,但是缺乏容错性,一旦某个服务器发生故障,Session可能丢失,(但是服务器发生故障是一个低概率事件,如果一个服务器经常挂掉,要么是硬件有问题,要么是应用有问题)可以使用用户IP哈希实现

解决方案2

  • Session复制策略,基于网络的广播策略,一个节点Session变化,其他节点同步复制,具有容错性,但节点多或复制量大时对网络负荷大,使网络效率低下,甚至阻塞
    • 在/conf/server.xml文件中开启Session复制的选项,将注释去掉,7.0默认值以配置好,需要接收器绑定内网(一般服务器都有两块网卡)网卡地址,修改端口>。
    • 在应用中指定应用是在分布式部署之下,在web.xml中添加选项

解决方案3

  • 额外创建一个共享的空间用来存放Session,所有服务器共享一个Session

(3)memcached缓存共享方案基本原理 粘性Session与非粘性Session方式:需要一些工具jar包,官网有目录和下载连接在/conf/context.xml中进行配置,全局有效。

WeiyiGeek.

注意事项:

  • 集群环境中应用代码应注意的问题传递Session需要实体类序列化支持,实现可序列化接口,设置版本号。
  • 获取用户IP地址方法的变化,获取真实客户端ip而不是Nginx代理地址。
  • 动静分离结构的预规划。一般高并发的网站上,资源类的文件,如js,css,图片通常是由静态服务器处理,Nginx处理静态文件效率就非常高,而tomcat处理静态文件是它很大的一个弱势,tomcat只负责动态请求的处理。
  • 编码的时候就要考虑静态资源最后可能要被拿出去,地址会有变化,所以在开发的时候应该规划访问地址,保持最大灵活性。

6.入坑出坑

问题1:压测时物理内存被用光 Tomcat 被 Kernel kill 掉

答:需要首先查看Tomcat日志和/var/log/message日志,需要注意交换分区空间是否分配以及分配大小; 解决办法: 给TOMCAT服务器启用虚拟空间,还可以降低 Apache 的最大连接数 MaxClients、最大内存 ServerLimit

问题2:报错INFO: Maximum number of threads (200) created for connector with address null and port 80

问题描述:INFO: Maximum number of threads (200) created for connector with address null and port 8080 问题说明:最大线程数设置错误,超出配置文件中MaxThreads访问请求; 解决方案:使用线程池用较少的线程处理较多的访问,可以提高tomcat处理请求的能力。

使用方法:

代码语言:javascript复制
#(1) 打开/conf/server.xml增加
#最大线程500(一般服务器足够),最小空闲线程数20,线程最大空闲时间60秒(这里根据需求更改)。接着修改<Connector>节点,增加executor属性。
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="500" minSpareThreads="20" maxIdleTime="60000" />
<Connector executor="tomcatThreadPool"
 port="80" protocol="HTTP/1.1"
 connectionTimeout="60000"
 keepAliveTimeout="15000"
 maxKeepAliveRequests="1"
 redirectPort="443" />

#(2) 当tomcat并发用户量大的时候,单个jvm进程确实可能打开过多的文件句柄(java.net.SocketException: Too many open files)。
ps -ef |grep tomcat    #查看tomcat的进程ID,记录ID号,假设进程ID为10001
lsof -p 10001 | wc -l  #查看文件操作数
ulimit -a              #查看每个用户允许打开的最大文件数默认是1024  
ulimit -n 65536        #将允许的最大文件数调整为65536 (重启后失效)

WeiyiGeek.

问题3:指定war包的docBase目录应用自动解压与部署设置

问题描述: 设置Context的Path路径以及docBase目录设置。

代码语言:javascript复制
<Service name="passport">
  <Connector port="8081" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" />
  <Engine name="passport" defaultHost="localhost">
    <Realm className="org.apache.catalina.realm.LockOutRealm">
      <!-- This Realm uses the UserDatabase configured in the global JNDI
            resources under the key "UserDatabase".  Any edits
            that are performed against this UserDatabase are immediately
            available for use by the Realm.  -->
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
              resourceName="UserDatabase"/>
    </Realm>
    <Host name="localhost"  appBase="passport" unpackWARs="true" autoDeploy="true">
      <Context path="" docBase="E:/Development/APP/"> </Context>
      <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>

0 人点赞