codecamp

云端监控和移动测试释疑——对话Just.me工程副总裁Kevin Nilson

作者 Sai Yang ,译者 刘君

云端监控和服务器管理区别甚远。在2013上海JavaOne大会上,just.me工程部副总裁Kevin Nilson讲述了云端部署的必要措施,其中涵盖一些AWS平台管理操作时的注意事项。

InfoQ就云端监控和服务器管理的具体差异、差异相关的应对方案以及app监控和移动测试的必备知识等方面内容采访了Kevin。

InfoQ:Kevin你好,很高兴你能来。你今早就云端监控做了讲演。那么就你看,从现有服务器向AWS迁移时,监控方面的最大不同是什么?

Kevin:云端部署会面临很多挑战,其中之一是确知特定时刻正在运行的服务器数量。系统规模会自适应调整,因而无从知晓到底有多少服务器在运行,亦无从知晓这些服务器的性能如何。这会是一种挑战。

另一个特定的挑战在于,云服务建立在商用硬件之上。云中一切共享,但每台服务器并非完全相同。很可能新启动的实例会比你先前使用的实例慢很多。

你要学会以不同的监控粒度查看API性能,一些情况下视整个服务为一体,另一些时候以服务器为性能查看的基本单元。有时,你大致了解API调用的执行流程,却发现本次调用的性能远低于预期。遇到这种情况,你可以试试删除当前实例并重新申请。毕竟,没有人会愿意为远低于应得的性能付款,而这种情况虽不常发生但确实存在。

许多人——我曾和Pinterest的首席工程师谈过,他们也曾遇到过同样的问题。我还知道Netflix的那群人在这一研究领域做了不少调研,而我们会继续保持对该领域的关注。

还有一件有意思的事情在于,使用云服务时,你常常会终止实例,而终止意味着完全终结。你会失去一切,包括各种日志以及其他类似物。这是另一种挑战。

云端部署的其他挑战源于服务器管理。在just.me我们使用Graphite,一种类似Ganglia的工具。配置特定数量的服务器实例并不困难,你可以用Graphite对这些服务器进行监控,并以拉模式收集运行时信息。这也是此类工具最常见的用途。不过,在云端使用拉模式意味着每次新实例添加都必须重启Graphite,重新配置并重启服务器。这显然不合适。

或许你可以试着换个角度。不是让服务器监管所有运行时实例,而是打破常规,让全部运行时实例了解到监视服务器的存在。这样,数据会被运行实例推送给负责汇报的进程,而不是汇报进程从服务器上主动获取。

我认为这是云服务的极大进步。行动前确定方向并考虑清楚,将很大程度上简化我们想做的事。

InfoQ:你在演讲中曾提及AWS CloudWatch会有5分钟的时延。

Kevin:诚然,AWS为监控提供了很多基础技术。CloudWatch十分出众,它提供了一些基本的警告和通知,并帮你监测一些基础属性,像CPU和网络流入/流出。CPU是我很关注的一点。

CloudWatch的问题在于,借助Amazon提供的基础监控技术,你无从获取应用相关的更深入细节。它只能让你查看诸如服务器状态、网络流入/流出等基础属性。

这是一个好的开端,但实用价值不大。试问,CPU0%代表什么?一切运转正常,还是应用服务器崩溃?可能为最好情况,也可能是最坏结果,而你,对实际情形一无所知。

CloudWatch本身存在不足。试着对其中的部分加以完善,你确实很想监测特定服务及其运转性能,对么?Yammer Metrics是我力荐的一种工具。它可以为你提供定时器,表和直方图,更重要的是,它能让你注释代码,让你监测任何API的运转性能及调用频率(每分或每秒的调用次数),这些信息唾手可得。

这在一定程度上迈出了提供服务相关信息的第一步。但问题在于,你真正想了解的是运行趋势。知道服务运行了400毫秒意义并不大。昨天是仅仅用了20毫秒,还是800毫秒?是服务已步入困境,还是性能有了飞跃?诚然,你无从知晓。

因此,我在just.me借助Graphite获得所有执行信息相关的图表,并与昨天、上月的情况进行比对,进而分析其运行趋势。这样,在软件版本大更新时,我就能从商业运作和系统运维两个维度出发,分析更新是否会影响性能和访问人数。Graphite带有一项十分便捷的设置服务,用于帮你迅速上手并熟悉Graphite。我们对这项服务非常满意。

其后的挑战在于监测各服务性能,并在故障发生时推送电子邮件或SMS以示提醒、通知。我用一款名为Nagios的工具,它非常出众,你可以通过对配置文件的简单修改来定义什么情况下你愿意得到“嘿,问题将至”的警告,什么情况下真正遇到了问题。

挑战的关键在于,你想在问题发生前未卜先知。先知往往会让分析变得简单。但毫无疑问,对顾客而言,故障永不发生更值得期待。

关于just.me的预测分析和全面监测,我所做的最后一件事是,Graphite向你提供了每次监测一项服务的一系列工具。也许你能一次观测五个服务,或是一次观测所有服务,但我更希望看到行为和趋势展望。

Square团队开发了开源软件Cubism。它能在屏幕上实时显示大量数据并推断出运行性能。它最吸引我的地方在于,很多情况下单个服务带来的问题会蔓延至整个应用。可能你会先收到某项服务持续10分钟低效运转的警告,再一段时间后,整个系统非正常运转。警告能帮你剥离出问题根源,关注最初发现问题的服务并在某种程度上引导你更快地接近问题根源。而尽快找到根源才能尽快恢复运转。

InfoQ:在那么多的监测量度中,你如何选定适合你的量度?

Kevin:的确有很多重要量度值得关注。你想监测CPU,若要同时关注成千上万事件,可以考虑创建仪表盘,有了它,各类状态一目了然。有CPU运转状态,也有实例运行情况。

监控中最难实现却又必须完成的功能是主动请求。获取哪些API发起主动请求和请求的确切数目的相关信息是最具挑战性也最具价值的事之一。若是访问量很大,当某项服务开始出现问题时,完成相关任务会更耗时,从而带来主动请求数量的上升。总体看,这非常非常有趣,特别是使用Java时,线程池大小固定且每项服务独占线程,一次API调用挂起就能引起整个服务崩溃。避免单个线程带来的服务崩溃十分重要。

很多服务并不关注性能。其中,主要区别在于信息取送时机。当你向服务器传送信息时,几乎可以肯定,后台进程是异步的。如果用户对究竟发生了什么一无所知,那么势必无从得知服务时耗。获取信息或是下载时,用户等待几乎是必然。下行量度中,用户性能体验更重要。

上传,发布信息,就商业角度而言更重要。我们监测各类社交行为,他们何时发布信息,发布多少信息,赞、评论和其他行为,关注人群。我们对这些事件的数目感兴趣,而商家并不关心用户刷过多少次屏。这就像一种博弈。你要了解获取时性能,而商家更关注提交。

Cubism很有用。决定哪些量度应一目了然时,它会是一个好的选择。通过展示顶部紧紧相靠的三色标注,Cubism在最小空间内让一切一目了然。我能以此在屏幕上监测尽可能多的量度并使之在更远处可见。

这更多是从操控角度而非商业角度。从商业的角度讲,你只需紧盯着你想要达成的核心目标就好。

我的仪表盘比起登录时约有30%的变动。我们将那些以往认为会发生问题但实际并未发生的量度移除。而另一些预料之外的量度被排放在办公仪表盘显眼的位置。

InfoQ:仪表盘保留了哪些量度?

Kevin:我会关注CPU。CPU信息与监控密切相关,我把所有MySQL CPU,EC2服务器CPU,Lucene CPU以及Neo4j CPU放在一起。它们都显示一个0到100间的数值,超过75%到80%时,会发生灾难。当我一眼看去,发现没有超过50%的,就会很放心。我并不关心每个CPU的具体数值,这种压缩可以使屏幕容纳更多信息。

我关注负载均衡器,确定顺利运转的实例数量不为0。我也关注主动请求并确定没有出现API峰值。

我关注DynamoDB,对于它,我想谈两点,我并不喜欢为DynamoDB读单元设定的收费方式。在我看,这种方式是非云的。它不会自动调整。基本上,你说,“我愿为100读单元支付”。一旦这100读单元用掉了,系统就开始拒绝返回结果,抛出异常。即便只需要10个,你也要为100单元支付。若是有一个白天活跃但夜晚清静的网站,你会面对不间断的重新配置。我常会惴惴不安于是否有任何一个服务达到了读单元的阈值,届时它将停止显示数据,而你将陷入大麻烦。这真的非常糟糕。

他们为Dynamo配置了CloudWatch,但使用不便。在just.me我们有很多很多量度,要立即打开浏览器监测CloudWatch的所有数据几乎不现实。这也是为什么我要在Graphite的基础上构建自己的工具来集成信息——那些需要上百浏览器方能显示的信息,我像对待CPU一样把他们整合在一张表中。监测读写单元时,我会划定一条基线作为阈值,超出阈值的就是有问题的。

仪表盘中还有什么?我曾排放过很多安全层相关的东西。每次请求都需要通过JAAS安全机制并确认是否授权,而早期的授权机制有过一些问题,那些曾被排放在仪表盘的顶部、前部还有中心,若通过安全验证耗费了10s,那其余部分的网站性能将不再重要,你必须先修正这一部分,不过现在这些都已解决。那些量度已经过时,并从仪表盘中销声匿迹。

我还把公开的工单数目加入报告中,如果被公开的工单数目很大,也许意味着你在这方面的监控是有漏洞的,所以我在仪表盘中安排了监测公开的工单数目的地方。

为了激发职员的士气,我也放入了一些市场量度。我能监测到系统新注册了多少设备以及这些设备发送了多少消息又收到了多少回复。这些信息主要是出于激励团队的目的。我希望仪表盘能吸引他们的目光,让他们对此好奇进而注意到更多其他方面。我们将仪表盘安置在办公室,放在一块很大的屏幕上,所有开发者都能看到。休息时,人们站在监视器下方,好奇而兴奋地谈论这些信息。

InfoQ:就iOS和Android应用的性能而言,你会重点监测哪些量度?

Kevin:当开发者同时开发维护Android, iOS或是移动HTML5三个版本时。作为一款响应式应用,移动HTML5常常是我们的选择,HTML版在最初向用户介绍应用时可以避免安装。也许有人会和他们分享信息,而他们会得到一种很棒的本地化体验,并宣布“哇,我想安装完全版并继续使用”。

得到高度关注的三种客户端后,你会希望找出其间的差别,从商业维度观测其运行,并确定哪一版本带来更多的流量。最大的挑战之一是找到安装来源。那些来到应用商店并开始安装的用户,是从哪来?又如何得知?也许我们做过大范围的广告推动,为广告投入了很多资金,但这真的有效?投资回报又如何?或许是我们博客上的文章带来了很多访问量,又或许我们应该更贴近那些潜在商机者,以期达成目标。

在just.me,我们并不直接将引导用户去应用商店,我们会向用户展示HTML5绘制的网页,即just.me/gettheapp。让他们去gettheapp,那儿Google Analytics会告诉我们用户如何得知该产品。我们常在尾部添加查询字段,just.me/gettheapp?src=TechCrunchArticle或是just.me/gettheapp?src=emailcampaign。从而根据量度确定最成功的推广途径。HTTP头部中的URL引用也非常管用。我们试图尽量平衡应用商店和gettheapp间的访问。毫无疑问这很有效。

至于其他移动监控的用具,最初我们选了Flurry。这种工具天生适合移动领域。我们把它用于iPhone和Android。它能告诉我们人们的手持设备型号。如果马上关注Android版just.me,你会发现,我们支持1500多种设备。我不可能命令QA,“去测试1500种设备”或是“随机挑选一种进行测试”。我们希望发现并购置用户真正用到的那种设备。

我们支持1500种设备,但公司里只有10到15种独立设备。我确实对开发者施加过不少压力来让他们购置和市场使用者接轨的个人手机。是否流行对我们而言很重要,因为,只有这样QA才能侧重关注人们真正在用的设备。

几周前索尼设备上出过问题,应用上架后我们发现索尼用户无法发布信息。之前我们从未购置过索尼设备。我们曾在百余人中做过beta测试,有意思的是,他们中没有人用索尼。反正就是没有人报告问题。不过,产品发布的第一天,我拨通了索尼热线,让他们尽快送来一台Xperia。我们拿到了机器,并在20分钟内做出了修正,然后上架应用商店。

Android的碎片化问题着实烦心,但能在一个小时内修正并上架,这很神奇。苹果应用商店上架前经常需要近五天来审核新版本。

Android带来的另一好处是风险转移。Google Play在今年的I/O大会上宣称有alpha和beta版本面市。在just.me应用发布经历三阶段:alpha,beta和成品。Alpha版本面向那些我很熟悉的人,比如我的酒友们,他们也能在手机上调试应用。如果我想上市新产品,并觉得存在风险,我会在alpha阶段停留几日。让熟悉的人试用,看看运行状况。这样,即便发生了可怕的错误,也没什么可担心的。

接下来是beta。这一版本面向那些登录过网址,并称“嘿,我对你的产品很有兴趣,我很期待上市的那天”的参与者,也许会有几百人,我们通过Google+小组进行管理。我把应用分发给他们,这一阶段发生错误也许不太好,但并非灾难。由于产品尚处于beta阶段,应用商店中无法评分。你肯定不想因为发布过早而获得1星评论。这一阶段Android已经做出很多真正值得开发者关注的工作。

就前面提到的索尼案例而言,我们采取的措施是马上登录应用商店使其不支持所有索尼设备。若是有手持索尼设备的人进入商店,它会被告之“你的设备还未被支持。稍后再来”。我们将索尼设备下线了四天来等官方承诺的送货日期。然后,我们完成修复,并将索尼设备重设为支持态。应用商店当真带给你很多便利。

在Apple平台上进行发布时很有意思的一件事在于如何进入编辑推荐区。Apple希望推荐时能看到你为产品引入很多特色。他们并不提倡每星期提交代码。不被推荐的最好方法是每周都向顾客推出新功能。而理想情况是一年发布三到四次。

当你完成一项特性的开发,你会很想立刻将其发布出去,认为这会挽救你的公司,带来商机,闭合下行困境而使相关指数上扬。但我们需要忍,因为要多攒点新特性一起发布才能上编辑推荐区。这很痛苦,却无疑是移动领域成功的关键。

回到Flurry的使用。最近Google Analytics发布了新更新Universal Access。Universal Access回归到Android和iPhone的本质,让你能做移动分析。此前,他们为JavaScript提供API。

我们用Google Analytics替代Flurry来获取量度,但获取数据前你必须真正理解Google Analytics。一般职员并不会去获取Google Analytics的各类数据。市场上只有真正想找到数据的人才能得到这些,而普通开发者并不会闲逛并宣布“噢,我洞察到了”。这不会发生,没有人会愿意让他们耗费那么久,因为标签,动作或是值集的获取并不容易,甚至看上去设计得非常不人性化。

我们开始使用另一样工具Mixpanel。这是一家初创企业发布的付费工具,我在JavaOne讲演中并未提到。它相当友好。API有点像Flurry,但更擅长同期群分析和路径分析。你能观察到是谁做了这些,是否还有其他人在做,你能找到那些使用产品一周以上的长期用户。基本上,它更关注长期的客户分层而非单纯统计值。

举一个简单的例子:如果有人以每周一次,每天五次的频度注册并登录应用,你能得到一个多少人仍在使用的大概估计。第一周,可能高达100%或90%,第二周,也许80%,下周70%,你希望在50%或其他目标上保持稳定。若半数的人还在,你想知道最终是否会下降到0。是否有忠实用户。一般而言,新人进入时,只关注统计器会让你很难分辨这是新人还是老用户;Mixpanel在这方面做得很好,它允许你关注关联事件,如消息回复或类似事件。

InfoQ:好的,最后一个问题,在面临很多工具(自己动手、参与开源项目、采用可信的第三方服务,如graphite, nagios, jmeter, yammer metrics, New Relic等等)可选时,你会如何抉择?最主要的影响因素是什么?

Kevin:我常关注是否已有现成的解决方案。我会先从开源工具中选取。开源工具的一大好处在于,若是存在痛点,将会是很多人共同的痛点,他们会尝试修复,若尚未修复,我会亲手完成。曾发生过很多次我或同事修复痛点的情况,我们编码回馈发起者。真的很像一块踏脚石,你打下桩,其他人帮你完善。

Picasso是源于Square的一款我非常喜欢的程序库。在just.me我用Picasso来载入图像。我已经向Square提交了一些功能请求。我还拥有为功能或其他东西投票的权利。对just.me而言,这很实用。我真的不愿意为缓存和图像载入编写所有需要的代码。

我常常关注开源,但开源并非次次有效。有时会没有足够的人对这一问题感兴趣。有时会需要你启动自己的开源项目。以我在E*TRADE工作时为例,我想测试应用如何在所有浏览器中运行,我想用Jenkins做持续集成。没有人那样做。我发起并为Jenkins完成了具备相关功能的插件。很多人开始贡献补丁、修正和各种很棒的功能需求。

很多次,开源方案并不完全适合你的需求。就像我对Graphite所做的,我需要一个仪表盘,他们的仪表盘做得很用心,但很难做出契合需求的修改。我并不认为在他们的仪表盘上再进行改进来契合需求可行,所以我在他们所提供原始图表基础上创建了自己的仪表盘。Graphite图表的自由度令我叹为观止,但我发现仪表盘有不足。所以我用自己的工具开发出一个更灵活的仪表盘。

我也会关注一些商用软件。商用产品在满足需求又不需过多个性化定制的情形下能帮你节约时间和支出。涉及业务核心时从零开始构建的确是正确的选择。你想和其他产品有足够的区分度,你想完完全全控制。具备资本时,你可以力挺开源项目。然而,当那些东西作为你的业务核心时,你不该总从开源入手。

如果你需要比较高级的功能,比如JVM调优,这时候你会发现在整个开源界里找不到能够同时做分析和调优的项目。人们并没有足够的时间和精力将之投放到开源世界。我认为New Relic已经做得很好,所以我们选择了跟New Relic合作。

Kevin Nilson是一位Java Champion,曾三次获得JavaOne Rock Star称号。Kevin在JavaOne, Devoxx, JAX, O'Reilly Fluent, Silicon Valley Code Camp, JAX, HTML5DevConf, On Android, NFJS SpringOne and AjaxWorld等会议上做过讲演。Kevin是Web 2.0 Fundamentals的作者之一。 他曾在San Mateo大学当助教。Kevin拥有Southern Illinois大学的计算机硕士和学士学位。Kevin是Silicon Valley Java User Group, Silicon Valley Google Developer Group和Silicon Valley JavaScript Meetup的领跑者。

查看英文原文:Interview with Kevin Nilson on Cloud Monitoring and Mobile Testing

查看原文:云端监控和移动测试释疑——对话Just.me工程副总裁Kevin Nilson

虚拟专家座谈会:迈向云开发
基于AWS技术实现发布/订阅服务
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }