1.1 现代应用程序的需求
数字体验已经不再是我们生活中的一个配角,它们在我们日常生活中的许多活动中都扮演着重要的角色。这种普遍性已经超越了我们对所使用的软件的期望:我们希望应用程序总是可用的,能够不断地升级并提供个性化的体验。在软件产品从构思到实现这一生命周期的初期,我们就必须能够满足这些期望。而你作为一名开发人员,也是负责满足这些需求的其中一员。让我们先来了解一下关键的需求有哪些。
1.1.1 零停机时间
2015年9月20日的AWS停机,揭示了现代应用程序的一个关键需求:它必须始终是可用的。可以容忍应用程序出现短暂不可用情况的日子已经一去不复返了。世界是始终在线的。没有人希望计划外的停机出现,其影响已经达到了惊人的水平。例如,2013年《福布斯》估计,亚马逊在一次13分钟的意外停机事故中损失了近200万美元。[3]不管停机是否在计划中,都会导致收益和客户满意度的严重下降。
但是,维护系统的正常运行不仅是运维团队的问题。软件开发人员或者架构师对设计和开发一个松耦合、组件化的系统同样负有责任,应该通过部署冗余组件来应对不可避免的故障,并设置隔离机制来防止故障在整个系统中引起连锁反应。而且,还必须把软件设计成能够在不停机的情况下完成计划事件(例如,升级)。
1.1.2 缩短反馈周期
同样至关重要的是频繁发布代码的能力。在激烈的竞争和不断增长的消费者期望的双重驱动下,应用程序更新已经从每月数次发展到每周数次,有时甚至一天数次。让用户感到兴奋毫无疑问是有价值的,但是持续发布新版本的最大动力是降低风险。
从你对某个功能有了想法的那一刻起,你就承担了一定程度的风险。这个主意好吗?用户能接受它吗?它能以一种更好的方式实现吗?虽然你会尽可能地去预测可能的结果,但现实往往与预期不同。获得诸如此类重要问题答案的最佳方法,是发布一个功能的早期版本并收集反馈信息。利用这些反馈信息,你可以做出调整,甚至完全改变想法。频繁的软件发布不仅缩短了反馈周期,也降低了风险。
在过去几十年里占主导地位的单体软件系统,无法做到频繁地发布新版本。因为由独立团队构建和测试的各个子系统之间密切相关,所以需要把它们作为一个整体进行测试后才能够进入“脆弱”的打包过程。如果在集成测试阶段的后期发现了缺陷,那么这个漫长而艰苦的过程需要重新开始。为了实现将软件发布到生产环境的敏捷性,新的软件架构是必不可少的。
1.1.3 移动端和多设备支持
2015年4月,技术趋势评测和分析公司comScore发布的一份报告中显示,移动设备的互联网使用率首次超过台式计算机。[4]今天的应用程序需要支持至少两种移动设备平台(iOS和Android)和桌面系统(仍然占很大一部分使用比例)。
此外,用户越来越希望他们的应用体验随时可以从一个设备无缝切换到另一个设备上。例如,用户可能在Apple TV上看电影,然后在去机场的车上改用移动设备继续观看。此外,移动设备的使用模式与桌面设备的使用模式有很大的不同。例如,银行必须能够满足移动设备用户频繁的应用程序刷新需求,他们可能正在不断查看每周的薪水是否到账。
正确设计应用程序对于满足这些需求至关重要。核心服务必须能够支持所有为用户提供服务的终端设备,并且系统必须能够适应不断变化的需求。
1.1.4 互联设备(物联网)
互联网不再仅仅将人类与系统连接起来,如今,数以亿计的设备通过互联网连接,使得它们能够被连接的其他实体监控甚至控制。预计到2022年,仅家庭自动化市场,即使其在所有物联网(IoT)连接设备中只占很小的一部分,也将成为一个将近530亿美元的市场。[5]
联网的家庭拥有传感器和远程控制设备,例如,运动探测器、照相机、智能恒温器,甚至照明系统。这些设备都是非常便宜的。几年前,在-32℃的天气里,我的水管爆裂了,于是我用一个联网的恒温器和一些温度传感器搭建了一套简易的恒温系统,花费总共不到300美元。其他物联网设备还包括汽车、家用电器、农业设备、喷气式发动机,以及我们大多数人口袋里的超级计算机—智能手机。
物联网设备从两个基本方面改变了我们的软件的特性。首先,互联网上的数据流量急剧增加。数以亿计的设备在一分钟内多次广播数据,甚至有的设备达到每秒多次。[6]其次,为了收集和处理这些海量数据,用于计算的基础设施势必发生重大的改变。当计算资源被放在“边缘”位置,即更靠近连接设备时,它会变得更加分布式。数据量和基础架构之间的差异,需要新的软件设计和实践来解决。
1.1.5 数据驱动
根据本书目前为止提出的几个需求,你应该会以更全面的角度来考虑数据。数据量正在不断增加,数据源分布得更加广泛,而软件的交付周期正在缩短。综上所述,这三个因素使得大型、集中式、共享的数据库变得无法使用。
例如,一个装有数百个传感器的喷气式发动机,它会经常与数据中心的数据库断开连接,同时由于带宽限制,无法在建立连接后立即将所有数据传输到数据中心。此外,共享数据库需要在众多应用程序之间进行大量的处理和协调,以便满足各种数据模型和交互场景的需求,这是导致无法缩短发布周期的主要问题。
这些应用程序需要的不是单一的共享数据库,而是一个由更小的、本地化数据库组成的网络,以及能够在多个数据库管理系统之间管理数据关系的软件。这些新方法催生了从软件敏捷开发管理到数据层面的各种要求。
最后,如果没有人使用新的数据,那么这些数据就没有价值。今天的应用程序必须越来越多地使用数据,通过更智能的应用程序为客户提供更高的价值。例如,地图应用程序使用来自物联网汽车和移动设备的GPS数据,以及道路和地形的数据,来提供实时交通报告和路线导航服务。过去几十年的应用程序,仅仅通过精心设计的算法加以仔细调整来适应预期的使用场景,而现在它们正在被不断变化的新应用程序所取代,甚至这些新程序可能会自动调整内部的算法和配置。
这些用户需求—持续的可用性、频繁发布新版本以实现不断演进、易于伸缩和智能化,都是过去的软件设计和管理系统所无法满足的。但是,什么样的软件能满足这些需求呢?