我们是如何构建复杂软件系统的
如今,现代互联网软件应用已经成为一项需要很多人一起构建与维护的庞大工程。 我们是怎么构建复杂软件系统的呢?
一切源于对人类生存处境和现实问题的洞察和思考。 计算机溯源于大量科学计算的需求。起初, 通过硬件电路直接实现计算;紧随后,软件的编写替代硬件开始成为商业应用的主要解决方案;接着, 通信成为重要驱动力; 紧接着, 万维网与分享成为主流, 搜索引擎助力; 然后, 智能手机催生了移动时代的来临, 进而引起云计算和大数据的技术变革; 在云计算和大数据之上,构建智能精准的业务。
软件技术的重要里程碑
可编程: 使得硬件成为“百变天后”, 通过程序可变幻出多样的功能;
编译器: 使得程序员可以使用高级语言和接近自然语言的领域语言来表达现实世界;
结构与算法: 计算世界的基石, 现实问题的求解方案通常表达成高效的结构与算法;
操作系统: 计算资源分配与调度的核心, 使应用可以更加专注于任务层面;
数据库: 用户企业数据的有序存储、组织、统计; 几乎所有现代应用都依赖于数据库;
开发库: 使得日常任务及成熟方案可以通过几行代码反复使用,站在巨人的肩膀上,极大地提升了软件开发的效率;
应用框架: 使得构建现代应用可以直接从 40% 起步,甚至从 80% 起步;
中间件: 使得基础技术组件化和服务化,为大规模系统的构建提供了强大的基础设施;
运维独立: 当今大规模软件世界得以持久稳定运行的重要护航力量;
多样强大的开发工具,极大地延展了人的固有能力,即使几岁的小孩都有能力做出像样的应用;
结构化、函数式、对象编程思想继续引领编程领域,成为构建可扩展的复杂系统的思想基石;
开源自由软件运动,使得软件技术突破商业公司的壁垒,大量开源软件、技术博客分享成为技术学习与进步的天堂。
在基础软件技术支撑下,更高级而综合的技术及应用应运而生:
物联网: 移动设备充当连接万物的媒介, 联接人们所能触及的世界;
云计算: 硬件资源聚合重用,提供弹性而强大的基础计算能力,成为大规模软件世界的发电厂;
大数据: 通过数据分析挖掘提炼出智能、精准的未来业务,为企业决策提供数据支持,适配人们的习惯和个性;
人工智能: 让计算机学习人的认知和判断能力, 胜任非指令式的、需灵活自主调节自身的复杂场景的工作,成为可与人协作的小伙伴;
现代软件应用的挑战
现代软件应用通常源于解决一个有潜力的用户市场所面临的痛点问题;这个用户市场有一定规模,可以构建起基本的业务系统并生成一定规模的数据集;
软件系统的研发牵涉到对现实世界的认知和建模;
如何去认识行业领域以及业务?
如何理清纷繁的事物关联, 把握重要的主线,做好规划?
如何将业务层面的解决方案转化为技术层面的架构设计和实现?
如何将软件使用中遇到的问题转化为重要的驱动力并保持软件和企业持续长久运行?
从不同视角去探索这个答案, 会产生不同的解决方案、发展方向和执行路径,获取到不同的数据集。
企业要生存,多样化、灵活的业务是直接驱动力;业务可扩展能力和低维护成本是应对业务变化的主要法宝,软件因为业务的扩张和拓展而快速成长和变得复杂;此时的复杂是多样化的业务流程与规则导致的;
当数据流量达到现有技术能承载的临界规模时,性能、成本与稳定性就成为必要的内在驱动因素; 在海量互联网用户的时代更是如此;
以尽可能少的成本, 安全高效地驾驭海量数据,是恒常的非功能性需求;
因此,软件的复杂性通常是由业务多变的“质”与数据规模的“量”共同构成的。
软件的能力有"刚与柔"之分;
刚性能力体现在软件的性能:单位时间内处理多少请求,每个请求的响应时间,占用多少资源,请求处理的成功率等;
柔性能力体现在健壮性和可维护性: 健壮性使得应用更友好地处理错误,减少用户烦恼和困惑; 可维护性良好的软件才有健康稳定成长的潜力。
软件技术与工程实践
对于多变的业务,并没有通用的方案来解决,人们通常是通过模块化、组件化、服务化的方案将复杂系统分而治之;再辅以适当的设计模式、代码规范保证系统的可维护性和柔韧性; 海量数据规模的处理,催生了一系列可复用的实用技术。
技术是人们用于解决一类问题的整体框架方案和可行措施;
技术是软件开发的战车,帮助人们碾过荆棘,渡过长河,长驱直入。
并发与异步成为现代软件应用的基础技术;
分布式计算成为构建大规模互联网应用的主流技术;
缓存是提升查询性能的必备技术;
KV 系统用于不规则数据的存储;
尽可能减少数据不一致成为维护现代应用的主要挑战。
智能是未来的憧憬, 通过智能、精准的技术来适配人的行为特性;
实时搜索与调控能力在部分领域是重要的驱动力;
子系统之间的交互标准化规范化也是重要的组成部分; SOA, Restful 开始广泛使用;大型软件应用常常是依靠多个子应用相互协作而良好运转;
黑客与安全技术一直是最容易被忽视但决不可轻视的组成要件之一;
逻辑严密与测试工程自动化与规模化是必不可少的。当数据量级达到千万甚至几十亿级规模之后,即使很小的逻辑缺陷都会充分放大,变成很多的工单;十几的工单量算是客气的;这些必须在测试阶段尽可能地被消灭掉;核心和常用业务是不允许出现功能性BUG的,哪怕是极小的;
最后但也是非常重要的, 大规模的、敏捷的、稳定的、用户无感知的软件热升级、发布与部署技术是必不可少的; Docker 应运而生; 这需要与运维工程师紧密配合。
互联网软件已经渗入到每个人的生活,并且每个人都逐渐成为这个世界的参与者、贡献者;
产品经理是洞察人们处境和需求的先锋队,是产品成长的守护者; 项目经理组织协调资源,在可接受的成本下督导项目与产品的完成; 程序猿与媛是实现产品的主力团队; 视觉、交互设计做出人性化的交互展示效果,使产品更易用; 运维工程师保障软件日常的稳定运行和高峰期的正常运行; 客服同学为用户答疑解惑,帮助用户解决困惑和问题; 运营同学通过策划使得产品获得更大的效用; 行政、财务、HR 保障整个组织的正常运行; 销售同学将产品推向市场,开拓新的市场领域;普通的消费者用户成为软件数据的生产者和传播者。
人们从最初的“需求-分析-概要设计-详细设计-编码实现-测试-发布-反馈” 的瀑布流程, 演进到“用户故事-场景-测试用例-迭代-反馈”的敏捷流程;UML、系统时序图等用于描述系统特征与行为, 甘特图、燃尽图等用于描述项目进度; 思维导图用于规划系统与行动全景图。
结语
软件开发是一门幸运的学问。物理学为电子世界构建了可靠的硬件基础; 数学为计算机软件构建了严谨的理论基础;在两大源远流长的自然基础学科的肩膀上,借助分工、分层、重用、缓存、多核、分布式等技术机制,开源自由运动的"分享共筑"的理念和行动,以及产品技术人永不止步的精神动力, 构建起如今恢弘壮丽的软件天网。