Tomcat解析、优化

一、Tomcat解析、优化

  一、Java的组成部分

  1、简述Java组成部分

  • bin:tomcat的脚本文件,catalina.sh
  • conf:tomcat的配置文件
  • lib:存放的是tomcat自带的jar(java程序,class文件) jar存放的地方(jdk安装目录下lib、jre\lib、tomcat安装目录下lib、开发人员编写的应用程序下lib) 注意:jar版本冲突
  • logs:存放tomcat日志,catalina.out日志(日志级别)
  • tmp:tomcat临时目录
  • webapps:存放tomcat自带的应用
  • work:存放了tomcat运行时,web应用jsp页面转变为,java程序,和class的目录

   2、配置文件

  • server.xml:tomcat核心配置文件;定义tomcat提供服务的很多组件、这些组件属性的设定
  • context.xml:每个webapp都有自己本身的配置,WBE-INF目录,
  • web.xml:每个web应用被tomcat加载(jvm加载)时的参数配置
  • tomcat-users.xml:用户认证账号配置文件
  • logging.properties:日志相关的配置文件
  • catalina.properties:java属性的配置文件,用于定于用于设定类加载器路径,以及一些jvm性能调整的相关参数
  • catalina.policy:安全运行策略
    1、server.xml组件:由Java类实现

  顶级组件:Server(tomcat实例,,关闭tomcat,提供tomcat管理端。。。。。)

port:监听tomcat管理端口
shutdown:传递什么信号可以关闭tomcat实例

  服务类组件:service 将连接器和引擎关联起来

tomcat运行在java,系统级服务

  容器类组件:Engine(web server),Host,Context

  连接器组件(Connector):使用java虚拟机向linux内核发起端口注册(绑定)请求,监听端口,接收用户请求

connectionTimeout:连接超时时长,单位是毫秒
keepAliveTimeout:长连接保持时长,15秒  单位是毫秒
maxSpareThreads:最大空闲线程
minSpareThreads:最小空闲线程
maxConnections:tomcat最多能并发处理的请求
acceptCount:每个tomcat线程,接收请求队列的长度,2
MaxThreads:tomcat启动最大线程数

  被嵌套类组件:valve(过滤器),realm(安全域)

*/
<Server> 代表一个tomcat实例(tomcat进程)
<Service>:  
<Connector>:代表和客户程序实际交互的组件,负责接收客户请求,以及向客户返回相应结果
<engine:处理在同一个<Service>中所有Connector组件接收的客户请求
<Host>:虚拟主机
<Context>:web应用
/*


<Server>
<Service>
    <engine>
    </engine>
    <Connector>
    </Connector>
</Service>
</Server>

  二、部署环境

  下载所需的JDK和Jmeter

  1、Linux上安装JDK8和jmeter5.0

cd /opt/soft
#上传所需安装包 apache-jmeter-5.0.zip  jdk-8u192-linux-x64.tar
tar -xf jdk-8u192-linux-x64.tar
ln -s jdk1.8.0_192/ /opt/soft/java
unzip apache-jmeter-5.0.zip

#创建环境变量
#编辑/etc/profile
export JAVA_HOME=/usr/java/jdk1.8.0_192
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib
#jmeter
export JMETER=/opt/ytd_soft/apache-jmeter-5.0
export CLASSPATH=$JMETER/lib/ext/ApacheJMeter_core.jar:$JMETER/lib/jorphan.jar:$CLASSPATH
export PATH=$JMETER/bin/:$PATH

#生效配置文件
source /etc/profile

#验证
java -version
jmeter  --version

  2、安装Linux图形化包

  Linux环境若没有安装图形化包会报下面的错误

# jmeter
================================================================================
Don't use GUI mode for load testing !, only for Test creation and Test debugging.
For load testing, use NON GUI Mode:
   jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
& increase Java Heap to meet your test requirements:
   Modify current env variable HEAP="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m" in the jmeter batch file
Check : https://jmeter.apache.org/usermanual/best-practices.html
================================================================================
An error occurred: 
No X11 DISPLAY variable was set, but this program performed an operation which requires it.

  安装所需的包(yum intall xorg-x11-xauth)

yum install xorg-xll-xauth xorg-x11-server-utils xorg-x11-server-Xnest libXtst -y

  验证(若还报错,可以重启一下机器,在进行测试)

# jmeter

   3、jmeter介绍

    1、bin底下脚本介绍
/data/apache-jmeter-3.1/bin目录下的脚本:jmeter脚本文件,应该在绝大多数linux/UNIX系统上运行

jmeter:运行JMeter(默认GUI模式)。定义了一些JVM设置,但并不是对所有JVM都生效

jmeter-server:以服务器模式启动JMeter(通过合适的参数来调用jmeter脚本)。
jmeter.sh:没有指定JVM选项的非常基础的jmeter脚本

mirror-server.sh:在非GUI模式下启动JMeter镜像服务器
shutdown.sh:关闭一个非GUI实例(优雅的)
stoptest.sh:停止一个非GUI实例(中断式的)

使用一个产品的原则:使用路径(用户使用路径)
功能繁多,会导致使用路径非常多,很多刚接触的用户经常会迷路
先研究和掌握最核心的一条用户路径
JMeter(怎么对一个web服务进行压力测试)
    2、JMeter常用术语
1、采样器(Samplers):采样器是JMeter测试脚本的基础单元用户可以用它来向服务器发出一个特定的请求,采样器会在超时前等待服务器的响应。

2、逻辑控制器(Logic Controllers):用户通过逻辑控制器来控制JMeter测试脚本的执行顺序,以便测试能够按照用户期望的顺序和逻辑执行

3、监听器(Listeners):监听器被用来收集测试结果信息,并以用户指定的方式加以展示

4、配置元件(Configuration Elements):配置元件被用来设置一些JMeter测试脚本公用的信息

5、断言(Assertions):断言被用来验证服务器实际返回的信息与用于期望的情况是否相符

6、定时器(Timers):定时器被用来保存JMeter测试脚本与时间相关的一些信息,例如思考时间(Think Time)

7、前置处理器(Pre-Processos):在前置处理器的作用范围内,任何采样被执行前,都要先执行前置处理器

8、后置处理器(Post-Processors):在后置处理器的作用范围内,任何采样器被执行后,都要执行对应的后置处理器

9、测试计划(Test Plan):测试计划是JMeter测试脚本的根节点,关于整个测试脚本的一些基础设置,可以在测试计划中设定,例如用户定义变量

10、线程组(Thread Group):线程组定义了一个虚拟用户池,其中每一个虚拟用户都使用同样的测试脚本

11、工作台(WorkBench):工作台被用来保存暂时不使用的测试元素,当测试人员保存测试计划时,工作台中的内容不会被一起保存
    3、JMeter测试结果字段的意义
Label:定义HTTP请求名称
Samples:表示这次测试中一共发出了多少个请求
Average:平均响应时长---默认情况下是单个Request的平均响应时长,当使用Transaction Controller时,也可以以Transaction为单位显示平均响应时长
Median:中位数,也就是50%用户的响应时长
90%Line:90%用户的响应时长
Min:访问页面的最小响应时长
Max:访问页面的最大响应时长
Error%:错误请求的数量/请求的总数
Throughput:默认情况下表示每秒完成的请求数(Request per Second),当使用了Transaction Controller时,也可以表示类似LoadRunner的Transaction per Second数。
KB/Sec:每秒从服务器端接收到的数据量
    4、建立测试计划
    线程组:

        HTTP采样器的配置元件:

        采样器:/index.html 
                /index.php

        监听器

  三、Tomcat优化

  1、server.xml主要优化参数

  基准、压力测试和性能测试

jmeter(性能测试)、ab(基准测试,压力测试)

ab:httpd服务自带的一个工具(apache)
yum install httpd-tools


ab参数:
-c:模拟用户数(启动多个进程或者是线程发起请求)
-n:总共要发起的并发请求数
-k:禁止Keep-Alive

ab -k -c 1 -n 2 http://www.baidu.com/index.html

打印日志,并分析
for i in {1..10000}; do netstat -n|awk '/^tcp/ {++S[$NF]} END{for(a in S) print a,S[a]}' >>/tmp/tcp.log; free -m >>mem.log; vmstat >>cpu.log; sleep 1; done

  mssssaxThreads尽量设置的小一点,当tomcat的线程数过大时,cpu资源都会浪费在tomcat线程调度上。线程调度消耗的cpu资源其实就是浪费的cpu资源,当cpu核心数<线程数,其实就会产生线程调度,(合理控制)

maxThreads:tomcat能够启动的最大线程数  100  处理用户请求的线程 
minSpaceThreads:tomcat初始化的线程池大小。
acceptCount:tomcat每个线程维护的最大队列长度
maxConnections:tomcat能够允许多少个客户tcp链接

  2、数据库连接池配置

    1、主要优化参数
#初始化连接:连接池启动时创建的初始化连接数量
initialSize=10
#连接池的最大数据库连接数。设为0表示无限制
maxActive=50
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被释放。设为0表示无限制
maxIdle=10
#最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接
minIdle=5
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制
maxWait=1000
#超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收(默认为false,调整为true) 
removeAbandoned=true
#超过时间限制,回收没有用(废弃)的连接(默认为 300秒,调整为180)
removeAbandonedTimeout=180
  2、配置方法

  方法一:在Tomcat的conf/context.xml中配置

 <!--配置mysql数据库的连接池, 
        需要做的额外步骤是将mysql的Java驱动类放到tomcat的lib目录下        
        maxIdle 连接池中最多可空闲maxIdle个连接 
        minIdle 连接池中最少空闲maxIdle个连接 
        initialSize 初始化连接数目 
        maxWait 连接池中连接用完时,新的请求等待时间,毫秒 
        username 数据库用户名
        password 数据库密码
        -->
    <Resource name="jdbc/mysqlds" 
        auth="Container" 
        type="javax.sql.DataSource" 
        username="root" 
        password="root" 
        maxIdle="30" 
        maxWait="10000" 
        maxActive="100"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://127.0.0.1:3306/db_blog" />

</Context>

配置好后需要注意的两个步骤

1.将对应数据库的驱动类放到tomcat的lib目录下

2.重新启动tomcat服务器,让配置生效

  方法二:在Tomcat的conf/server.xml中配置

打开tomcat的conf/server.xml文件,找到<GlobalNamingResources></GlobalNamingResources>节点,默认的内容如下

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

在该节点中加入相关的池配置信息,如下

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

             <!--配置mysql数据库的连接池, 
                需要做的额外步骤是将mysql的Java驱动类放到tomcat的lib目录下        
               -->
             <Resource name="jdbc/mysqlds" 
              auth="Container" 
              type="javax.sql.DataSource" 
              username="root" 
              password="root" 
              maxIdle="30" 
              maxWait="10000" 
              maxActive="100"
              driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://127.0.0.1:3306/db_blog" />
  </GlobalNamingResources>

在tomcat的conf/context.xml文件中的<Context></Context>节点中加入如下内容

<ResourceLink name="jdbc/mysqlds" global="jdbc/mysqlds" type="javax.sql.DataSource"/>

然后在web项目中的WEB-INF目录下的web.xml中配置

 <resource-ref>

      <description>mysql Connection</description>
      <!-- 参考数据源名字,同Tomcat中配置的Resource节点中name属性值"jdbc/mysqlds"一致 -->
      <res-ref-name>jdbc/mysqlds</res-ref-name>
      <!-- 资源类型 -->
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
      <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

同样配置好后,需要重新启动服务器,让配置生效.

  方法三:web应用中中配置方法一

在Web项目中的META-INF目录下新建一个文件context.xml,写入配置

注意:是META-INF目录下,不是WEB-INF目录下

<?xml version='1.0' encoding='utf-8'?>

<Context>
    <Resource name="jdbc/mysqlds" 
        auth="Container" 
        type="javax.sql.DataSource" 
        username="root" 
        password="root" 
        maxIdle="30" 
        maxWait="10000" 
        maxActive="100"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://127.0.0.1:3306/db_blog"
        logAbandoned="true" />
</Context>
    3、mysql  jdbc  url参数详解:
user    数据库用户名,用于连接数据库      所有版本
password    用户密码(用于连接数据库)       所有版本
useUnicode  是否使用Unicode字符集,如果参数characterEncoding设置为gb2312或gbk,本参数值必须设置为true     false
characterEncoding   当useUnicode设置为true时,指定字符编码。比如可设置为gb2312或gbk,utf8    false
autoReconnect   当数据库连接异常中断时,是否自动重新连接?   false
autoReconnectForPools   是否使用针对数据库连接池的重连策略   false
failOverReadOnly    自动重连成功后,连接是否设置为只读?  true
maxReconnectsautoReconnect  设置为true时,重试连接的次数    3 
initialTimeoutautoReconnect设置为true时,两次重连之间的时间间隔,单位:秒 
connectTimeout  和数据库服务器建立socket连接时的超时,单位:毫秒。 0表示永不超时,适用于JDK 1.4及更高版本 
socketTimeoutsocket操作(读写)超时,单位:毫秒。 0表示永不超时

  范例

jdbc:mysql://localhost:3306/test?user=root&password=&useUnicode=true&characterEncoding=gbk&autoReconnect=true&failOverReadOnly=false

  3、JVM优化

-Xms:设置初始化堆大小
-Xmx:设置堆最大可使用空间
-Xss128k:虚拟机栈和本地方法栈溢出 
-XX:PermSize=10M -XX:MaxPermSize=10M :运行时常量池的内存溢出 

  范例如下

export GC_LOG_DIR=/opt/logs/gc   # 此处修改为规定的路径
export HEAPDUMP_DIR=/opt/logs/gc   # 此处修改为规定的路径
mkdir -p ${GC_LOG_DIR}
mkdir -p ${HEAPDUMP_DIR}
 
jdk_verbose_version=`java -version 2>&1 | grep version | awk -F"\"" '{print $2}'`
echo "JDK version: ${jdk_verbose_version}"
 
jdk_major_version=`java -version 2>&1 | grep version | awk -F"." '{print $2}'`
if [ ${jdk_major_version} -gt 7 ]
then
    # jdk7 之后的版本
    JAVA_OPTS="${JAVA_OPTS} -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=384m"
else
    # jdk7 以及之前的版本
    JAVA_OPTS="${JAVA_OPTS} -XX:PermSize=256M -XX:MaxPermSize=384M"
    JAVA_OPTS="${JAVA_OPTS} -XX:+UseConcMarkSweepGC -XX:CMSMaxAbortablePrecleanTime=5000"
fi
 
JAVA_OPTS="${JAVA_OPTS} -Xms2g -Xmx4g"
JAVA_OPTS="${JAVA_OPTS} -Xloggc:${GC_LOG_DIR}/gc.log_$(date +%F) -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
JAVA_OPTS="${JAVA_OPTS} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${HEAPDUMP_DIR}/heapdump_$(date +%m-%d_%H:%M:%S).hprof"
JAVA_OPTS="${JAVA_OPTS} -Dfile.encoding=UTF-8"
 
export JAVA_OPTS

 

posted @ 2018-11-18 15:53  思维无界限  阅读(77)  评论(0编辑  收藏  举报