




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
(一) -方案和原则一.方案演化 历经一周多的性能测试和性能调优工作接近尾声了,这里总结下一周多的进展和调优情况。首先声明一点,我没有性能调优方面的经验,很多方法都是请教了大牛和网上查找得到的答案,感觉自己进步了很多。 1.1封装框架 刚开始对于压力测试采用的自己先的压力测试框架,就是启N多线程。然后调用远程服务器进行压力测试,调用完成后有响应时间等统计信息(见pc2性能测试方案篇) 优点:压力测试简单,不需要写太多代码。 缺点:和客户端性能有很大关系,在不同客户端上起线程的速度肯定不一样,这样就导致了测试出来数据价值不是很大。 1.2 windows下Jmeter 进行测试 优点:统计信息全面,较为切近的模拟并发情况。 缺点:由于windows下客户端性能差别较大,启动线程并没有linux下快,会导致发送的请求数有限,tps上不去的。 1.3 linux下Jmeter 进行测试 优点:较好的模拟并发情况,并发效率较高。 缺点: 使用较为复杂,如果使用nmon更需要一定的配置基础。 二.调优原则 1. 贵在坚持,不可以一簇而就,别人的经验通常是针对特定系统,特定环境的,不可以照搬,不可以不知所以然。 2. 细节决定成败,调优的准备工作要做好,消除外部因素对测试造成的影响。 3. 可以按照先整体-后部分-再整体的思路进行测试,先整体是看看整体哪块有问题,找出比较慢的部分进行重点测试和调优,然后再整体测试保证所有应用并发是没有问题。(二) -方法和步骤1. webTrace 跟踪数据库SQL 瓶颈:是否走到索引,是否sql执行计划最优等。 2. jProfile 跟踪那块代码消耗cpu较多,(jprofile使用方法见工具篇)。 3. kill -3 进行线程查看,如果有大量BLOCKED线程,则说明有问题,如果RUUNNBLE的线程很多都是在执行一样的操作那就说明这部分比较消耗资源,要做优化。 4. apache 调优,对apache的各个参数进行调优,最终使apache参数对应于当前系统和当前并发量最优。所以调优的并发量参考数据要经过计算,不可以认为响应时间越快,tps越高越好。(经验告诉我们apache由于是多进程多线程的,我们采用的是apache 和jboss一直链接的情况,也不会消耗太多性能,所以还是apache好些。其在并发处理方面的能力要显著高于JBOSS) 5. jvm 调优:对于jboss配置的jvm 垃圾回收机制进行调优,让其垃圾回收更加及时高效。 6. 内存使用调优, 使用jconsole 进行监控,如果内存直线上升,最终得不到稳定,则说明有可能存在内存泄露等问题。 7. linux 内核调优。这部分难度较高,一般不需要,如果以上步骤不能满足性能要求,考虑此步骤。(三) -遇到的问题(数据库)1. Webtrace 分析sql 性能,发现 userPermissionService.listVAccountIdsByUserIdAndProductCode 是数据库未分析数据,执行方案是基于开销的方式,导致执行计划未走到索引。后来是走的索引,但是仍然较慢。 分析: kill -3后查看jboss 日志发现很多都在执行listVAccountIdsByUserIdAndProductCode 这个代码 由于apache 线程池都进行了调整,有足够多的等待线程,不太会导致BLOCKED,这样runnble 的较多都集中在这个代码上,就说明线程在这里比较占用时间。(用vi 不要用 tail) 这个sql有问题: select pup.vaccount_id from pc2_user_permission pup where duct_code = #productCode# and pup.user_id = #userId# and pup.acl = 1 没有走正确的索引,目前只有product_code +user_id的索引,需要建立 product_code +user_id + acl的索引 解决方法:DBA 进行oracle 的数据分析,然后再跑,或者delete掉数据,这和应用进行delete一样,数据库会自动进行数据分析和重建索引等。 对于走了索引仍然较慢的情况,加上含有acl的索引,这样就不用查询数据库了,速度会快比较多。 2. 测试apache 和jboss 性能对比情况时,发现和QA使用jmeter测试的结果不一致,本机测试apache 较好,QA测试 jboss反而更优。 本机测试,多数情况是apache 较好,QA使用jmeter做大并发时,数据库连接数是个瓶颈,经常over-load。 解决办法:需要让DBA 再把数据最大连接数调大些, process给调成250。 3. 不断执行压力测试,表空间占满。 分析:不停的delete 和insert时会有碎片产生,这样oracle自己的回收机制来不及做,就会导致原来占一个G的数据,现在就要占5G并且会增加insert的成本,导致插入数据时非常慢。 处理方法:正常情况下是会自动回收的。只要在高并发情况下才会出现这种情况,原来表空间6G,目前增加到10G, DBA进行碎片整理。 4. DBA调整了事务管理块及insert预分配空间,调整后性能有所提高,大概提高10%左右 因为PC2中有大量的insert操作,DBA认为insert操作时,若有较多的磁盘碎片,会对insert性能产生影响 ,所以为此预分配了一定空间,所有的插入操作都是往预分配空间插入,这样省去了寻址的时间。 5. 报数据库已经关闭异常,jboss log 报出 ERROR com.mchange.v2.resourcepool.BasicResourcePool : com.mchange.v2.resourcepool.BasicResourcePool5b553d28 - Unexpectedly broken! com.mchange.v2.resourcepool.ResourcePoolException: Unexpected Break Stack Trace! 解决方法:修改pc2-spring-common.xml 中C3P0配置,将其如下值修改 此问题较为普遍,在UDB和原来PCC都有发生,发生场景为不少连接被占用(本次是被预发环境占用)资源发生竞争时,如果设置为true,已经被占用的连接,就会直接报出异常,如果为false ,他会去尝试再获取下,短链接的情况下会很快释放的,这样就不会报出异常了。 6. 多次fetch的数据问题 webtrace是一个很不错的SQL跟踪工具 通过查看trace得到的SQL执行情况,问题一可以很容易查到原因,问题三的原因也由此可以看出来。 虽然走到索引,但fetch次数太多(ibatis是以object来传输的,查到了这么多数据,取了这么多次,肯定是耗费很大性能的)。数据存在问题。 (四) -遇到的问题(Apache)一.两个失误 1. Timeout 20 改错 改成0了,导致报500 异常 解决办法:这样客户端链接一直不超时,很快就会占满所有的资源。其它连接就连接不上。这个超时时间是必须有的 2. 配置的应该是AJP1.3的协议,原来配置项有些配置到8080端口了 配置的是http1.1协议。对应于AJP的8009参数没有配置上。导致不能满足高并发的要求. 二.其他调优点 3. tps 上不去 分析: (1)测试代码问题,把newSampleTest() 放在了setUp里面,统计结果不准 ,导致TPS一直比较异常,要么是用户数整除的,要么是直线上升的。 (2)TPS开始会比较高,但随时间大幅下降,响应时间也是越来越长,并通过监控显示, 大量线程bolck在 取用户产品权限这里 QA的测试脚本中存在一个问题:往数据库插入的数据,每次请求都是同一个userid,只会循环改变vaccountid,这样导致按userid取列表的SQL性能每次请求一次比一次差。 (3)接口测试时都是短连接,不需要长链接。 httpd.conf KeepAlive 为Off JkWorkerProperty worker.localnode.connection_pool_timeout=0 为链接池的等待时间,让其不超时,因为我们采用的是一个apache 对应一个jboss 一直保持通讯就可以了,JBOSS 同步修改。 结果:比原来理想,tps 有提高。 4. 502 异常频繁出现 4.1 解决办法:将原来的 mod-jk localnode方式修改为loadbalancer,使用apache 缓冲池,并设置了apache 线程池大小为500。 4.2 又爆出 502、503 异常:Apache configured - resuming normal operations 将socket超时时间增加些,让请求的线程等待时间加长一点。不至于很快拒绝掉,导致503异常。 JkWorkerProperty worker.localnode.socket_timeout=20 增加 JkWorkerProperty worker.localnode.connection_pool_minsize=25 (增加,原来注释掉了) 4.3 502 Response has been sent to the client (yet) 解决方法:线程池被被占用,先修改log看下,再有问题修改下 mod-jk soket超时时间。调的长一点。 5. 将maxProcess 和maxThread 同时出现,以哪个为基准,cpu与性能有什么关系 分析: maxProcessor 和maxThread 同时出现时,maxProcess 优先级较高。maxProcess 表示最大并发数,maxThread 是jboss 启动的最大线程数。 这里最大链接数调整为3200 ,这个已经足够满足需求了,用于保证jboss 的稳定性,算法就是每个cpu 可以撑住200个线程,16core*200/core = 3200 ,生产环境为8core cpu需要调整下。 apache 起了10 个进程 StartServers = 10 这里有两个相关参数要调整 MinSpareThreads(http_conf)*10 = MinSpareThreads (server.xml) ? JkWorkerProperty worker.localnode.connection_pool_size=320 *10 (启动了10个进程)= maxClient ServerLimit 100 ThreadLimit 400(大于 ThreadsPerChild 320) StartServers 10 MaxClients 3200 MinSpareThreads 100 MaxSpareThreads 320(小于MaxClients/10) ThreadperChild 320 6. 报异常Socket read failed org.apache.catalina.core.StandardWrapperValve ERROR org.apache.catalina.core.ContainerBase.jboss.web.localhost./pc2.remoting : Servlet.service() for servlet remoting threw exception java.io.IOException: Socket read failed at org.apache.coyote.ajp.AjpProcessor.read(AjpProcessor.java:1014) at org.apache.coyote.ajp.AjpProcessor.readMessage(AjpProcessor.java:1089) 解决方法:对比和UDB配置区别server.xml maxThreads=3200 color=redminSpareThreads=100(1000修改为100没有与httpd中相应值 10:1 这个说法)/color backlog=256 7. 宕机,apache error_log报child process 14629 still did not exit, sending a SIGTERM 错误 解决办法:apache 子进程无法正常终止,资源耗尽就宕机了,apache的日志文件太大导致的,将apache 日志删除。 8. 3200多个close_wait 状态, apache 很慢。最终跑完时有1800多个close_wait,gcUtil观察回收情况,发现回收不正常 YGC非常慢,不是每次更新一行都有增加回收次数 解决方法:由于测试环境是 16core的cpu ,这样我们的最大连接数可以按照 16*200= 3200 调,从结果来看,1800个最终的close_wait/UDB 在同样配置下是900左右的cose_wait挂起状态,也说明我们16核接收了更多请求,但是apache 配置确没有接受这么多,导致线程阻塞。调整为 3200个最大并发数。 调整后 wait 的线程保持 200 个左右回收正常了。刚才的回收不正常是由于线程挂起导致的。(五) -遇到的问题(内存)1. free 查看内存,使用超过16G(累积出来的)。而生产环境只有一驱四 25G内存,有内存溢出危险。 解决方法:修改jboss 启动脚本虚拟机配置,修改回收机制,改为CMS回收。 Xml代码 JAVA_OPTS=-server -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX :+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods 2. 内存使用始终很大,在2G多,tps 也上不去。ps aux 没有发现apache日志占用内存。 解决方法:apache access log 是apache的访问日志,每次访问都会记录,占用了46M,删除后内存占用降低了很多 从2G多降低到300M,最终在httpd.conf中去掉access_log配置 #DeflateFilterNote ratio #LogFormat %r %b (%ration) %User-agenti deflate #CustomLog /home/admin/pc2/logs/deflate_log deflate #LogFormat %h %l %u %t %m /%HOSTi%U%q %H %s %b %Refereri %User-Agenti %T combined #LogFormat %h %l %u %t %r %s %b common #LogFormat %Refereri - %U referer #LogFormat %User-agenti agent #CustomLog /home/admin/pc2/logs/access_log combined (六) -遇到的问题(环境准备)1. SA默认装了jboss4.2.3GA+jdk1.6会出现ajp connector的线程挂起在CLOSE_WAIT状态上。属于jboss的一个bug,具体见:/jira/browse/JBPAPP-2100 解决方法:Jboss 4.2.3的bug 后来统一调整为 4.0.5 版本。 可选通过修改Linux内核参数: net.ipv4.tcp_keepalive_time=30 net.ipv4.tcp_keepalive_probes=2 net.ipv4.tcp_keepalive_intvl=2 增大tcp协议请求的等待时间,尝试消除CLOSE_WAIT状态的线程。一定数量的close_wait状态(即线程挂起)多时则需要处理。 2. open files 确保足够大,否则并发大的情况可能jmeter-server会出现too many open files错误 解决方法:ulimit a 查看系统参数 配置为 open files (-n) 10240 3. Jprofile 比较影响性能,做长时间大压力测试时去掉。 4. 发送消息给计费,连不通,导致异常,pc2_log 变的很大 303 M,内存飙升,old区有大量对象待回收。 解决方法:看下出异常的时间,4:30 左右开始飙升,出错时间吻合,就说明是出错导致的,还有一个影响因素就是00的task 每两分钟取10000条进行处理,处理时肯定会导致大量并发等待,占用大量内存,一时回收不掉。 将任务时间调短一点 将数据中错误数据清除 (待处理)(七) -遇到的问题(方法策略和代码问题)1. QA 测试时,第一次去链接时间较长 处理方法:应该去除第一次链接的时间,第一次链接的时间包含了DNS解析等等,比较消耗时间,这个和访问web页面一样的道理。才能模拟正常的使用情况。 2. 测试错误率要求在0.01%-0.05%,目前太高。 处理方法:测试程序覆盖了原有的result是false 还是true 的方法。导致有些成功的也返回false。 3. jprofile 跟踪到代码有cpu-views 刷新缓存消耗较大。Kill -3 发现大量线程都在执行这个代码 (1)中有对对象的序列化,比较慢 List listCorpInfo = new ArrayList(); for (String vaccountId : vaccountList) CorpInfo corpInfo = corpInfoCacheService.getCorpInfoByVaccountId(vaccountId); if (corpInfo != null) listCorpInfo.add(corpInfo); 解决方法:刷新的是公司列表数据,由于corpinfo不是java 内建对象,采用java自有的序列化机制,效率不高,修改代码改变缓存实现策略(刷新缓存返回时不返回公司列表,返回null,不用序列化公司实体了)(八) -工具和方法一.linux 自带命令查看性能等。 (1)top -1 查看 cpu 使用情况,占到162% (2)free 查看内存,使用超过16G(累积出来的) (3)ps cx | grep java kill -3 pid 强制显示该java 进程的线程信息 发现 39个blocked进程 grep BLOCKED jboss_stdout.log -wc TIMED_WAITING是主动的有时间的waiting,是没问题的. 很多线程并发时,RUUNBLE较多的集中在同样的线程上,就会有问题的。 (4)netstat -an| grep CLOSE_WAIT 和上面的作用一样的 netstat -an| grep WAIT (5) 查看并行的进程 netstat -an|grep EST|wc -l 查看数据库连接数 netstat -an|grep 1521|wc -l (6)jstat -gcutil 线程 2000 监控堆栈回收情况 这个是java 自带的便捷工具 -gcutil 能够看到正常的回收情况,YGC应该是每次刷新都增加的,而对应于old区的FGC会较长时间执行一次。 占用率在40%-50%是正常的。 二.使用java 自带jconsole 监控内存 修改了 jboss 启动脚本的run.sh 增加配置端口9999 JAVA_OPTS=$JAVA_OPTS -D=$PROGNAME -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom .sun.management.jmxremote.ssl=false 注意:如果在run.sh 增加了这段配置,不要再在jbossctl再加一次,否则会被run.sh 覆盖掉,导致你找不到原因的连接不上。 增加了 jboss 启动项 jbossctl 的配置增加 JA
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论