中国应用性能管理行业盛宴——2016中国应用性能管理大会(简称APMCon 2016)于8月18日至19日在北京新云南皇冠假日酒店隆重召开。APMCon由听云、极客邦和InfoQ联合主办的作为国内APM领域最具影响力的技术大会,首次举办的APMCon以“驱动应用架构优化与创新”为主题,致力于推动APM在国内的成长与发展。
听云研发总监杨金全于服务器端应用监控实践专场发表了题为《全栈溯源——追溯性能问题根源》的演讲,现场解读了在复杂应用环境下,精确定位并判断网络、移动端、浏览器端、服务端性能问题根源,高效地解决问题的经验。
以下为演讲实录:
杨金全:大家下午好,谢谢尤勇老师。刚才尤勇老师给我们分享了很多的前课,包括APM的一些技术点,APM在客户端、服务器端的一些实现方式。我这里不再介绍APM相关的概念,给大家分享一下我们通过这种技术是如何实现定位复杂应用环境下的问题,从而找到这些问题的根源。
今天的主题是全栈溯源,其实这是听云在APM领域耕耘了这么多年的一个技术解决方案,我们主要去讲利用这个方案去解决一些实际场景下的问题。
一、为什么用户离我远去……
就上图而言,不管是现在还是以往,在我们传统应用部署模式下会存在很多盲点或者说叫坑。从我们的角度来看,从右往左去看,最终用户端通过不同的接入方式,比如用浏览器去访问,比如用手机打开一个APP去访问我们的网站,访问我们的服务,那个时候如果你的浏览器渲染能力,或者APP本身的一些切换能力,都会对我们的一些应用性能产生一定的影响。除了这些,就算APP做得很好,或者说浏览器在到节点上都处理的非常棒的话,网络的方面比如说DNS解析、CDN策略也会影响到整个服务的情况。如果说网络保证很好,CDN调动也很好,那么最终问题绕过防火墙就出在我们本身对外提供服务。
比如说我们有一些规则,例如做这些负载均衡,你的WebServers怎么做请求,怎么成为AppServers怎么进行服务,这个时候每一个服务节点出现故障都会对整个用户体验造成影响,所以我们在这个部署架构面前需要一些很好的方式去解决这些坑。
这两年我们听的比较多的是微服务的概念,大家都在做一些服务的拆分,在做一些RPC分布部署,但是为什么用户还是慢慢减少,为什么用户离我远去了,从我们进行市场分析来看,会有一些正常的流失,比如说国家政策导致的流失,比如说产品更新迭代,还有一些是我们受控流失的,比如说新用户上手难度大,用户难以理解这个产品的价值等。除了这些我们比较关心的一点是用户体验差,现在大家都在讲体验,我们说什么是用户体验?用户体验就是说用户的需求在使用你服务的时候,能不能很好的去解决它的痛点,满足它各方面的需求。我们为解决这种用户体验的问题,将用户在使用一个服务的时候,把它进行分片,比如说我们在网络请求的阶段、在浏览器加载、每一个节点的加载、每一个页面的切换、把这些时间做切片,把网络时间也做切片,包括刚才尤勇老师说我们把一些DB做成切片,做成不同慢的追踪。
今天跟大家分享全栈溯源就是我们为了留住用户给我们带来一些价值,这里面主要有三个内容,怎么定义全栈溯源,全栈溯源到底有什么含义,以及有什么价值,再下来我们通过一些场景和案例来实际的去看全栈溯源到底能帮我们解决什么样的问题。
二、全栈溯源
我们先来看看全栈溯源的定义:在复杂的应用环境下,精确定位并判断网络、移动端、浏览器端、服务端性能问题根源的技术手段。它包括:
• 从移动端到服务端的性能溯源
• 从网络到服务端的性能溯源
• 从浏览器端到服务端的性能溯源
• 服务端跨语言跨应用的性能溯源
在复杂的环境下,基于大数据的分布式部署,微服务的部署更加流行化,你的每一个应用不再是一个all in one的应用。在复杂应用环境下怎么样去精确的定位到底是因为网络的原因,还是因为移动端APP原因导致整个用户体验出现了问题,还是说因为浏览器端在页面解析的时候出现了问题,以及最终我是不是能够定位到服务器上的一行代码。这是我们来找到复杂问题的根源的一个技术解决方案,它包括因为投诉或者在移动端收到一条警报告诉你APP在访问的时候出现了缓慢情况时,我们怎么样去定位这次缓慢是因为你的方法出现问题,还是说因为服务器端的一条语句出现了问题;同样我们在网络上是不是因为DNS时间,或者因为首包和首屏时间导致了问题;还有一些浏览器Dom处理的原因,以及服务器端服务器端之间调用的关系。我们今天是服务器的专场,所以下面的一些概念都是基于我们将问题全部丢在服务器端,但在现实的场景里可能不一定是服务器端的问题。
全栈溯源能够给我们带来什么价值呢?大概是以下几点:
• 降低跨部门排障沟通成本
• 从3天到5分钟快速追溯性能问题根源
• 性能问题界定,协助运维明确责任,协助研发修改问题
• 完整业务调用链跟踪(业务、运维、研发)
以往我们去解决一个问题,用户投诉了,老板找到你有一个交易失败了,或者说有一个用户反映访问非常慢,我们只能找不同的人,比如去找运维的人查是不是网络出现了问题,找技术人员告诉你没有问题去找DBA,这样就会存在一些沟通的障碍,跨部门之间的合作不是说我们几分钟能解决的,可能需要很长的时间来进行部门之间的信息传递,信息筛减。我们将这个处理问题的根源时间缩短3-5分钟。还有一些性能问题界定,还有就是完整业务链的追踪。
三、全站溯源的案例
下面是一些案例,我们模拟一个电商的系统,我相信大家对电商都非常熟悉,登录、选商品,把商品加到购物车,下订单去支付等等,这样一整套流程里面去模拟这样一些问题的点,它包括以下一些场景:
• 场景一、登录缓慢 (APP~Server) [HTTP]
• 场景二、商品选择操作缓慢 (Browser~Server) [HTTP]
• 场景三、订单提交失败 (Network~Server) [HTTP]
• 场景四、用户信用检查故障 (Server~Server) [JMS]
场景一、登录缓慢 (APP~Server) [HTTP]
在APP端发现登录端非常缓慢,怎么样定位这个问题呢?还有通过HTTP的协议,有一个商品选择操作缓慢等,最终最严重的问题是订单提交失败,订单提交失败就意味着没产生资金交易。除了这些信息以外还有现在大家都在讲征信的系统,其实电商也会有这样一套系统,你每一次去买一个东西的时候,他会去查你整个用户信用情况是什么样的,如果在查询用户信用的时候出现了故障也会导致整个支付的中断,在这几种场景下我们来看到底是什么原因导致了整个用户体验的缓慢。
上图是一套我们期望的逻辑拓扑,我们通过手机APP,通过页面访问不同的Portal,比如部署在Azure上的Azure Web Role会接受APP的请求,然后将不同的请求分发到对应的Service,以及最终订单的信息,这是我们最初的一个希望的逻辑拓扑。但是这些系统在匆忙上线之后出现了一个问题,我们有一天收到一个警报,说其中大量用户出现了登录拥塞,通过一些信息去看因为其中一个登录的接口平均消耗了9秒的时间,这是不可以接受的。我们看到这次登录的接口它的TCP时间、SSL时间、网络传输时间都非常快,只有一个首包时间比较慢。我们通过这样一次钻取想去看到底这次登录接口是哪一个服务为登录提供服务。
下图我们会看到一个ASP应用过程为我们的登录提供服务,在这个登录的过程中我们看到其中有很大的一个延迟区块是因为它访问了另外一个服务,通过这样一层信息的获取我们就知道登录时间问题根源不是在APP端,而是因为我们服务器端部署在上面的应用出现了问题,这个应用因为访问了其它的应用,导致这个应用为APP提供服务的时候出现了问题。但是这样还不足以说明我们到底哪些用户受到影响,当单一用户受到影响的时候它都已经走过了哪些轨迹。
所以我们需要看单一场景下的一个用户,下图是我们在手机上抓取到的,在这个里面可以看到CPU没有问题,内存消耗也非常正常,而是在网络请求的请求消耗了绝大多数时间,他调用了其中的一个login.aspx这个服务,这个服务占了20多秒,这20多秒究竟花在什么地方,我们到底如何切片,我们去追踪看这个服务到底它有哪些切片。
我们看到是这个服务跟刚才的片子对应,我们再看DB操作,是因为哪一行代码调用了DB操作。可以看到有一个service,这样的 service到底执行了什么样的操作,它大概执行了这么几个操作,其中一个语句消耗了18秒的时间,有了这个信息我们就可以根据这个信息就找到了问题的元凶。
场景二、商品选择操作缓慢 (Browser~Server) [HTTP]
再来看场景二,商品选择非常缓慢。这个时候我们通过浏览器将这条商品加在我的购物车里面的时候,我不知道它到底经过了哪些后续的操作,但是我可以感受到的是它非常慢,在这样的一个应用过程叫选择,下图可以看到在整个24秒时间里面,其中在服务器响应时间里可以占到90%,这个时候到底这90%的时间是哪个服务为我提供了服务。
从商品选择的服务去看它的一些业务操作,除了本身一些业务代码操作还去访问了一个商品列表的操作,这个列表是一个.NET的应用,从这可以看到整个商品选择缓慢可能不是我的页面处理问题,也不是因为提供商品节选的问题,而是说我调用了.NET的服务出现了问题。同样的原理,我们还是没办法知道用户在这个情况下的具体问题。
一个用户在访问这个页面的时候,可以看到他客户端的IP在整个情况下因为对URL的调用产生了30秒的时间,这30秒的时间大概花在哪里?
可以看到在这个服务里面在这行代码因为.NET对本地服务操作消耗了很长时间,这样就可以知道这次用户选择商品慢是因为.NET的操作慢。
我们就可以根据这条信息去优化.NET的操作。
场景三、订单提交失败 (Network~Server) [HTTP]
再去看另外一个场景,订单提交失败,这是一个很严重的问题,关系到钱的问题,我们通过这样一个全景图去看到在全国范围内的情况,颜色越重就说明时间消耗越长,用户体验越差。老板看到这个图会非常不高兴,为什么在这么多地区都出现了这样的问题。
那么问题来了,在所有的请求里面大致的分布是什么样的?所有的请求里面有绝大多数是处于60秒以下的,但一些极端的情况下超过了120秒,120秒是不可以忍受的,所以我们能不能知道这120秒到底消耗在哪?
在这样的一个事物流程里面包括登录、商品选择、订单提交,我们会发现在订单提交最后一步出现了问题,而导致整个订单失败。在订单提交里面其实是调用了一个URL,响应时间大概是27秒,这27秒我们怎么样去做分解?
我们将这27秒做分解以后发现,又是数据库的问题,我们还是想知道这个数据库到底执行了什么样的语句,这里面就可以知道数据库是因为查询了一个表的操作导致的。
这个时候有了这个表可以看到执行计划是什么,这个表是不是因为单表的数据量过大,而导致了整个请求的拥塞,这就是在订单处理的时候出现问题我们如何查找这个问题原因的过程。
场景四、用户信用检查故障 (Server~Server) [JMS]
我们现在都在提数据流,我们在处理数据流的时候会使用MQ做这种消息处理负载,在处理消息字节上的等待时间出现问题也会对用户体验造成影响。因为消息没有处理完,所以信用检查也没有处理完,导致整个消息没有回传过来,所以用户的信用检查就卡在这儿。我们来看这个消息检查他做了什么样的操作导致延时会这么长?比如说他是因为调用了另外的一个支付网关的服务,而这个支付网关给他的响应很慢,当然这里面是我们模拟的一些数据。
支付网关接入如果是支付宝、微信导致了我在整个订单的过渡中出现了问题,我们就可以跟支付宝,微信的团队去沟通,为什么这个接口这么慢,在这里我们会看到因为在这个消息解析的时候,他访问了一个支付网关出现了问题,而导致了整个的清理检查的失败。这就是整个场景里面对于我们刚才这个问题的一个解答。
下图是我们实际能够抓出来的一些逻辑拓扑。
除了这些大面积的拓扑,它的单一拓扑也在一定程度上会帮助我们快速的定位这个问题,比如刚才说login.NET这样的接口,它调用了JDBC的拓扑,这是单一用户请求下的一个拓扑,这样也能快速的解释是不是因为DB出现了问题而导致了整个服务出现了问题。
案例大概分析完了,我们今天主要讲的是全栈溯源,全栈溯源是通过不同的接入方式去看,一旦其中的一个用户出了问题,我们要看到服务与服务之间调用出现了问题,还是说是因为DB出现了问题,或者是数据库响应不够及时。今天的分享还是全栈溯源的最初部分,我们希望将来能够做到我知道你登录某个电商用户名,我希望能够查到这个用户名下的全部链路过程。讲的有点快,大概整体内容就是这样,谢谢大家!
Q&A
Q1:我想问一下那个数据时间是怎么来的?
杨金全:这一点刚才尤勇老师也讲了,其实大致的原理都是一样的,我们通过做自动的埋点。有一些对于数据库的操作,我们做埋点去看这个执行方法是什么样的,。
Q2:这些埋点的代码是在哪呢?
杨金全:对于实现原理来说我们针对不同的语言有不同实现方案,比如说Java,我们对自解码进行简单的修改,我们认为有一些可能引起性能问题的方法,去做嵌码追踪。对于PHP可能是正引擎的扩展,对于.NET可能就是一个HTTP。
Q3:我的问题主要是调用链串联,调用链串联比较困难的是在于异步调用,这种问题一般怎么去解决,特别是商业级的产品。还有一个难点就是可能跟一些业务模型有关系,比如请求,比如它有些分摊引擎,这两边数据过来自己去做处理,这种模型一般怎么处理?
杨金全:您的第一个问题就是如果是线程内部的,线程与线程之间总会出现一个线程,我们将线程之间相关的东西作为一个关联点,将两个异步线程怎么关联起来的问题。MQ也是我们近期做的一个尝试,MQ里面其实也是允许一些HTTP的,它类似于DB请求。