freelogic's blog

2016-03-11-信息系统实践手记2-客户端启动速度调优思路

信息系统实践手记2-客户端启动速度调优思路

说明:

正文:

  • 信息系统实践手记系列是系笔者在平时研发中先后遇到的大小的问题,其中比较典型的内容加以收集和分享。
  • 信息系统实践手记目录:博客园(或查看源码的README.MD文件)

摘要:

  • 分享调优的个人经验,以及客户端启动速度调优的一个具体实例(本文可能需要读者具备一定基础)。

正文

1. 什么是调优?

实践中遇到很多同事很热衷于发现,某某模块启动太慢,处理太慢,需要调优。然后找来某个框架或者类库,用上试一试,发现有改善,于是欣喜。
这特别好,积极性是大家最喜欢的,但真正的调优其实是很复杂,这里分享个人的少量看法。

问:怎么算一个软件模块已经很优秀了? 
答:四个字"收放自如"。

能充分发挥(吃掉)硬件资源:如CPU/内存/网络带宽/IO;如果不限制,甚至能升到95%或更多,把硬件用足;
能按需调节硬件资源占用比:针对各种硬件资源(CPU/内存/网络带宽/IO)既能发挥到极致,又能按需消减占用,比如CPU不能超过75%;
受控/敏感/稳定:模块要充分受控,通过配置文件或额外信令能很好控制;而且要对控制响应快,快速调整到位;长时间稳定运行;

原则可能是:正确性>稳定性>韧性>敏捷性

解读:正确是必须的,否则无意义;正确后要长时间稳定的正确表现则需要稳定;稳定后要讲究资源占用的灵动变化,贴合要求,这是韧性,很难;最后是敏捷性,要快速反应,就像特种部队的快速响应,那就比较完美了。

问:什么时候软件模块需要调优?
答:很简单,没有达到上述“收放自如”的模块,就有调优的余地。说明原来开发没有做“足”。

问:什么时候不应该调优?
答:
能硬件升级的不调优:如增加CPU/MEM/磁阵/带宽等硬件资源的,尽量不要软件调优。这样最经济实惠,一般情况下是划算的。
不搞清楚业务模型和压力模型就不调优:对一个软件模块,如果都不了解清晰其业务模型(场景模型),主要功能,以及针对他们的压力模型,你怎么知道你的模块不达标呢?虽然你的模块按照上述要求,没达到客观的“收放自如”,但主观上也许已经达到产品经理的要求了,那就不建议优化。
没有好的审计手段不调优:要找到瓶颈或权重问题,经常需要测试和计量,比如做业务的时间消耗分析等。在做这些的时候,如果遇到困难,千万不能盲目去尝试优化,要科学和理性。所以必须要有一个可重复测量和审计软件模块运行情况的手段。没有手段,妄谈优化,但实践中往往大家很喜欢猜测,因为猜测容易。
不找到权重问题不调优:即便找到了一堆问题,但根据二八原理,只有找到核心问题,占比重大的权重问题,最重要问题,才需要先解决它。其他次要的问题可以记下来,千万不要因为容易,顺手先做次要问题。否则容易引入了额外的变化(比如新BUG),影响对核心问题的解决。
不成熟的框架不使用:有些同志经常喜欢尝试各种新鲜的类库,这对拓宽知识面是好的。但是新框架不成熟,行业地位不稳定,社区资源不丰富,这都不利于使用它。一般建议采用主流成熟框架,排名前三,社区资源充分,案例较多,功能专著于某领域。不建议尝鲜。
人力经验不足不调优:调优很耗人力,考验广泛的知识面和经验积累,如非准备充分,不要轻易尝试调优。有时候找到一个专家来优化一周,比投入5个普通开发折腾1个月还有效率。
不熟透软件模块就不调优:调优时必须对软件模块的细节烂熟于心,经验必须足够,否则一群不了解的人,即便是专家,妄谈优化。
还有更多惨痛经验,不一一列举,大家要慎重决定。

2. 具体到某个细节比如“调优客户端的启动速度”,怎么弄?

具体调优的过程肯定不简单,但还是愉快的,“痛并快乐着!”。举例供参考。 就拿手记1“信息系统实践手记1-列表数据展现的6个要素”中提到的一个包含地图(GIS)业务的客户端来说。

客户端软件结构:
客户端用C#的WPF框架开发GUI界面;
底层VC是业务功能引擎,它供WPF上层界面调用;提供比如播放视频(StreamPlay)等功能函数;
WPF的GUI界面层还嵌入了IE的OCX控件,控件中跑JSP代码,以便调用提供JS接口的各种GIS引擎(百度/公安PGIS/第三方);
所以C的代码(C#)和JAVA/JS代码(JSP)的,都和后台SERVER交互,获取信令和数据(因不同场景和应用而有差异)。
信令:一般指信令协议,无论是国家标准GB,或国际标准如SIP,或私有定义的协议,他们主要为了让不同平台或软件模块做沟通,数据量一般不大,多为传递核心数据诸如“设备列表”,“用户账号权限”等等;
数据:特指数据量较大的内容(针对视频应用),一般指视频信息,音频信息,或者交换的大量信息主体。以示对信令的区别;

客户端启动过程:
初始化界面并等待用户账号密码登陆;
客户端W从另一视频平台A拿来它管理的设备列表;
客户端W从GIS地图引擎平台B拿来地图资源(资源通过IE的OCX控件中JS接口展现);(一般是非矢量的点阵方块地图瓦片资源)
客户端W的WPF/GUI层执行自己初始化逻辑并和后台C沟通;
客户端W的JSP层执行自己的初始化逻辑并和后台C沟通;
登陆完成,界面稳定;
就这一个过程来说,其实很简单。但也可以说复杂,因为涉及到三个平台(A,B,C)和W交互,涉及多种信令,多类数据传递。
既有同步的信令接口,它需要暂停代码执行等返回值再继续;
也有异步的信令接口无需中断当前代码运行就马上返回,但需事先设定回调函数或回调机制等待异步回调再处理。
实践中发现客户端启动到登陆完成,整个过程比较慢,比如2万个设备从A平台同步过来,然后从B平台获取GIS地图资源,再和的后台C交互,最终呈现并稳定,用了2分钟,用户觉得很慢。
当然,用户可以有自己想法(无论是否合理),但搞研发的人还是要先调查,再客观分析判断,确定调优思路。

调优过程简单描述:
针对W和A平台交互过程P1:在A和W之间两端抓包,分析出来两边印证结果,分析时间/信令/数据情况。(有时候和第三方系统对接,不两边抓包对方会否认!)。
针对W和B平台交互过程P2:在B和W之间两边抓包分析如上。(如对端无抓包条件,那也只能先抓自己侧做分析)
针对W和C平台交互过程P3:在我客户端W(JSP和WPF是逻辑上独立的两块)和我后台C之间两边抓包,同上分析。
得到三个基本独立的过程P1,P2,P3,分析后,发现P1较慢,且慢在A平台,于是让A优化接口,实测有提升,两边实测P1提升了速度;
但结合P2,P3,总体还是较慢不达标,继续分析。发现P1,P2,P3互相不依赖(独立),从原来串行改为并行处理,让三个过程并发,提升了不少速度。
原因:一般开发人员按照自然习惯,总是顺序(串行)开发功能,做完1,2,3,再做4,5,6,并无时空概念,这是一大问题。
解决:通过引入适当的框架;或者经常做时空性能分析,理解业务的串并特性(这考验研发人员思维);或者持续重构优化;

从2分钟提升到30秒登录,但用户还是不解渴。其实P1,P2,P3三者取最长的P3是30秒,额外开销是5秒内暂时不计。
大流程P1,P2,P3已经并发运行,无可优化。但发现最长时间的P3过程中,W本地启动时总感觉太慢,不正常。
找到底层协议栈的负责人仔细code review,发现很久未修改过的底层信令协议栈,在其初始化中居然自动做了一个不必要的高层业务逻辑,额外消耗了10秒,这是不应该的。
较为底层的协议栈不应参与高层业务逻辑,它只需要为上层提供功能就可以了!修改后提升了速度到20秒。
原因:协议栈不会经常维护,开始做的时候也许不一定是高手或牛人,有些问题很隐蔽,短期不影响使用,在大数据量大压力下才能发现问题。也可能是后续图方便,为实现某个功能,不恰当的引入了BUG。
解决:协议栈必须标准化;尽量用成熟框架;尽量在初期多设计研究分析定型(各种使用者和各个软件模块多多参与);研发组织要有核心team维护核心代码(包含协议栈);

优化上还有很多细节(比如更细致的拆分了JSP/JS的异步更新等内容)不再详述。
用户还是不解渴,说最好10秒,且同意并要求你缓存所有必要数据,允许数据因为缓存而不同步!
那我们自然同意。我们从技术上说明了,当前模型和数据量,10秒启动是合理的,如要提升,就要权衡和牺牲。
同意用户的建议,将数据持久化到本地,启动能更快,但是数据的新鲜度(及时性)肯定会降低,有可能需要引入额外的同步刷新机制,这是一个平衡,完美的解决方案并不存在,合适就好。
最后,用户也同意了我们最开始就提出的提升硬件的要求,购买了I7六代的超级台式PC,进一步提升了(网络和对端凭他以外的本地过程)速度,这是硬件提升性能的好例子。这要看用户的预算了。
 

说明:本文涉及的所有专有名词,包括协议名,软件名等,皆来自于网络信息,仅供参考,如涉及版权等问题,请及时联系作者处理。

END