聊聊系统端到端优化

最近我们接了一个某政务移动APP的优化项目,最初找到我们是希望我们帮他们做一下数据库优化,让这个移动APP能够支撑2万用户登录/秒的并发量,因为根据他们的经验,数据库往往会成为APP的性能瓶颈。我们后来采集了一些数据,发现数据库服务器上压根没啥负载,于是一个数据库优化项目就变成了一个系统优化项目。用户发现优化目标没有变,不过把这个项目分成了两个阶段,第一阶段确定当前并发能力,并初步定位目前存在的主要性能瓶颈。如果第一阶段顺利,再开展第二阶段的优化工作。
前阵子我写过一篇文章众提到过这个项目,通过两次现网实际压测和测试环境压测(实际环境和生产环境的云平台存在较大差异),我们初步定位了云平台的软负载均衡和Redis存在严重的问题,导致了现网环境的并发登录量只能达到最大3000/秒。至此第一阶段任务完成,下一步的优化方向也十分明确了。
最近项目的第二阶段也展开了,首先云厂商解决了软负载均衡的问题,我们也通过D-SMART发现了REDIS服务器的负载不均衡的问题,通过TOP语句分析工具,也发现了一些HOT KEY和BIG KEY的问题。不过解决了这些问题之后,并没有想象的那样,系统的并发能力一下子就提高了上去。这是什么原因呢?
实际上系统优化就像疏通下水道一样,只要整个管道体系中存在堵点,那么在一定时长的高负载压力下,这些堵点都会表现出性能瓶颈。甚至各个IT组件中的缓冲、排队队列的长度也是有限的,当持续的压力把这些排队队列压爆的时候,更大的性能问题就会出现了。这个问题我在前几个月写过的一片《从疏通下水道联想到的优化问题》中有所阐述。
聊聊系统端到端优化
当时我在那篇文章中画了一张图,实际上这张图是针对数据库服务器的。对于大多数传统业务系统来说,中间件、数据库、负载均衡等搞好,SQL优化好,大部分问题就解决掉了。而对于互联网业务,其优化范围要广的多,不仅仅要考虑本系统的性能问题,任何一个调用接口出现问题,当系统负载高的时候都会出现问题。另外一方面,传统业务的并发量总是有限的,并且规律性较强,业务高峰持续的时间也有限,只要在整个系统端到端的结构中,每个环节都能支撑一个处理上限,就没有问题了。如果某个环节无法支撑,则需要通过一些缓冲、队列等来削峰填谷,就能确保系统稳定运行了。而互联网应用的负载变化范围极大,有可能一个突发事件会导致数百倍的访问增加,而且其持续时间之长,很可能各种削峰填谷的手段都不足以应对。因此在互联网应用的优化中,动态横向扩展是十分重要的手段。通过在架构上的优化,实现在云平台上,基于容器或者基于云主机的动态资源调度,才能确保某些突发业务高峰出现时,不会出现性能瓶颈。
不过不幸的是我们优化的这个项目虽然是一个典型的互联网APP,理论上,业务高峰期间,可能会有数百万用户同时使用,不过其架构依然是较为传统的架构。唯一和传统架构不同的是,为了避免业务高峰期的高负载压垮数据库服务器,在系统中引入了一个REDIS集群,用于缓冲部分相对静态的数据。原本这个集群包含3个REDIS主库实例和3个REDIS 备库实例,当主库故障时备库可以快速接管。因为当前的应用架构中,REDIS实例动态扩展时缺少应用上的有效支持,因此,首先我们建议客户首先将REDIS扩充一倍,以满足突发高峰的需求。随后,正式的优化工作就展开了。
聊聊系统端到端优化
其实针对一些互联网APP,其在前端的优化工作就十分复杂,这是目前我们的优化项目现在和今后可能会面对的一系列的问题。上面这张图是针对那个数据库优化图的扩展,在一个非专业互联网企业开发的移动APP中,前端的优化也是一条流水线,整个流水线上的任何一个环节出现问题,都会导致APP的整体并发能力受到影响。就像我们正在做的这个优化项目,当前端的负载均衡问题解决后,系统压力马上就真正传递到了应用上了。而后端最大的一个瓶颈-REDIS服务器的初步问题解决后,系统负载马上就上来了。
在使用3台jmeter进行压测的时候,已经能够把每台REDIS访问网络的流量压倒70M/秒。此时jmeter所在的服务器的cpu已经能够压满。于是项目组立即添加了3台jmeter服务器。这是奇怪的现象又出现了,并发量不升反降,每台REDIS服务器上的流量减少了一半。通过D-SMART我们可以看到,REDIS上的命令的延时是正常的,和3台服务器是差不太多。于是项目组马上把怀疑对象对准了应用服务器。通过jstack生成了一个dump文件。

大量的线程都在等待dubbo的锁,提供后端支持的研发人员一看jstack数据,当即就傻眼了。这明显是dubbo的线程池满了,难道应用里没有设置dubbo线程池就上线了吗?通过和开发商现场人员的沟通,他们居然不知道dubbo还需要调整线程池参数,看样子这套系统中使用了默认值。
似乎问题已经定位,于是在我们的开发人员的指导下,开发商的人员在现场调整了dubbo线程池的配置,压测重新开始。刚刚启动压测的时候,REDIS端看到流量一下子提高到90M/秒,大家都以为问题已经解决了。几分钟之后,负载又下降了为30M左右了。开发商认为我们的定位不对,这个问题并不是dubbo线程池配置的导致的。经过仔细沟通后我们才了解到,他们的框架、应用中都用到了dubbo,而且测试环境中有8台应用服务器,刚才他们只是调整了其中一台应用服务器的框架中的dubbo线程池。于是我们强烈要求他们把框架和应用中的所有dubbo线程池都按照要求调整,再做压测。费了半天劲,开发商终于同意调整。调整完参数几分钟后,REDIS的流量逐渐提升,最后稳定在每个实例90多M。看看时间,已经是晚上10点左右了。解决了这么一个问题,大家都很高兴。
第二天是周六,下午才回到公司。刚刚进门,就收到了优化现场再次发来的求救消息。随着前端负载的加大,应用服务器上又出现了问题。

这个问题比较简单,我以前也遇到过,这是TOMCAT的线程池不够了,于是昨天晚上的一幕再次上演,TOMCAT的线程池居然也没有优化。因此我也没有咨询开发人员的一件,就让现场加大TOMCAT线程池的配置。十分钟后,调整完成,压测重新开始,压测数据立马就飙升上去了。
把源头疏通干净后,后面的瓶颈才会一个个的展现出来,调整完应用服务器之后,REDIS服务器立即又成为优化的焦点了。系统的并发量虽然有所提高,但是离每秒2万登录的目标还有较大的差距。通过监控发现,现在业务负载真正的压到了登录这个应用上了。后面的优化工作依然十分艰巨。
做移动APP的优化与做传统业务系统的优化确实有很大的不同,特别是我们面对的研发团队是传统架构应用开发商的时候。在他们传统的观念中是按照一个普通的管理系统来开发一个APP的,并没有在架构上针对移动应用做较好的设计,这种时候需要优化团队和开发商紧密配合,一点点的发现应用中的问题,并协助他们解决这些问题。不过从另外一个方面来说,大量的不太懂互联网应用的开发商正在开发一些互联网APP,这也给我们的优化队伍提供了一个新的项目机会,我们的优化团队,优化工具,也应该在这个领域上多做技术储备了。

聊聊系统端到端优化》来自互联网,仅为收藏学习,如侵权请联系删除。本文URL:https://www.hashtobe.com/718.html