1、响应时间
响应时间指的是从客户端发起一个请求开始,到客户端接收到从服务器端返回的响应结束,这个过程所耗费的时间。响应时间通常用时间单位来衡量(一般为秒)。
图形中的拐点,表示响应时间突然增加,意味着一种或者多种系统资源的利用达到了极限
响应时间 = N1+A1+N2+A2+N3+A3+N4
网络传输时间:N1 + N2 + N3 + N4
应用服务器处理时间:A1 + A3
数据库服务器处理时间:A2
2、并发用户数
系统用户数:系统额定的用户数量,如一个OA系统,可能使用该系统的用户总数是2000个,那么这个数量,就是系统用户数
同时在线用户数:在一定的时间范围内,最大的同时在线用户数量
平均并发用户数的计算:
C=nL /T
其中C是平均的并发用户数,n是平均每天访问用户数,L是一天内用户从登录到退出的平均时间(操作平均时间),T是考察时间长度(一天内多长时间有用户使用系统)
3、吞吐量
吞吐量指的是单位时间内处理的客户端请求数量。
从业务角度看,吞吐量可以用:请求数/秒、页面数/秒、人数/天或处理业务数/小时等单位来衡量
从网络角度看,吞吐量可以用:字节/秒来衡量
对于交互式应用来说,吞吐量指标反映的是服务器承受的压力,他能够说明系统的负载能力
以不同方式表达的吞吐量可以说明不同层次的问题,例如,以字节数/秒方式可以表示数要受网络基础设施、服务器架构、应用服务器制约等方面的瓶颈;已请求数/秒的方式表示主要是受应用服务器和应用代码的制约体现出的瓶颈。
当没有遇到性能瓶颈的时候,吞吐量与虚拟用户数之间存在一定的联系,可以采用以下公式计算:F=VU * R / T
其中F为吞吐量,VU表示虚拟用户个数,R表示每个虚拟用户发出的请求数,T表示性能测试所用的时间
4、资源利用率
资源利用率指的是对不同系统资源的使用程度,例如服务器的CPU(s),内存,网络带宽等。
资源利用率通常以占用最大值的百分比n %来衡量。
当某个资源利用率随着负载的增加最终在100%居高不下时,就可能意味着这个资源变成了系统的性能瓶颈所在,提高这个资源的量,将会提高系统的吞吐量,同时降低交易的响应时间,即改进了系统的性能。
1. 优化思路
(1)、升级服务器的硬件,换成更快、更大的机器。
(2)、增加服务器的数量。
(3)、对系统和应用程序进行仔细的调优,以提高响应时间、吞吐量和资源利用率的性能指标。
2. 优化方法
(1)、每次改变一个系统参数或者一个应用逻辑。
(2)、使用固定的负载(比如保持相同的并发用户数)。
(3)、测试另一个设置之前收集本次性能测试的数据。
(4)、重复测试过程,直到应用程序的性能达到了期望的状态。
3. 优化对象
(1)、服务器硬件(CPU、内存、磁盘IO)
(2)、网络(网速、网卡)
(3)、操作系统
(4)、J2EE容器(比如WebLogic)
(5)、应用程序(包括前台和后台)
(6)、数据库
(7)、JVM
4. 优化步骤
(1)、获取系统性能测试的性能参数数据,根据系统现有的性能情况做分析。
(2)、先排除外部因素,然后再对应用程序的性能进行调优。
(3)、对系统的各个环节进行针对性监控,包括操作系统资源、处理线程堆栈、数据库连接池、数据库和JVM等。
(4)、结合监控的结果和性能测试的数据起来做分析,优先处理通道问题(比如连接池连接不够、操作系统最大Socket数不够、内存设置太小等等),然后再到应用程序内部,看看是否出现线程等待是否严重,或者JVM中哪些对象或者方法使用过多、数据库那条SQL语句执行时间太长了、或者哪条SQL语句使用太频繁了、哪个JSP或者Servlet处理的时间太长了等等。
(5)、如果发现了性能瓶颈的原因,则每次只修改一个地方,并且做性能测试,对两次的性能测试参数进行对比。
(6)、如果没有找到原因,那么我们只能做试探性的修改,并且在改后重新做性能测试,并进行对比。
调优思路
1、 操作系统最大Socket数设置
2、操作系统Socket关闭等待时间设置
调优思路:
1、网络带宽(路由器是采用百兆还是千兆速率)
2、是否采用磁盘阵列(特别是数据库很容易出现瓶颈)
3、机器的网卡是采用百兆网卡还是千兆网卡
4、应用服务器的发送和接收是否采用两个独立的网卡
5、JVM的内存大小是否设置准确
6、监控应用服务器和数据库服务器的CPU利用率、内存利用率和IO读写情况,找出瓶颈
7、监控应用服务器到数据库服务器之间的网络流速,看是否网速太小
Tomcat性能调优1. 调整虚拟内存
Linux:
在/usr/local/tomcat_home/bin目录下的catalina.sh
添加:JAVA_OPTS='-Xms1024m -Xmx2048m'
要加“m”说明是MB,否则就是KB了,在启动tomcat时会报内存不足。
-Xms:初始值
-Xmx:最大值
-Xmn:最小值
Windows:
在catalina.bat最前面加入
set JAVA_OPTS=-Xms1024m -Xmx2048m
如果用startup.bat启动tomcat,OK设置生效.够成功的分配200M内存.
但是如果不是执行startup.bat启动tomcat而是利用windows的系统服务启动tomcat服务,上面的设置就不生效了,就是说set JAVA_OPTS=-Xms1024m -Xmx2048m没起作用.
windows服务执行的是bin\tomcat.exe.他读取注册表中的值,而不是catalina.bat的设置.
解决办法:
修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Tomcat Service Manager\Tomcat5\Parameters\JavaOptions
原值为
-Dcatalina.home="C:\ApacheGroup\Tomcat 5.0"
-Djava.endorsed.dirs="C:\ApacheGroup\Tomcat 5.0\common\endorsed"
-Xrs
加入 -Xms1024m -Xmx2048m
重起tomcat服务,设置生效
2. HTTP通道调优
将tomcat_home/conf/server.xml中的HTTP通道默认配置屏蔽,添加下面这段配置:
- <Connector port="8080" redirectPort="8443"
- maxHttpHeaderSize="8192" useBodyEncodingForURI="true"
- minProcessors="100" maxProcessors="5000"
- maxThreads="5000" minSpareThreads="1000" maxSpareThreads="4000"
- enableLookups="false" acceptCount="3500"
- compression="on" compressionMinSize="2048"
- compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
- connectionTimeout="60000" disableUploadTimeout="true" debug="0" URIEncoding="UTF-8"/>
当web应用程序向要记录客户端的信息时,它也会记录客户端的IP地址或者通过域名服务器查找机器名转换为IP地址。DNS查询需要占用网络,并且包括可能从很多很远的服务器或者不起作用的服务器上去获取对应的IP的过程,这样会消耗一定的时间。为了消除DNS查询对性能的影响我们可以关闭 DNS查询,方式是修改server.xml文件中的enableLookups参数值:
- <Connector port="80" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false"
- redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true"/>
1. 调优思路:
(1). 数据库连接最大数设置
(2). 回滚段大小设置
(3). 共享SGA大小设置
(4). 数据切分(水平分库、垂直分库、分区表)
(5). 找出执行时间长的SQL语句并优化SQL的执行计划
(6). 查看数据库是否有死锁
(7). 数据库集群
2. 优化措施
(1). 查看和设置数据库最大连接数
当数据库最大连接数不够时,会出现客户端连接间歇性失败,报ORA-12519错,我们可以通过以下的SQL语句来查看当前连接数和数据库允许的最大连接数,对比一下,看是否达到了最大值。
- --查看当前连接数
- select count(*) from v$process;
- --查看数据库允许的最大连接数
- select value from v$parameter where name = 'processes';
a. 使用sqlplus登陆数据库
sqlplus "sys/oracle as sysdba";
b. 设置数据库允许的最大连接数
alter system set processes = 300 scope = spfile;
c. 重启数据库
shutdown immediate;
startup;
d. 查看数据库允许的最大连接数
select value from v$parameter where name = 'processes';
(3). 查看数据库是否有被锁的表
- SELECT A.OWNER 方案名,
- A.OBJECT_NAME 表名,
- B.XIDUSN 回滚段号,
- B.XIDSLOT 槽号,
- B.XIDSQN 序列号,
- B.SESSION_ID 锁表SESSION_ID,
- B.ORACLE_USERNAME 锁表用户名,
- decode(D.type,
- 'XR',
- 'NULL',
- 'RS',
- 'SS(Row-S)',
- 'CF',
- 'SS(Row-S)',
- 'TM',
- 'TABLE LOCK',
- 'PW',
- 'TABLE LOCK',
- 'TO',
- 'TABLE LOCK',
- 'TS',
- 'TABLE LOCK',
- 'RT',
- 'ROW LOCK',
- 'TX',
- 'ROW LOCK',
- 'MR',
- 'S(Share)',
- NULL) 锁定方式,
- C.MACHINE 用户组,
- C.TERMINAL 机器名,
- B.OS_USER_NAME 系统用户名,
- B.PROCESS 系统进程id,
- DECODE(C.STATUS, 'INACTIVE', '不活动', 'ACTIVE', '活动') 活动情况,
- C.SERVER,
- C.SID,
- C.SERIAL#,
- C.PROGRAM 连接方式,
- C.LOGON_TIME
- FROM ALL_OBJECTS A, V$LOCKED_OBJECT B, SYS.GV_$SESSION C, v$lock d
- WHERE (A.OBJECT_ID = B.OBJECT_ID)
- AND (B.PROCESS = C.PROCESS)
- and C.sid = d.sid
- and B.LOCKED_MODE = D.LMODE
一. 优化原则:
1、减少数据库访问次数
(1) 使用数据缓存的存取方式
(2) 使用批量处理的方式
2、减少SQL语句的执行时间
(1) 使用占位符的访问方式
(2) 优化SQL的执行计划(比如使用数据库索引或者调整SQL)
3、 减少程序执行的时间
(1) 使用异步调用代替同步调用
(2) 使用本地API方式代替远程调用(比如WebSerivce)
(3) 减少同步块或者同步方法的使用
(4) 减少IO读写
4、减少请求压力
(1) 使用应用集群部署方式分担掉服务器的压力
(2) 将静态文件和动态文件分离部署,减少J2EE容器的压力
二. 高效Java:
1、尽量避免不必要的方法调用
原则:在Java中,一切都是对象,如果有方法(Method)调用,处理器先要检查该方法是属于哪个对象,该对象是否有效,对象属于什么类型,然后选择合适的方法并调用。尽可能在外层确定是否一定要执行该方法。
优化前:
- public void CallMethod(int i ){
- if( i ==0 ){
- return;
- }
- ... // 其他处理
- }
- int i = 0;
- ...
- CallMethod(i);
优化后:
- int i = 0;
- ...
- if( i ==0 ){
- CallMethod(i);
- }
2、尽量避免不必要的对象创建
原则:当一个对象是用new进行初始化时,其构造函数链的所有构造函数都被调用到,所以new操作符是很消耗系统资源的,new一个对象耗时往往是局部变量赋值耗时的上千倍。同时,当生成对象后,系统还要花时间进行垃圾回收和处理。尽量少用new来初始化一个类的实例, 当new创建对象不可避免时,注意避免多次的使用new初始化一个对象,尽量在使用时再创建该对象。
优化前:- NewObject object = new NewObject();
- int value;
- if(i>0 )
- {
- value =object.getValue();
- }
优化后:
- int value;
- if(i>0 )
- {
- NewObject object = new NewObject();
- Value =object.getValue();
- }
- Vector vect = new Vector(1000);
- ...
- for( int i=0; i<vect.size(); i++){
- ...
- }
- int size = vect.size();
- for( int i=0; i>size; i++){
- ...
- }
- Map map = new HashMap();
- Iterator iter = map.keySet().iterator();
- while (iter.hasNext()) {
- Object key = iter.next();
- Object val = map.get(key);
- }
高效率的遍历方式:
- Map map = new HashMap();
- Iterator iter = map.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry entry = (Map.Entry) iter.next();
- Object key = entry.getKey();
- Object val = entry.getValue();
- }
三. 高效SQL
一. 优化思路
1、减少HTTP请求的次数
(1) 合并Javascript/CSS以减少请求次数
(2) 合并前台请求次数成一次操作
(3) 前台页面缓存
2、 减少网络数据的传输量
(1) 将大JSP页面的JS挪到JS文件
(2) 将JS文件进行压缩传输
(3) 最小化JS文件的大小(去掉空格和替换变量名等)
3、减少服务端IO读
(1) 将静态文件和动态文件分开(将静态HTML、图片之类的存放在HttpServer、动态文件JSP/Servlet放在J2EE容器)
1. 尽量避免随意使用静态变量
当某个对象被定义为static的变量引用时,那么GC通常是不会回收这个对象所占用的内存
public class A {
static B b = new B(); // 静态变量b的生命周期与A类同步, 只要A类不被卸载,那么b对象就会常驻内存,直到程序终止
}
2. 处理好包装类型和基本类型的使用场所
虽然包装类型和基本类型在使用过程中是可以相互转换,但它们两者所产生的内存区域是完全不同的,基本类型数据产生和处理在栈中;
包装类型是对象,在堆中产生实例。
3. 慎用synchronized
实现同步是要很大的系统开销为代价,甚至可能造成死锁,所以尽量避免无谓的同步控制。
4. 单线程尽量使用HashMap、ArrayList
HashTable、Vector等使用了同步机制,降低了性能。
5. 尽量减少对变量的重复计算
for(int i = 0; i < list.size(); i++) // 循环中,循环条件会被反复计算
应该改为 for(int i = 0, len = list.size(); i < len; i++)
6. 尽量避免不必要的创建
A a = new A();
if(i == 1){ list.add(a); }
应该改为: if(i == 1){ A a = new A(); list.add(a); }
7. 尽量确定StringBuilder的容量
StringBuilder的构造器会创建一个默认大小(通常是16)的字符数组,在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建StringBuilder的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。
8. 尽量早释放无用对象的引用
大部分时间,方法局部引用变量所引用的对象会随着方法结束而变成垃圾,因此,大部分时候程序无需将局部引用变量显示地设为null;但是如果对象较大,占用较多内存,不用的时候就应手动置为空了