杨建旭
作者杨建旭2017-11-12 23:35
技术经理, 中国人民银行清算总中心

应用中间件相关的性能监控与优化

字数 7156阅读 4743评论 1赞 14

在信息系统中,不少性能问题是由不起眼的应用中间件造成的。应用中间件之所以诞生,是为了帮助应用程序的编码人员处理与业务逻辑没有太大关系而又必须处理的经常性事物,比如处理应用程序和数据库之间的关系,设置开启多少个session来处理客户请求,session的超时时间等等。

然而在享受便利的同时,应用中间件也会成为系统性能问题的缔造者,但开发人员和测试人员往往忽视了中间件本身对性能的影响,这种影响包括交易吞吐量的制约、响应时间的影响、交易成功率的影响等等。

在11月10日的线上交流中,大家针对应用中间件的性能监控、性能优化提出了不少问题,本文对这些问题进行了分类总结,同时也感谢中国金融电子化公司的swallowluo帮忙回答了不少问题。
应用中间件相关的性能监控与优化可以归类为6个字,判断、监控、优化。

  1. 判断
    性能问题是多方面的,比如应用、系统软件(应用中间件、消息中间件、数据库等)、操作系统、硬件、网络,那么如何诊断性能问题是出自应用中间件。

  2. 监控
    监控是确诊性能问题的唯一重要手段,没有监控数据,任何人都只能猜测问题原因,而不能确定问题根因。
    监控包括了监控工具和监控指标。监控工具是利器,具有了利器还需要明确监控什么指标,这些指标如何影响系统的性能。

  3. 优化
    应用中间件的性能优化涉及到调整中间件的参数和一些策略。需要了解调整这些指标有什么好处和坏处,这些指标之间有什么关联。

一、 判断

如何判断性能问题是出自应用中间件?

运维监控、甚至是专门的性能测试中,最容易漏掉监控的就是“应用中间件”和“存储”。往往是出了问题,把所有可能怀疑遍了,也没发现什么可疑之处,比如cpu利用率不高、网络带宽占用率很低、读写磁盘IOPS不多、数据库响应时间很短,应用的并发数量也充足,可就是业务响应时间很长,吞吐量很低。甚至把硬件配置的一堆参数也分析的透彻,这时候才想起了中间件。

从上面的场景中,其实可以发现,从系统拓扑的角度,前端->中间件->应用->中间件->数据库的包抄当中,如果你发现其他都没有问题,那很可能就是中间件的问题了。或者从系统层次的角度,应用->系统软件(中间件、数据库)->OS->硬件/网络这条线上,如果其他都没问题,那也得看看中间件了。

我比较主张,一旦遇到性能问题,或者平时关在测试环境里做的性能测试,只要是涉及到应用中间件的、并且有压力的,一定要做好中间件的监控,在所有监控数据都全面的时候,判断问题才得心应手。就好比去医院,说了病情,大夫一般什么结论也不会给,而是开一堆检查单化验单,你先做N个检查,我看看。

如果已经有了中间件的监控数据,可以先关注ResponseTime(接收到请求和应答之间的平均时间),如果这个值出现异常,那就说明业务在中间件中的这段处理可能有问题,这段时间包括了收到请求到分配执行的时间,包括了应用等待数据库连接池的时间、包括中间件调用数据库执行时间等等,然后我们再分段分析哪里出现了问题。如果ResponseTime较长,收到请求到分配执行的时间很长或者等待数据库连接池的时间很长,而从数据库上查看SQL的执行时间很短,那么八成就是中间件里面的时间长了。

二、 监控

(一) 监控工具

1. 采用什么工具来监控中间件?

1)中间件监控
自然是各家自带的监控工具或者监控模块效果最好。采集项也都是针对自己的产品定制的。当然,市面也会有针对某个中间件的监控产品。

例如WAS监控有自带模块“性能监控基础结构(PMI)”,也有PerformanceTuningToolkit用于后期展示。应用中间件WAS的监控方法可以参考本次线上交流的分享http://www.talkwithtrend.com/Article/216341
tomcat监控工具有市面上的probe等。

同时,可以查看中间件的日志、FFDC(事故记录,其中包含堆栈跟踪、异常发生时的环境,以及对生成这一异常的服务器的组件状态所做的一个短转储)

2)JVM的监控
但如果某个中间件没有自带监控工具并且市面上也没有它的监控工具,可以采用JVM的监控来监控一些最基本的信息(JVM线程、GC等)。这种主要是通过Java自带的JMX以及一些中间件的JMX接口查询。可以通过Jconsole远程查看,开源的话,Zabbix也可以收集的到,不过要自制模板。

3)应用的监控
APM是Application performance management的简称。

有时候中间件没有定制的监控工具,同时又觉得JVM的监控信息太少,有时候单从中间件的监控中不足以分析应用的性能问题、数据关联,可以采用Pinpoint、Glowroot、dynatrace等工具。这类工具采用插针的方式,在java代码中插针,可以在吞吐量不是特别巨大的时候,监控现在每一步的执行干什么、响应时间、数据关联等等。但由于是采用插针方式,在吞吐量特别大的时候,这种应用性能管理工具反而不太好使了。

2. 采用什么工具监控中间件的集群

如果想看最全面的性能数据,中间件自带的工具无疑是最好的,例如WAS监控有自带模块“性能监控基础结构(PMI)”,并且辅以PerformanceTuningToolkit来做后期展示。对于大规模集群的监控,只能是运维级别的监控,即大面上看一看(不像性能分析那么细致),这个应用还活不活着,有没有队列堆积,资源利用率等等。例如webshpere采用IBM的itcam比较配套,正所谓原汤化原食,虽然我并不觉得ITCAM好用。开源的优秀代表比如zabbix,它可以提供分布式系统监视以及网络监视功能的企业级的开源解决方案。

(二) 监控指标

如果从大的系统性能角度,需要看响应时间、吞吐量、资源利用率、交易成功率这几个重要的指标。这几个指标都是可以从中间件中观察到的。只不过这些指标我们往往不从中间件中监控。例如,响应时间、吞吐量往往从用户的端到端计算,或者从日志里面计算,资源利用率从操作系统层面监控。这里介绍的指标是中间件特有的监控指标。

1. 响应时间

最重要、最直观的指标就是响应时间:这里的响应时间指的是业务在中间件中的响应时间。
例如WAS可以监控到众多的这方面的响应时间,有
1)ServiceTime:完成servlet请求的平均响应时间(毫秒),
2)ResponseTime:接收到请求和对方应答之间的平均时间,
3)RequestResponseTime:接到请求与分派执行之间的时间,
4)DispatchResponseTime:从分派执行到返回应答之间的平均时间。
5)等等

可以先关注ResponseTime(接收到请求和应答之间的平均时间),如果这个值出现异常,那就说明业务在中间件中的这段处理可能有问题,这段时间包括了收到请求到分配执行的时间,包括了应用等待数据库连接池的时间、包括中间件调用数据库执行时间等等,然后我们再分段分析哪里出现了问题。如果ResponseTime较长,收到请求到分配执行的时间很长或者等待数据库连接池的时间很长,而从数据库上查看SQL的执行时间很短,那么八成就是中间件里面的时间长了,需要重点关注其他的中间件当中的指标了。

其他比较常关注的指标包括:

2. Web应用程序其他指标

ConcurrentRequests:并发处理的请求数
RequestCount:servlet处理的请求总数。结合这个指标和监控的总时间,可以计算请求的吞吐量。
ErrorCount:错误的数量。需要结合RequestCount计算错误的比例。

3. JDBC连接池

PoolSize:连接池的大小
PercentUsed:正在使用的池的平均百分率
WaitTime:在允许连接之前的平均等待时间(单位毫秒)。如果这个值不为0,并且等待时间较长,需结合PercentUsed和WaitingThreadCount来扩大PoolSize。
WaitingThreadCount:等待连接的平均并发线程数

4. 线程池

线程池有许多类型,例如web容器线程池、ORB线程池、EJB异步线程池
池中配置的线程数。
ActiveCount:并发活动的线程数
PercentUsed:正在使用的池的平均百分率,如果太大(超过80%,接近100%)那就说明线程不足了。

5. JVM虚拟机

HeapSize:JVM的堆大小
UsedMemory:JVM运行时中的使用的内存总量(KB)

6. 会话数

ActiveCount:请求当前访问的会话总数。在测试环境中,如果在稳定的压力面前,请求访问的会话数持久增长,那么,很可能程序中没有关闭会话的设置。最终会导致会话数不足,无法接受新的请求。

7. 垃圾回收GC

垃圾回收期间,1)占用CPU资源,2)业务的响应时间略有影响。
因此垃圾回收的调用频率比较重要。
GCIntervalTime:两次垃圾回收调用之间的平均时间(毫秒)
GCTime:垃圾回收调用的平均持续时间(毫秒)

8. 高速缓存

9. 数据源语句缓存大小

详细可参考本次线上交流的分享材料
http://www.talkwithtrend.com/Article/216337

(三) 监控和分析案例

1. weblogic 数据源连接延迟案例

1.png
这个案例中weblogic 的jdbc 延迟较高。

一般来说,jdbc延迟较高是因为jdbc连接池数量不足,应用要连接数据库,而连接不够用了。但从这个案例的数据来看,最大连接池数量180,当前有104个连接是已经连接了数据库,这104个当中,有19个是正在用的(即正在执行sql),现成的可以用的就有104-19=85个,另外还有180-104=76个可以被后期产生。

但这种情况下竟然有40个线程正在等待“数据库连接池“,平均等待时间5527毫秒。

可能性分析
1)weblogic的bug,咨询厂商,查询相关bug,必要时升级weblogic
2)整个weblogic系统处于半僵死状态。
有资源(85个现成的连接)不用,往往是系统慢到了惊人的程度。建议检查系统资源利用情况。操作系统层面,内存是否有page space in/out,例如aix看看pgsin/pgsin有没有非0的度数jvm的内存是否濒临耗尽,系统不停的做垃圾回收(GC)系统分区的CPU分配过低,比如只分配了0.1颗cpu,CPU利用率90%以上。其他系统资源接近是否饱和。

2. WAS的内存溢出监控方法

可以通过查看垃圾回收日志中剩余内存的大小或者已用内存的大小进行初步判断,如果JVM的空闲内存一直在减小,那么结可能存在内存溢出(在垃圾回收日志中是可以看出哪些是fullGCC,哪些是minorGC的,而且如果没有内存溢出的话,fullGC后,空闲内存会有较大提升,所以看垃圾回收日志是可以看出一些内存溢出的端倪的。)。如果发现有内存溢出的隐患时,可以通过kill -3或者wsadmin命令生成内存转储文件,使用IBM提供的HA工具对内存转储文件进行分析,尝试找到溢出点,并进行修改。

如果实在找不到问题原因,并且在垃圾回收日志中可以看到有内存溢出的迹象,那么就要制定定期重启WAS的机制了,然后一直到找到问题为止。

三、 优化

(一) 中间件如何影响系统的性能指标(如吞吐量、响应时间、交易成功率)?

业务系统的性能上不去(具体表现在吞吐量低,响应时间长)等现象,不少是应用中间件导致的。
例如系统的处理能力上不去,加了WAS并发也不管用,cpu利用率上不去。然后仔细一问,加了什么并发,回答说“负责去MQ队列读消息的应用进程数”,我问“连数据库的jdbc连接池数量呢”,回答说“不知道”。这说明不少人对中间件的参数以及它的作用并不是很清楚。

跑在应用中间件上的应用是委托“中间件”来处理“应用”与外界的一切联系,比如
1)有请求进来,我有多少个session来服务于请求
2)应用需要读写数据库,数据库连接由应用中间件负责,并且还放置了连接池。
3)应用需要多少内存,由中间件定制
4)应用需要做GC,由中间件定制
5)等等

可以把这个中介(中间件)看做是应用和外界联系的一个管子,或者多个管子(每个管子负责某一方面的联系)。

如果这个管子太细,比如数据库jdbc连接池的太小,就不足以满足应用与数据库的频繁沟通。这样前端就会积压大量的业务等待处理,而后端又不给力,导致了等待“数据库连接”的时间变得特别长(也就是响应时间增加),响应时间增加后,单位时间呃逆处理的业务数量减少,也就是吞吐量下降。

上面的例子是前面的管子太粗,把大量的请求放进来,跑到了应用服务器上,而后面的管子(数据库连接)太细。

假如说这时候把后面的管子放的足够大会出现什么结果呢? 也许性能优化的还不错,也许就出现灾难(也就是所谓的负优化),本来一秒钟还能处理10笔业务,结果,大量业务冲到数据库上,把数据库压瘫了,一笔业务能也处理不了了。

竞争剧烈的时候(大量业务抢一个或几个小管子)就会有等待超时(例如设置了进程等待资源超过xx秒就超时,进程自杀),或者僵死(拥有A资源,等待B资源,而另一个业务拥有B资源,等待A资源),这就造成了交易失败。这也是为什么所有系统在吞吐量高到一定程度的时候就会出现交易成功率不再是100%的现象。

再比如设置GC太频繁,会导致应用总会有停顿,停下来做那个GC,而忘了应该干的正经事。

(二) 优化的目标

目标是把耗费在中间件的时间缩短(提升用户体验),提高整个应用服务器的吞吐量。

(三) 中间件的参数的优化?

说到优化,往往用到的词是调优,既然是调优,就是case by case的调,N个参数这个一会儿调高,那个一会儿调低。中间件的参数也是这样,参数很多,互相牵制。参数有默认的设置,根据自身系统运行的情况,可以进行调节,不能太大也不能太小,找到一个接近最优的组合。

一般情况下,一个新的系统隆重出场,安装上之后,参数都是默认。所有调优的起点都是这套默认的参数。然后根据预期的性能模型(例如并发用户数、操作频度、业务类型、吞吐量等等)施加压力。如果是已经在生产上运行的系统,那么可以直接在业务高峰期抓取监控信息。

根据各个监控指标看看哪个指标不够用了,例如jdbc连接池利用率90%,jdbc连接等待时间较长,那就谨慎考虑是否增大jdbc连接池的数量。但前提是,调整某一个指标,需要考虑对其副作用。例如,如果数据库这时候资源利用率很高,SQL语句执行时间较长,这时候如果把jdbc连接池这个大口子给打开了,会导致灾难性后果,要么就是吞吐量更低了、响应时间更长了,要么就是系统瘫痪了。

再例如,会话数、线程数到达最大值,接收不了新请求了,要么增大会话数、线程数看看,要么缩短每个会话的时间。如果增加会话数、线程数,就要考虑这个应用服务器现在的资源利用情况能不能撑住更多的业务,后端的数据库能不能撑住更多的业务。

增大这些指标有一个终极影响,就算别的影响都没有,占用更多的内存总是有的吧。这一点和增大高速缓存、数据源语句缓存大小有点像。这里的性能提高了,而别的地方因为缺少内存而性能下降了,没准整体的性能也下降了。

如果是生产环境的调优,一定要评估其影响后,采用渐进的方式调,即目标是从10调到50,但一次只增加一点,10-20-30-40-50,这样慢慢调上来,这样不至于因为未知原因一下子把系统拖垮。
另外,调什么参数,一定要了解其含义、原理、调整后的收益和风险是什么,最好是N个参数能在脑子里缠绕为一个整体。

具体指标含义及对性能的影响可以参考本次线上交流的分享“应用中间件概念及关注指标” http://www.talkwithtrend.com/Article/216337

如果觉得这些指标太多,还要一个有优先级的甩干版,如下:
高优先:调整JDBC连接池大小、线性池(N种线程池)、JVM虚拟机的heapsize
中优先:会话数、垃圾回收GC策略
另外还有高速缓存、数据源语句缓存大小

(四) 设计层面的优化

有人咨询:什么有效办法避免中间件实例hang死?

首先咱们分析下可能造成hang的原因
1)中间件bug

2)硬件资源不足
例如,jvm的heapsize太小,不足以运行这个应用服务器。这种情况就是加资源

3)应用逻辑导致
例如内存泄露,这个很难定位。但很好解决--restart。所以我见过很多企业的系统有定期重启的运维策略。所以内存资源充足的定义是:在下次系统重启之前内存没有被耗尽。
避免的方法,1)定期重启,2)采用集群,挂了一个不要紧,只要不是同时挂就行。

4)资源争用导致
不当的配置也会导致中间件处于假死状态。比如某类资源(session或jdbc)被应用完全占满了,并且短期不释放,这样新的请求就没法执行,造成了假死的情况。这类情况,要做好超时放弃的参数配置。

从上面的分析可以看出,除了调应用bug,找厂商解决bug,增加硬件资源,调整中间件参数之外,还可以有的方法是系统架构设计层面和运维策略。

系统架构设计层面:采用集群是个解决问题的大招。IT行业从上世纪的硬件高可用转变为今天的软件控制的高可用,就是要解决各种解不了的问题。

运维设计策略:定期restart也是解决问题的大招。

搜索微信号关注“性能测试与调优”

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

14

添加新评论1 条评论

#zgagxf数据库管理员, 某数据服务厂商
2018-05-09 20:56
关于weblogic 监控指标这一块 有没有详细的说明文献
Ctrl+Enter 发表

本文隶属于专栏

活动总结
活动总结是社区交流活动内容的总结及延伸,为大家提供了社区专家们丰富且高水平的理论知识、实践经验以及常见问题的最佳解决方法,非常值得大家收藏学习。

关于TWT  使用指南  社区专家合作  厂商入驻社区  企业招聘  投诉建议  版权与免责声明  联系我们
© 2019  talkwithtrend — talk with trend,talk with technologist 京ICP备09031017号-30