博客:O1高地


大规模服务设计部署经验谈(上)
大规模服务设计部署经验谈(下)




5 发布周期及测试

  在生产环境中进行测试是一件很现实的事情,必须成为所有Internet 级服务所必须的质量保证方式之一。在尽可能( 可以掏得起钱)的情况下,绝大多数服务都应当有至少一个与生产环境相似的测试实验室,并且所有优秀的工程师团队应当使用生产级的负载,以反映现实的方式测试服务器。不过,我们的经验是,这些测试实验室即便模拟得再好,也绝不可能百分之百的逼真;它们至少总是会在一些细微的方式上和生产环境有所差别。由于这些实验室在真实性上接近生产系统,因此相应的费用也呈渐进趋势,在部署互联网级大规模服务时,有关依赖管理和发布周期及测试方面的经验和最佳实践在本文中得以体现。新的服务发布版本可以顺着标准单元测试、功能测试和生产测试实验室测试一路走下来,一直进入受限的生产环境作为最后的测试阶段。

  快速逼近生产系统的开支。与此不同,我们推荐让新的服务发布版本顺着标准单元测试、功能测试和生产测试实验室测试一路走下来,一直进入受限的生产环境作为最后的测试阶段。显然,我们不想让无法正常工作并给数据一致性带来风险的软件进入生产环境,因此这就不得不小心翼翼地实施。下面的原则一定要遵守:

1. 生产系统必须有足够的冗余,以保证在灾难性的新服务故障发生时,能够快速地恢复到原来的状态;

2. 必须让数据损坏或者状态相关的故障极难发生(一定要首先通过功能测试);

3. 故障一定要能检测得到,并且开发团队(而不是运营团队)必须监控受测代码的系统健康度;

4. 必须可以实现对所有变更的回滚操作,并且回滚必须在进入生产环境之前经过测试。这听起来有点让人心惊胆战。不过我们发现,使用这个技术实际上能够在新服务发布时提升客户体验。与尽可能快地进行部署的做法不同,我们在一个数据中心中将一个系统放到生产环境数天。随后在每个数据中心内把新系统引入生产环境。接着,我们会将整个数据中心带入生产环境。最后,如果达到了质量和性能的目标,我们就进行全局部署。这种方式可以在服务面临风险之前发现问题,事实上还可以通过版本过渡提供更优秀的客户体验。一锤定音的部署是非常危险的。我们青睐的另一种可能违反直觉的方式是,在每天正午而不是半夜部署。在晚上部署,出现错误的风险更高,而且在半夜部署时如果有异常情况突然发生,那么能处理这些问题的工程师肯定会少些。这样做的目标是

  为了使开发和运营团队与整体系统的互动最小化,尤其在普通的工作日之外,使得费用得到削减的同时,质量得到提高。对于发布周期和测试的最佳实践包括:

5.1 经常性地交付。

  经常性地交付。直觉上讲,人们会认为更频繁地交付难度要更大,而且会错误频出。然而我们发现,频繁的交付中突兀的变更数量很少,从而使得发布的质量变得更高,并且客户体验更棒。对一次良好的发布所进行的酸性测试,用户提供可能会有所变化,但是关于可用性和延迟的运营

  问题的数量应当在发布周期中不受改变。我们会喜欢三个月一次的交付,但也可以有支持其他时长的论调。我们从心底认为,标准最终会比三个月更少,并且有许多服务已经是按周交付的了。比三个月更长的周期是很危险的。

5.2 使用生产数据来发现问题。

  使用生产数据来发现问题。在大规模系统中的质量保证,是个数据挖掘和可视化的问题,而不是一个测试问题。每个人都必须专注于从生产环境的海量数据中获得尽可能多的信息。这方面的策略有:

l 可度量的发布标准。定义出符合预期用户体验的具体标准, 并且对其进行持续监控。如果可用性应当为99%, 那么衡量可用性是否达到目标。如果没有达到, 发出警报并且进行诊断。

l 实时对目标进行调优。不要停顿下来考虑到底目标应当是99%、99.9%还是任何其他目标,设定一个可以接受的目标,然后随着系统在生产环境中稳定性的建立,让目标渐进式地增长。

l 一直收集实际数据。收集实际的度量,而不是那些红红绿绿的或者其他的报表。总结报表和图像很有用,不过还是需要原始数据用来诊断。

l 最小化“ 假阳性(falsepositive)”现象。在数据不正确时,人们很快就不再关注它们。不要过度警报,真是很重要的,否则运营人员会慢慢习惯于忽略这些警报。这非常重要,以至于把真正的问题隐藏成间接损害常常是可以接受的。

l 分析趋势。这个可以用来预测问题。例如,当系统中数据移动的速度有异于往常的时候,常常能够预测出更大的问题。这时就要研究可用的数据。

l 使系统健康程度保持高度透明。要求整个组织必须有一个全局可用且实时显示的系统健康报告。在内部安置一个网站,让大家可以在任意时间查看并了解当前服务的状态。

l 持续监控。值得一提的是,人们必须每天查看所有数据。每个人都应当这么做,不过可以把这项工作明确给团队的一部分人专职去做。

5.3 在设计开发上加大投入。

  在设计开发上加大投入。良好的设计开发可以使运营需求降到最小,还能在问题变成实际运营矛盾之前解决它们。非常常见的一个现象就是组织不断给运营部门增加投入,处理伸缩问题,却从没花时间设计一套伸缩的可靠架构。如果服务一开始没有进行过宏伟的构思,那么以后就得手忙脚乱地追赶了。

5.4 支持版本回滚。

  支持版本回滚。版本回滚是强制的,而且必须在发布之前进行测试和验证。如果没有回滚,那么任何形式的产品级测试都会存在非常高的风险。回复到先前的版本应该是一个可以在任意部署过程中随时打开的降落伞扣。

5.5 保持前后版本的兼容性

  保持前后版本的兼容性。这一点也是至关紧要的,而且也前面一点关系也非常密切。在组件之间更改文件类型、接口、日志/ 调试、检测(instrumentation)、监控和联系点,都是潜在的风险来源。除非今后没有机会回滚到之前的老版本的可能,否则不要放弃对于老版本文件的支持。

5.6 单服务器部署。

  单服务器部署。这既是测试的需求也是开发的需求,整个服务必须很容易被托管到单一的系统中。在对于某些组件单服务器无法实现的地方(比如说一个对于外部、非单箱的可部署服务),编写模拟器来使单服务器测试成为可能。没有这个的话,单元测试会的难度会很大,而且不会完全覆盖到实际条件。而且,如果运行完整的系统很困难的话,开发人员会倾向于接受从组件的角度看问题,而不是从系统的角度。

5.7 针对负载进行压力测试。

  针对负载进行压力测试。使用两倍(或者更多倍的)负载来运行生产系统的某些小部分,以确保系统在高于预期负载情况下的行为得到了解,同时也确保系统不会随着负载的增加而瓦解。

5.8 在新发布版本之前进行功能和性能测试。

  在新发布版本之前进行功能和性能测试。在服务的级别上这么做,并针对每个组件这么做,因为工作负载的特征会一直改变。系统内部的问题和降级现象必须在早期捕获。

5.9 表象性且迭代地进行构建和部署。

  表象性且迭代地进行构建和部署。在开发周期中早早地把完整服务的骨架先搭建起来。这个完整服务可能几乎做不了什么,也可能在某些地方出现偏差,但是它可以允许测试人员和开发人员更有效率,而且也能让整个团队在一开始就从用户的角度进行思考。在构建任何一个软件系统时,这都是一个好方法。不对,对于服务来说这尤为重要。

5.10 使用真实数据测试。

  使用真实数据测试。将用户请求和工作量从生产到测试环境分门别类。选择生产数据并把它放到测试环境中。产品形形色色的用户,在发现bug 的时候总是显得创意无穷。显然,隐私承诺必须保持,使得这样的数据永远不会泄漏回到产品环境中,这是至关紧要的。

5.11 运行系统级的验收测试。

  运行系统级的验收测试。在本地运行的测试提供可以加速迭发的健康测试。要避免大量维护费用,这些测试应当放在系统级别。

5.12 在完全环境中做测试和开发

  在完全环境中做测试和开发。把硬件放在一边,在专注的范围内测试。作重要的是,使用和在这些环境中的生产条件下同样的数据集合和挖掘技术,以保证投资的最大化。■(中结束)


6 运营和功能计划

  要高效地运营服务,关键在于让构建的系统有效地消除运营团队的绝大部分管理交互。这样做的目标,是让一个高度可靠的24 x 7 小时运行的服务,由一个8 x 5小时工作的运营团队就足以维护起来。

  不过世事难料,一组或者多组系统救火不成,无法恢复上线的事情是时有发生的。在熟知这些可能性的情况下,实现把损坏的系统标为当机这个过程的自动化。依赖运营团队手动更新SQL 表或者使用特别的技术移动数据,都会招致灾难。与故障交战正酣时,往往错误也容易迭出。先预估运营团队需要采取的补救措施,然后预先编写和测试这些过程。一般来说,开发团队必须将紧急恢复措施自动化,而且他们必须对之进行测试。显然,百密一疏,并非所有故障都能预估到,但通常一小组恢复措施就可以用来恢复多种类型的故障。从根本上说,要构建并测试可以根据灾难的范围和性质以不同方式使用及结合的“恢复内核”。

  恢复脚本应当在生产环境中进行测试。这里有一条普适规则,即如果没经过频繁测试,什么程序都无法正常工作,因此不要实现团队没勇气使用的任何东西。如果在生活环境中测试风险过高,那么脚本就没有达到能在紧急情况下使用的标准,或者说在紧急情况下不安全。这里很关键的一点是,灾难总是可能发生的,由无法按预期结果运行的恢复步骤所导致的小问题酿成大灾难的例子是屡见不鲜的。要预见到这样的事件,设计出自动化措施,让服务回复正常状态,而不至于丢失更多数据或损耗更多正常运行时间。

6.1 让开发团队承担责任。

  让开发团队承担责任。Amazon也许是沿着这条道路贯彻得最坚定最矢志不渝的公司了——他们的口号是“你创建就该你管”。这样的立场也许要比我们会选择的更坚定一些,但这显然是一个正确的大方向。如果不得不频繁在深更半夜给开发团队打电话,那么你就得做出一套自动化方案。如果需要频繁给运营团队打电话,那么通常的反应就是要增加运营团队的人手。

6.2 只进行软删除。

  只进行软删除。绝不要删除任何东西,只可以把这些东西标记成删除状态。在有新数据进入时,即时将请求记录下来。每两周(或者更长时间)保存一份所有操作的历史记录,可以有助于从软件或者管理上的错误进行恢复。如果有谁犯了错误,忘记在delete 语句加上where 子句(这样的错误以前发生过,以后也可能再犯),那么数据的所有逻辑拷贝都会被删除。不管是RAID还是镜像都无法防止这样的错误。具备数据恢复的能力,可以让原来会十分令人窘迫难堪的大问题转化为一个小到甚至可以忽略不计的小障碍。对于那些已经做过离线备份的系统,只需要从上次备份开始记录进入服务的附加数据就可以了。不过谨慎起见,不管怎么说我们还是推荐进行更进一步的备份。

6.3 跟踪资源分配。

  跟踪资源分配。了解性能规划的额外负载所带来的开销。每个服务都需要开发出一些使用的度量标准,例如并发在线用户数量、每秒用户访问数或者合适的标准。不管度量标准是什么,在这个负载度量和所需的硬件资源之间肯定存在一个已知的直接相互关系。估算的负载数字应当由销售和营销部门提供,并在性能规划过程中为运营团队所使用。不同的服务会拥有不同的变更速率,也要求不同的订购周期。在我们开发过的服务中,我们每90天更新一次市场预报,每30天更新一次性能规划和订购一次设备。

6.4 每次变更一样东西

  每次变更一样东西。在出现麻烦时,应当每次只向环境应用一个变更。这条准则看起来显而易见,但我们也看见过许多场合里出现多个变更,导致起因和效果不能吻合。

6.5 使所有资源都可以配置。

  使所有资源都可以配置。在生产环境中,任何存在变更需求的资源,都应无需经过任何代码改变,就能在生产环境中进行配置和调优。即使你没什么好理由说明为什么某个值会有必要在生产环境中更改,只要实现起来没什么难度,还是让它可变更好些。不应在生产环境中随意更改这些开关,而应该使用为生产环境所规划的配置对整个系统进行彻底测试。不过,在出现生产环境问题时,比起编码、编译、测试再部署代码变更的过程,进行简单的配置变更永远是更加简单、安全和快速的。


7 审核、监控和预警

  运营团队不能在部署环境中装配服务。要在部署过程中付出实质性的努力,以确保系统中的每个组件都可以生成性能数据、健康数据和吞吐量数据等。

  在任何有配置变更发生的时候,都必须在审核日志中记录详细变更内容、变更人和变更时间。在生产环境出现异常时,第一个要回答的问题就是最近到底进行过哪些变更。离开了审核跟踪,那么这个答案就是“什么都没被改过”,而且情况往往会是,被人们忘掉的就是引发问题的变更。预警是一门艺术。人们总是倾向于对所有事件都做警报,因为开发人员认为这些事件可能值得关注。正是如此,多数服务的第一版通常都会产生长篇累牍的无用预警,结果再也没

  有人去理睬。要提高效率,每个警报都得说明一个问题,否则运营团队会慢慢学会对这些警报置之不理。进行互动慢慢跳出需要警报的条件,保证所有关键性事件得到预警,以及在无需采取应对措施时没有警报。除此之外,要实现正确的预警别无灵丹妙药。要得到正确的预警标准,有两条度量标准很有用,也值得尝试:

  一、警报和实际故障比(同时要设定一个较为接近的目标);

  二、没有相应警报的系统健康问题数量(并设定一个近于0的目标)。

7.1 对所有资源进行检测。

  对所有资源进行检测。测量通过系统的每一次用户交互或事务,报告异常情况。尝试“运行器(人为的工作负载,用来模拟生产环境中用户和服务的交互)”也是可以的,不过这还远远不够。如果只是单独使用运行器,我们发现需要花费数日才能检测到一个严重错误,因为运行器的标准工作负载也会被继续良好地处理,接下来还要再花几天才能查出原因。

7.2 数据是最有价值的资产。

  数据是最有价值的资产。如果没有充分理解正常的操作行为,那么要对非正常行为做出响应就不是件容易的事情。我们需要汇集许多系统内发生的事件信息,才能知道系统是否真的正常运行。许多服务都经历过灾难性故障,而只有电话铃响起的时候,人们才意识到故障的发生。

7.3 从客户的角度看服务。

  从客户的角度看服务。进行端到端的测试。虽然单有运行器不够,但还是需要它们来保证服务器的完整运行。保证例如新用户登录这样重要的复杂过程经过运行器的测试。避免误警,如果在某个运行器上的故障没被当作重要故障,那么变更测试对象,换到是重要故障的运行器上。重申一下,一旦人们开始对数据视而不见,真正的损失就会让人们措手不及。

7.4 检测是生产环境测试所必不可少的。

  检测是生产环境测试所必不可少的。检测是生产环境测试所必不可少的。要在生产环境中实现安全的测试,就有必要进行全面监控和预警。如果某个组件开始出现故障,就必须快速检测出来。

7.5 延迟是最棘手的问题。

  延迟是最棘手的问题。缓慢的I/O,以及尚未出现故障但处理缓慢的现象,都是很好的例子。这些问题发现起来很困难,所以一定要仔细检测,保证这样的现象可以检测出来。

7.6 要有足够的生产环境数据

  要有足够的生产环境数据。为了发现问题,数据是不可或缺的。在早期就要建立细粒度的监控机制,否则放到后面再翻新成本就高得多了。

我们所依赖的数据中最重要的包括:

l 对所有操作使用性能计数器。至少记录操作的延迟和每秒钟的操作次数。这些数值突然出现的此消彼长现象,是一个十分危险的信号。

l 审核所有操作。每次有人进行操作之后,尤其是那些明显的操作,一定要记入日志。这样做有两个目的:首先,可以对日志进行挖掘,找出用采取的操作类型(在我们的例子里是用户查询的种类);其次,一旦发现问题,这样做有助于调试问题。相关视点:如果每个人使用相同的账号管理系统的话,这么做带来不了多少好处。相反这是一个非常糟的办法,不过这种情况不多。

l 跟踪所有容错机制。容错机制会把故障隐藏起来。每次出现重试、某个数据被一处复制到另一处,以及机器或者服务重启这类现象时,都要进行跟踪。要了解容错机制在何时隐藏了小故障,这样就可以对这些小故障进行追溯,以防其变成大面积故障。我们曾经碰到过这样一个问题:一个跨2000台机器的服务在几天内慢慢地瘫痪,最后只剩400 台机器可用,而一开始这个问题却没有发现。

l 跟踪对重要实体的操作。为某个特殊实体的所有重要操作记录一份“审核日志”,不管这个实体是一个文档,或者一组文档。在运行数据分析时,常常能在数据中发现异常现象。要了解数据的来源及其经历的处理过程。到了后期才往项目加入这样的功能是非常困难的。

l 断言(asserts)。不要吝惜断言的使用,而且要贯彻在整个产品中。收集因此产生的日志或者崩溃转储(crashdump),并进行调查研究。对于在同一个进程边界内运行不同服务并且无法使用断言的系统,要写下跟踪记录。不管哪种实现,都要能够对错误进行标记,频繁挖掘不同问题的频率。

l 保留历史记录。历史性能和日志数据对于趋势的总结和问题的诊断都是非常必要的。

7.7 可配置的日志功能。

  可配置的日志功能。对可配置的日志功能提供支持,这些日志记录可以有选择性开启或关闭,以便进行错误调试。在故障过程中,如果不得不部署带额外监控功能的新构建版本是非常危险的。

7.8 外部化健康信息,用于监控

  外部化健康信息,用于监控。考虑能实现外部监控服务健康程度的方式,并使对生产环境进行监控容易实现。

7.9 保证所有报告的错误可以应对

  保证所有报告的错误可以应对。问题总会发生,系统也总会出错。如果在代码中检测到无法恢复的错误,并且在日志或者报告中归为错误,那么错误信息应当指出错误可能发生的原因,并提供修复的建议。无法采取应对措施的错误报告毫无用处,而且时间一久这些错误报告会像“狼来了”一样被人们忽略,那时候真正的错误就可能被错过。

7.10 启用生产环境问题的快速诊断。

  启用生产环境问题的快速诊断。

  为诊断提供足够信息。当问题被标出时,要提供足够的信息,人们才可以对其进行诊断;否则门槛会非常高,标注也会被忽略。例如,不要只说“10个查询都没返回结果”,还得补上“列表在这里,还有问题出现的次数”。

  证据链。保证存在一条贯穿始终的路径,可供开发人员诊断之用。通常这都是由日志实现的。

  在生产环境中的调试。我们偏爱这样的一种模式:系统没有被包括运营团队在内的任何人触碰过,并且调试是通过镜像快照、内存转储并将所得数据发送到生产环境之外来实现的。当生产环境成为唯一选择是,开发人员就是最好的选择。要确保开发人员得到良好的培训,知晓生产环境的操作限制。我们的经验是,系统在生产环境中动的次数越少,客户通常也越开心。因此我们推荐,一定要多努一把力,尽量避免接触生产环境中的系统。

  ◇ 记录所有重要的操作。每次系统执行了重要的操作,特别是对网络请求和数据修改上,要进行记录。这既包括用户发送命令的事件,也包括系统内部的行为。有了这样的记录,调试问题的时候就会获益无穷。更重要的是,还可以开发出相应的挖掘工具,用来找出有用的集合,比如用户的查询都是什么样的(也就是说,用了哪些关键字,有多少关键字等等)。


8 优雅降级和许可控制

  当发生DoS攻击或者由于用户使用模式变化而带来的负载激增时,服务器需要能实现优雅降级和管理控制。例如,911恐怖袭击发生后,大多数的新闻服务都发生瘫痪,无法向所有用户群体提供任何可用的服务。与此相比,如果能够将一部分文章可靠地提供给用户,总比什么都不能提供好。最佳实践有两种:“大红开关(big red switch)”和许可控制,如果能够针对服务进行量身定制,作用将会十分强大。

8.1 支持“大红开关”。

  支持“大红开关”。这个概念最初来源于Windows Live Search,它拥有很大的权力。我们对这个概念进行了一定程度的推广,更事务性的服务与搜索差别迥异。不过这个想法非常有效,而且可以应用于任何地方。一般来说,“大红开关”是当服务已经或者即将无法满足SLA时,采用的一个经过精心设计和测试的措施。将优雅降级比喻成“大红开关”稍微有些不恰当,但核心意思是指在紧急时刻卸掉非关键的负载。“大红开关”的主要思想是保证关键任务的运行,同时卸掉或者延迟非关键的负载。从设计角度来说,这种情况应该不会发生,但在发生紧急情况时不失为一个好的救火办法。在紧急情况已经发生之后再来考虑这些问题是十分危险的。如果有哪个负载可以被加入队列并延后处理,或者在关掉高级查询后仍能继续运行事务系统,那么这都是作为“大红开关”的理想对象。关键在于,判断在整个系统出现问题时有哪些任务是必不可少的,然后实现并测试在问题出现时关闭非关键服务的选项。切记“大红开关”必须是可逆的,也就是说当紧急情况解除后,必须保证开关能正确地让所有的批处理工作和先前被停止的非关键任务恢复原状,这是应当经过测试的。

8.2 控制许可

  控制许可。许可控制是另外一个重要的概念。如果都无法对当前的任务进行处理,向系统引入更多的工作负载只会将不好的体验扩散到更大的用户群中。这要如何实现和系统有关,有些系统实现很容易,有些则比较困难。拿我们上次的邮件处理服务作为例子,如果系统超过负荷,开始排队列的话,我们最好是拒绝接受后续邮件进入系统,然后让这些邮件在来源处列队等候。这样做很有意义并实际上减少了整体服务延迟,主要原因在于一旦队列在我方形成,系统会处理得更慢。如果我们拒绝形成队列,吞吐量也会得以提升。另外一个诀窍是:重要客户优先于非重要用户,注册用户优先于访客(但如果是以吸引新访客作为商业模式的,另当别论)。

8.3 对许可进行计量

  对许可进行计量。还有一个无比重要的概念,就是前面所说的许可控制观点的修改方案。如果系统故障并当机,必须能够实现逐步恢复用户使用,并确保系统运行正常。比如先允许1 个用户进入,然后允许每秒进入10 个用户,随后再逐渐放宽限制。对于重新上线或者从严重错误中恢复过来的系统,应该确保每项服务都有一个细粒度的开关,来实现用户的缓慢增加,这是至关紧要的。大多数系统的初始版本中很少有包括这项功能。

  对于有客户端的系统,一定会存在一种方式,用来通知客户端服务器当机,并且告知可能的恢复时间。这样一方面使客户端尽可能继续基于本地数据来运行,另一方面也可以避免客户端打扰服务器,以便后者更快恢复。这样同时也给了服务拥有者一个直接和用户沟通的机会( 见下节),用来调整用户的期望值。另外一个关于客户端的技巧是刻意设置扰动(jitter),和自动备份来防止客户端在同一时刻“扑向”脆弱的服务器。客户和媒体沟通计划当系统出错时需要就发生的延误和相关事项与客户进行沟通。沟通应当能以可选的方式通过多个渠道完成 :RSS、Web,还有即时消息等等。另外,对于拥有客户端的系统,通过客户端来进行和用户的沟通也是很有效的。可以告诉客户端在一定时间内或者特定时间点之前避免访问服务器,或者如果支持的话,可以告诉客户端在离线和缓存的方式运行。客户端可以把系统状态告诉用户,并说明可以预计完整的功能在何时恢复。即使在没有客户端的情况下,比如用户通过网页来和系统交互,仍然可以告知用户系统当前的状态。当用户了解发生的状况并对系统的恢复时间有一个合理的期望值,他们的满意度会大大提高。系统管理员常常会不自觉地倾向于隐藏系统发生的问题,但是跟据我们的经验,我们确信,将系统的状态告知用户会极大地提高其满意度。即便是非付费系统,如果人们知道系统发生了状况并被告知其何时会恢复,他们放弃使用这项服务的可能性也会减小。某些事件会引发媒体报导。如果这样的场景有预先备好的应对方案,那么会更加真实地反应服务的情况。大量数据丢失或损坏、安全遭到破坏、违反隐私以及服务器长时间当机,这样的情况都可能引起媒体的关注。事先准备好一份沟通计划。清楚电话通知谁,并能主导谈话。沟通方案的框架应当事先搭好。应针对每一种事故制定一份沟通方案,内容包括该给谁电话通知、电话时间,还有如何掌控沟通过程。客户自预置及自助服务客户自己进行预置可以大幅度降低成本,同时还能提升客户满意度。如果客户可以访问网站,输入所需数据,然后就可以开始使用服务,那么他们要比不得不在电话处理队列中浪费时间开心得多。我们一直认为,主流移动运营商因为没为那些不想致电客户支持组的用户提供自助服务,错过了一次拯救并提升客户满意度的好机会。

9 结语

  要降低大规模互联网服务的运营成本并改善服务的可靠性,一切从编写服务时注重运营友好开始。在这篇论文中,我们为“运营友好”做了诠释,并根据从事大规模服务的工程师的经验,总结了服务设计、开发、部署和运营的最佳实践



10 作者简介

  James Hamilton,

  是微软LivePlatform Service团队的架构师,在微软有11 年工作经验, 此前他曾带领Exchange Hosted Service团队,该团队为超过两百万用户提供Email 相关服务。在微软的前八年,他曾是SQL Server 团队成员,并带领大部分的核心引擎开发团队。在加入微软之前,James 曾担任IBM 的DB2 UDB 团队的首席架构师,更早时曾带领团队交付IBM的第一个C++ 编译器。在20 世纪70 年代末、80 年代初,他曾持有汽车机械师和意大利汽车竞赛驾驶执照。
锐亚教育

锐亚教育,游戏开发论坛|游戏制作人|游戏策划|游戏开发|独立游戏|游戏产业|游戏研发|游戏运营| unity|unity3d|unity3d官网|unity3d 教程|金融帝国3|8k8k8k|mcafee8.5i|游戏蛮牛|蛮牛 unity|蛮牛