博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入剖析Tomcat性能优化与集群session共享
阅读量:3926 次
发布时间:2019-05-23

本文共 9530 字,大约阅读时间需要 31 分钟。

北京尚学堂旗下优效学院

《Tomcat性能优化与集群session共享》

公开课文档版本 视频版本wx:Nancy007001  备注:CSDN   免费获取

tomcat 运行模式优化

Tomcat Connector(Tomcat 连接器) 有 bio、nio、apr 三种运行模式

BIO模式

bio(blocking I/O),顾名思义,即阻塞式 I/O 操作,表示 Tomcat 使用的是传统的 Java I/O 操作 (即 java.io 包及其子包)。Tomcat 在默认情况下,就是以 bio 模式运行的。遗憾的是,就一般而言,bio 模式是三种运行模式中性能最低的一种。

配置Tomcat Manager

我们可以通过 Tomcat Manager 来查服务器的当前状态。

深入剖析Tomcat性能优化与集群session共享

 

访问入口在Tomcat默认首页或直接访问

在apache-tomcat-7.0.91conf目录下找到tomcat-users.xml

在<tomcat-users>节点中添加

<role rolename="manager-gui"/>

<user username="tomcat" password="tomcat" roles="manager-gui"/>

重启Tomcat 让配置文件生效

Tomcat服务器运行状态

观察server status 已经能看到Tomcat7.0.19默认已经是apr模式

深入剖析Tomcat性能优化与集群session共享

 

巴特,不要高兴的太早,默认的apr模式只在Windows版本的Tomcat中已经配置好了

那么在Linux系统中部署Tomcat后,会显示Bio模式

深入剖析Tomcat性能优化与集群session共享

 

NIO模式

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) 更好的并发运行性能。

要让 Tomcat 以 nio 模式来运行也比较简单,我们只需要在 Tomcat 安装目录 / conf/server.xml 文件中将如下配置:

<Connector port="8080" protocol="HTTP/1.1"

connectionTimeout="20000"

redirectPort="8443" />

其中的 protocol 属性值改为 org.apache.coyote.http11.Http11NioProtocol 即可:

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"

connectionTimeout="20000"

redirectPort="8443" />

深入剖析Tomcat性能优化与集群session共享

 

APR模式

apr(Apache Portable Runtime/Apache 可移植运行时),是 Apache HTTP 服务器的支持库。你可以简单地理解为,Tomcat 将以 JNI 的形式调用 Apache HTTP 服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高 Tomcat 对静态文件的处理性能。

Tomcat apr 也是在 Tomcat 上运行高并发应用的首选模式。如果我们的 Tomcat 不是在 apr 模式下运行,在启动 Tomcat 的时候,我们可以在日志信息中看到类似如下信息:

信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib

部署方式:

1. 安装依赖

yum install -y apr apr-util apr-devel

2.编译安装tomcat-native

· 进入 apache-tomcat-7.0.91/bin

深入剖析Tomcat性能优化与集群session共享

 

· 解压缩 tomcat-native.tar.gz

· 进入源码目录

深入剖析Tomcat性能优化与集群session共享

 

· 编译安装

深入剖析Tomcat性能优化与集群session共享

 

如果提示以下错误

configure: error: Found APR 1.3.9. You need version 1.4.3 or newer installed.

错误内容显示APR的版本过低,需要新版本

· 安装新版apr

下载

http://apr.apache.org/download.cgi#apr1

分别下载最新版的APR APR-util APR iconv

· 解压编译安装

./configure --prefix=/usr/local/apr

编译出错提示

configure: error: in `/usr/local/apache-tomcat-7.0.91/bin/apr-1.6.5':

configure: error: no acceptable C compiler found in $PATH

· 安装gcc

yum install gcc

· 再编译安装apr

./configure --prefix=/usr/local/apr

make

make install

· 编译安装APR iconv

./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr

make

make install

· make && make instal

重新编译

./configure --with-apr=/usr/local/apr/bin/apr-1-config --with-ssl=/usr/include/openssl/

报错

checking OpenSSL library version >= 1.0.2... configure: error: Your version of OpenSSL is not compatible with this version of tcnative

更新ssl

yum install openssl-devel

报错

Found OPENSSL_VERSION_NUMBER 0x1000105f (OpenSSL 1.0.1e 11 Feb 2013)

Require OPENSSL_VERSION_NUMBER 0x1000200f or greater (1.0.2)

configure: error: Your version of OpenSSL is not compatible with this version of tcnative

需要 1.2版的

下载 https://www.openssl.org/source/openssl-1.0.2h.tar.gz

解压 编译安装

./config shared zlib

提示需要perl

yum install perl

mv /usr/bin/openssl /usr/bin/openssl.bak

mv /usr/include/openssl /usr/include/openssl.bak

ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl

ln -s /usr/local/ssl/include/openssl /usr/include/openssl

echo “/usr/local/ssl/lib” >> /etc/ld.so.conf

ldconfig -v

查看是否升级成功

openssl version –a

重新编译

./configure --with-apr=/usr/local/apr/bin/apr-1-config --with-ssl=/usr/include/openssl/

修改

· Server.xml

<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"

connectionTimeout="20000"

redirectPort="8443" />

· catalina.sh

100行左右 更新内容

JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+DisableExplicitGC"

cygwin=false

darwin=false

CATALINA_OPTS="-Djava.library.path=/usr/local/apr/lib"

os400=false

重新启动服务器观察

深入剖析Tomcat性能优化与集群session共享

 

Apr模式配置心酸成功!

内存优化

在上面我们已经添加过一个参数JAVA_OPTS

针对这个参数可以对Tomcat的内存进行优化

修改 /bin/catalina.sh,在其中加入,可以放在 CLASSPATH = 下面:

JAVA_OPTS="-server -XX:PermSize=512M -XX:MaxPermSize=1024m -Xms2048m -Xmx2048m"

参数说明

-server:启用 JDK的 server 版本;

-Xms:Java虚拟机初始化时堆的最小内存,一般与 Xmx配置为相同值,这样的好处是GC不必再为扩展内存空间而消耗性能;

-Xmx:Java虚拟机可使用堆的最大内存;

-XX:PermSize:Java虚拟机永久代大小;

-XX:MaxPermSize:Java虚拟机永久代大小最大值;

这些参数外还可以根据具体需要配置其他参数,参数的配置可以参考 JVM 参数的配置

为jd1.7的参数

从JDK8开始,永久代(PermGen)的概念被废弃掉了,取而代之的是一个称为Metaspace的存储空间。

Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace的大小只与本地内存大小有关。

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=512m; suppor t was removed in 8.0

jdk8 使用

MetaspaceSize=2048m

MaxMetaspaceSize=2048m

Connector 优化

Connector 是连接器,负责接收客户的请求,以及向客户端回送响应的消息。

所以 Connector 的优化是重要部分。

默认情况下 Tomcat 只支持 200 线程访问,超过这个数量的连接将被等待甚至超时放弃,所以我们需要提高这方面的处理能力。

/conf/server.xml,打开 server.xml 找到 Connector 标签项,默认配置如下:

<Connector port="8080" protocol="HTTP/1.1"

connectionTimeout="20000"

redirectPort="8443" />

· port 代表服务接口;

· protocol 代表协议类型;

· connectionTimeout 代表连接超时时间,单位为毫秒;

· redirectPort 代表安全通信(https)转发端口,一般配置成 443。

常见优化选项

<Connector port="8080"

protocol="HTTP/1.1"

maxThreads="1000"

minSpareThreads="100"

acceptCount="1000"

maxConnections="1000"

connectionTimeout="20000"

maxHttpHeaderSize="8192"

tcpNoDelay="true"

redirectPort="8443"

enableLookups="false"

URIEncoding="UTF-8" />

· maxThreads : 连接器创建处理请求线程的最大数目,处理同事请求的最大数目,默认值为200。

如果一个执行器与此连接器关联,则忽略此属性,因为该属性将被忽略,所以该连接器将使用执行器而不是一个内部线程池来执行任务。

maxThreads是一个重要的配置属性,maxThreads配置的合理直接影响了Tomcat的相关性能。

maxThreads并不是配置的越大越好,事实上你即使配置成999999也是没有用的,因为这个最大值是受操作系统及相关硬件所制约的,并且最大值并不一定是最优值,所以我们追寻的应该是最优值而不是最大值。

QPS(Query Per Second):每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。我们常常使用 QPS值来衡量一个服务器的性能。

QPS = 并发数 / 平均响应时间

并发数 = QPS * 平均响应时间

一个系统吞吐量通常由QPS、并发数两个因素决定,每套系统的这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降,原因是系统超负荷工作,上下文切换、内存等等其它消耗导致系统性能下降。所谓吞吐量这里可以理解为每秒能处理请求的次数。

所以选择一个合理的 maxThreads值,其实并不是那么容易的事。

因为过多的线程只会造成,更多的内存开销,更多的CPU开销,但是对提升QPS确毫无帮助;找到最佳线程数后通过简单的设置,可以让web系统更加稳定,得到最高,最稳定的QPS输出。

# 获取最佳maxThreads的最佳值

(1)通过线上系统不断使用和用户的不断增长来进行性能测试,观察QPS,响应时间,这种方式会在爆发式增长时系统崩溃,如双11

(2)根据公式计算,服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量,这种方式有时会被误导,因为某些系统处理环节可能会耗时比较长,从而影响公式的结果。

(3)单、多用户压力测试,查看CPU的消耗,然后直接乘以百分比,再进行压测,一般这个值的附近应该就是最佳线程数量,这种方式理想场景比较适用,实际情况会比这个复杂的多。

(4)根据系统的自身情况调整,如硬件限制,系统限制,程序处理能力限制等。

(5)定期修改为不同的 maxThreads值,看服务器响应结果及用户反应。

# QPS和线程数的关系

(1)在最佳线程数量之前,QPS和线程是互相递增的关系,线程数量到了最佳线程之后,QPS持平,不在上升,甚至略有下降,同时相应时间持续上升。

(2)同一个系统而言,支持的线程数越多(最佳线程数越多而不是配置的线程数越多),QPS越高。

# QPS和响应时间的关系

(1)对于一般的web系统,响应时间一般有CPU执行时间+IO等待时间组成。

(2)CPU的执行时间减少,对QPS有实质的提升,IO时间的减少,对QPS提升不明显。如果要想明显提升QPS,优化系统的时候要着重优化CPU消耗大户。

· minSpareThreads:线程的最小运行数目,这些始终保持运行。如果未指定,默认值为10。

当所有可能的请求处理线程都在使用时传入连接请求的最大队列长度。如果未指定,默认值为100。一般是设置的跟 maxThreads一样或一半,此值设置的过大会导致排队的请求超时而未被处理。所以这个值应该是主要根据应用的访问峰值与平均值来权衡配置。

· maxSpareThreads:最大备用线程数,一旦创建的线程超过这个值,Tomcat 就会关闭不再需要的 socket 线程。

· acceptCount:最大队列长度。一般与maxThreads相同,默认为100。

· maxConnections:在任何给定的时间内,服务器将接受和处理的最大连接数。

当这个数字已经达到时,服务器将接受但不处理,等待进一步连接。NIO与NIO2的默认值为10000,APR默认值为8192。

· connectionTimeout:当请求已经被接受,但未被处理,也就是等待中的超时时间。单位为毫秒,默认值为60000。通常情况下设置为30000。

· maxHttpHeaderSize:请求和响应的HTTP头的最大大小,以字节为单位指定。如果没有指定,这个属性被设置为8192(8 KB)。

· tcpNoDelay:如果为true,服务器socket会设置TCP_NO_DELAY选项,在大多数情况下可以提高性能。缺省情况下设为true。

· compression:是否启用gzip压缩,默认为关闭状态。这个参数的可接受值为“off”(不使用压缩),“on”(压缩文本数据),“force”(在所有的情况下强制压缩)。

· compressionMinSize:如果compression="on",则启用此项。被压缩前数据的最小值,也就是超过这个值后才被压缩。如果没有指定,这个属性默认为“2048”(2K),单位为byte。

· disableUploadTimeout:这个标志允许servlet Container在一个servlet执行的时候,使用一个不同的,更长的连接超时。最终的结果是给servlet更长的时间以便完成其执行,或者在数据上传的时候更长的超时时间。如果没有指定,设为false。

· enableLookups:关闭DNS反向查询。

· URIEncoding:编码

线程池

Executor 代表了一个线程池,可以在 Tomcat 组件之间共享。使用线程池的好处在于减少了创建销毁线程的相关消耗,而且可以提高线程的使用效率。

要想使用线程池,首先需要在 Service 标签中配置 Executor,如下:

<Service name="Catalina">

<Executor name="tomcatThreadPool"

namePrefix="catalina-exec-"

maxThreads="1000"

minSpareThreads="100"

maxIdleTime="60000"

maxQueueSize="Integer.MAX_VALUE"

prestartminSpareThreads="false"

threadPriority="5"

className="org.apache.catalina.core.StandardThreadExecutor"/>

参数选项

· name:线程池名称,用于 Connector中指定。

· namePrefix:所创建的每个线程的名称前缀,一个单独的线程名称为 namePrefix+threadNumber。

· maxThreads:池中最大线程数。

· minSpareThreads:活跃线程数,也就是核心池线程数,这些线程不会被销毁,会一直存在。

· maxIdleTime:线程空闲时间,超过该时间后,空闲线程会被销毁,默认值为6000(1分钟),单位毫秒。

· maxQueueSize:在被执行前最大线程排队数目,默认为Int的最大值,也就是广义的无限。除非特殊情况,这个值不需要更改,否则会有请求不会被处理的情况发生。

· prestartminSpareThreads:启动线程池时是否启动 minSpareThreads部分线程。默认值为false,即不启动。

· threadPriority:线程池中线程优先级,默认值为5,值从1到10。

· className:线程池实现类,未指定情况下,默认实现类为org.apache.catalina.core.StandardThreadExecutor。如果想使用自定义线程池首先需要实现 org.apache.catalina.Executor接口。

线程池配置完成后需要在 Connector 中指定:

<Connector executor="tomcatThreadPool"

...

负载均衡 Session共享

Memcached

1、 安装依赖

yum install gcc openssl-devel pcre-devel zlib-devel libevent

2、安装memcached

可以用yum方式安装

yum –y install memcached

3、启动memcached

memcached -d -m 128 -u root -l 192.168.43.151 -p 11211 -c 256 -P /tmp/memcached.pid

memcached-tool 192.168.2.51:11211

参数解释:

-d:后台启动服务

-m:缓存大小

-p:端口

-l:IP

-P:服务器启动后的系统进程ID,存储的文件

-u:服务器启动是以哪个用户名作为管理用户

Nginx配置

负载均衡

upstream tomcat{

server 192.168.2.52:8080;

server 192.168.2.53:8080;

}

location /tomcat {

proxy_pass http://tomcat/;

}

Tomcat配置

拷贝jar

到tomcat的lib下,jar包见附件

配置tomcat

每个tomcat里面的context.xml中加入

<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"

memcachedNodes="n1:192.168.43.151:11211"

sticky="false"

lockingMode="auto"

sessionBackupAsync="false"

requestUriIgnorePattern=".*.(ico|png|gif|jpg|css|js)$"

sessionBackupTimeout="1000" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"

/>


大家可以持续关注小编,我将尽其所能的为大家提供技术性实践资料、文章、视频。

感谢大家的支持!公开课文档版本 视频版本wx:Nancy007001  备注:CSDN   免费获取

本文为原创作品,转载请注明出处!

你可能感兴趣的文章
strftime函数
查看>>
linux下的时间函数使用
查看>>
C语言问题集-- 把 struct tm 或一个字符串转换成 time_t
查看>>
hp unix下strptime的使用
查看>>
C语言中如何求任意一个int型数组的长度?
查看>>
蓝牙基带数据传输机理分析
查看>>
各种文件后缀名与打开方式大全
查看>>
利用Java的Properties 类读取配置文件信息
查看>>
用java读写ini配置文件
查看>>
java读取和修改ini配置文件实例代码
查看>>
网络字节序与主机字节序
查看>>
inet_aton和inet_network和inet_addr三者比较-《别怕Linux编程》之五
查看>>
组播通信
查看>>
setsockopt 设置socket 详细用法
查看>>
在局域网中实现多播功能
查看>>
什么叫组播地址(Multicast Address )?
查看>>
掌握IP地址知识 子网掩码与子网划分
查看>>
组播地址,IP组播地址
查看>>
什么是组播
查看>>
组播通信
查看>>