一、前言
如今已既成事实的是每家公司其实都是软件公司,快速向客户提供新服务和新功能是公司的关键竞争优势之一。IT 敏捷性是有些初创公司能战胜巨头的基石。
对于以基础架构为中心的环境而言,其结果之一就是开发人员对自己代码的用途失去了感知力。产品的发布周期较长,而更改速度较慢。在开发人员完成相关工作后,代码将进入测试或运转流程,然后要在数月之后才能发布。由于前期准备时间长,工程师失去了作为开发人员的乐趣,也就是做出创造性工作并见证它在现实生活中发挥作用的乐趣。
数字化转型以及相关的文化和技术变革(例如 DevOps)所引发的巨变之一,就是重新带来了创建代码的乐趣。开发人员可以创建代码并实际看到运行。这是一种巨大的转变。使得代码创建的即时性得到重现。由于能实时查看应用,从而为开发人员员提供了一个反馈回路,藉此可以让他们重新设计和改进代码,并实现项目的快速推进。
二、数字化转型意味着什么
数字化转型是企业的一种战略性变革。促使公司在竞争压力发生变化或新法规出台时能够调整核心服务,在发现漏洞后可以立即推出更新。
但是,除了“改变现状”之外,还没有数字化转型的通用定义。数字化转型一词有时用于表示新的架构(如微服务)、新的流程(如 DevOps)或新的技术(如容器和应用编程接口(API))。数字化转型并不是某个能够实现的具体目标。这是一种每个企业都必须为自己量身定制的东西。
没有任何一个架构模式或技术平台可以完美地应用于各种环境。成功实现数字化转型需要清楚地了解企业目标和文化。关键点不在于专注某种模式或某项技术,而是从团队、当前技术债务及业务策略的评估入手,专心致志地按照既定方向将企业向前推进,最终得到想要的结果。
借助明确的目标和策略,无论现在处于什么状况,都可以不断克服困难(技术债务、设计缺陷等等),实现所设想的进化。这意味着您必须清楚地了解自己所要完成的任务以及与现实之间的差距。
三、注意房间内的大象
评估当前的技术前景并完善业务策略绝非易事,往往很难得到这种视角。有一个众所周知的寓言是 “盲人摸象”。故事的重点在于每个人都有不同的观点、有限的信息,以及基于上述观点的假设。这些不同观点所引发的结果说明了团队内部的内在沟通和关系⸺有些可以跳出自己的观点局限,有些则分崩离析。我们所看到的取决于我们是谁、我们在哪里、我们要寻找什么、我们知道什么,以及我们不知道什么。
任何采用传统应用(和传统团队)的企业,其房间内不止有一只“大象”,其中包括:
- 当前的团队结构和沟通模式。
- 开发、测试、构建和发布流程。
- 技术债务和现有的商用应用。
- 部门之间的目标或战略愿景不同。
这些都是大象,而每个利益相关者都可以从不同的角度看待这些大象。
四、数字化转型的达尔文进化论观点
不同类型的改变可能需要不同的基础性变革,有时可能还取决于文化和流程的改变。 罗马不是一日建成的,将数字化转型视为一个逐层推进、环环相扣的连续过程,可能会更具建设性。
1、DevOps 与流程改变
数字进化的基础是 DevOps。和业务策略一样,应用也体现了创建过程中团队及沟通的情况。DevOps(或类似的流程改变)让更多的利益相关者参与到开发讨论中,并提供了有关运营团队如何维护软件和基础架构(以及客户和合作伙伴如何实际使用这些应用)的深入见解。
DevOps 在团队之间建立了更紧密的反馈回路,并且需要开诚布公的交流。这种开诚布公的交流是其他演进阶段的基础。
2、自助式基础架构
该阶段是一种以技术为中心的变革,旨在引入通常与现代化技术平台相关联的高效率。容器和自助服务目录使开发人员、测试人员和运营团队可以快速启动一致的环境。在有些企业中,新实例的交付时间已从几天缩短到几分钟,而不是让技术人员等待几天。
3、构建自动化和编排
构建自动化涉及两方面的改变。从技术角度看,可以采用如 Kubernetes 等高级部署引擎,但也需要流程的改变。许多企业都围绕变更和风险管理制定了严格的流程。如果不对这些流程采用更敏捷的方法,就无法充分利用新的技术。
4、持续集成/持续交付 (CI/CD) 管道
持续交付就是承诺以快速、迭代的方式交付软件变更。管道的思路是:同时采用流程和技术手段,减少不良代码(或损坏的代码)从制作到部署的风险。它反映了先前步骤(DevOps 以及团队之间的开放式交流、围绕测试和构建的流程,以及自动测试与部署)的成熟度。待所有这些阶段都确定之后,就有可能快速推送代码。这就是管道。
5、高级部署路径
一旦用于快速部署的流程和基础架构就位,便可以使用部署系统来减轻更新所带来的任何风险, 评估功能的有效性,并为新想法提供实实在在的测试基础。这其中可以包括在部署过程中(蓝绿部署)采用独立的环境并在它们之间进行负载平衡,使用两个不同的环境来测试用户交互(A/B 测试),或向少数用户推出更新并安全地增加用户数量 (金丝雀发布)。
6、微服务(或分布式系统)
微服务是一种执行离散、功能单一的小型应用。整个应用架构可能需要执行数十个或数百个不同的功能,而且每一项功能都要在微服务中定义和编排。微服务架构(或任何分布式计算架构)既复杂又简单。单个服务更为简单,更易于维护、添加和停用,但总体架构却更为复杂。如果做法得当,“基于微服务的设计就会成为您所学优秀应用设计的最终体现”。这种高度分散型架构可以更轻松地进行扩展,更容易引入新的服务或更新,并且降低了系统范围故障的风险。
微服务是一种必需的状态吗?
鉴于维护的复杂性,数字化演进的最后阶段是微服务。但是,企业演进的最后阶段一定要是微服务吗?
未必。
如果演进的其他方面都到位, 那么单体式架构仍可以每周发布一次,并使用高级部署技术、CI/CD 和分布式可扩展基础架构。只有在团队规模较大且需要比按周发布更快的速度,或需要按不同的时间表进行发布时,才应考虑微服务。小型团队或小型代码库不需要分解为微服务代码库。
五、文化改变是前提
DevOps 将紧急、全力以赴式的工作方法转变为在团队规划、开发、测试和部署中实现更平稳、 更可持续的迭代。这是 DevOps 团队在效率方面实现天文数字式增长的原因所在。
值得注意的关键点是达尔文(软件)进化过程不只是技术的改变。流程和人员的改变以及基础架构的改变交替发生,而文化的革新更是首当其冲。
康威定律:“任何采用系统设计的企业,其设计结构最终都会不可避免地与该企业的沟通结构相一致。” 针对这方面,有两个彼此相关的解释:
- 除非也改变沟通结构,否则单纯改变架构或基础架构不会带来任何改变。
- 无论基础架构如何,改变沟通结构都会带来流程和基础架构的改进。
Gartner 实际上有这方面的数据:“有 90% 尝试使用 DevOps 、但没有针对性地解决自身文化基础的企业会走向失败。”
DevOps 是一种文化的转变,努力打破开发人员、运维团队和业务利益相关者之间的隔阂。这种隔阂是真实存在的,但也是人为造成的。一个团队中可以不止包含工作职能相同的人员。 DevOps 试图重新定义团队,将应用生命周期中涉及的每个人员都纳入其中,并在这些团队之间实现有效沟通。
文化上的改变是所有技术和流程改变的基础。 如果您更改了沟通方式,结果也会随之而变。一些重大更改有时是从非常简单的步骤开始的。
无论您的最终应用架构是更完善的单体式应用还是分布式微服务,都需要改变团队结构和沟通方式。无论是在规划应用前还是在部署应用后,都必须确保沟通的顺畅。除非建立并启用支持开放式沟通和反馈的文化,否则按照不同的服务来划分团队很容易造成公司分化成一个个孤岛。
六、应用架构设计:关注微服务
设计必要性、技术债务与策略选择
不知道该如何处理当前的应用,是企业变革的一大阻碍。这就是许多数字化转型计划考虑采用 “淘汰和替换”方法的原因之一;有些时候,重新开始似乎更容易。
但是,问题在于技术债务是设计的结果。在不清楚要替换什么的情况下拿掉一个应用,意味着同一个不被接受的架构最终还会再次出现。
您所开发的一切都是您的技术债务。对于非常新的应用,团队经常会在没有明确设计的情况下开始开发工作,这不一定是坏事。不过,也有观点认为,好的设计造就稳定发展,而没有设计则平淡无奇。
在开始规划架构之前,需要对战略重点和目标有非常清楚的了解。您必须确定客户或最终用户是谁,客户看重的是什么,期望的结果是什么,以及如何衡量成功。
- 谁是您的客户或用户?
- 他们想要做什么?
- 您使用什么基础架构?
- 该基础架构生命周期有多长?
- 单个工作流有哪些服务或功能需求?
- 该工作流的生命周期有多长?
- 您的部署路径是什么?需要多久部署一次?
- 这会影响哪些业务功能?
换句话说,不要一开始就想着如何完成某个任务或要使用哪种架构。要从战略目标开始,然后设计支持该目标的架构。
微服务和单体式应用
简单来说,单体式应用就是在单个应用中包含所有功能的应用堆栈。无论是服务之间的交互还是开发与交付方式,都采用紧密耦合的形式。更新或扩展单体式应用的某个方面也会对整个应用及其基础架构产生影响。
单体式应用存在的潜在问题是动态扩展和故障转移。这些问题通常可通过简单的扩展性设计来加以解决,例如横向扩展(在集群中复制该功能)或纵向扩展(镜像实例和扩展硬件)。开发和运维团队也很少考虑可扩展性问题。如果需要一个完整的 50 人团队每 6 到 9 个月发布一个单体式应用,那么通过让五个独立的团队提供五个较小的应用并每隔几周发布一次更新,即可提高可扩展性。
考虑到最初的简单性以及服务与依赖项之间的清晰关系,单体式架构可能称得上是最古老的应用架构。该架构也更能反映有限的、基于商品的 IT 基础架构以及更严格的开发和发布流程。 由于单体式是一种较为陈旧的架构形式,因此它们常常与传统应用相关联。相比而言,更为现代化的架构则尝试按功能或业务能力来拆分服务,以带来更好的灵活性。这在面向客户的界面(如 API、移动应用或 Web 应用)中尤为常见。这些界面通常较小,需要更加频繁的更新才能满足客户的期望。
分布式架构的最新定义之一是微服务。与其他模块化设计,像面向服务的架构(SOA)有一些相似之处,但微服务将服务之间的松散耦合转变为服务独立性。通常,单个服务的定义较为明确,可以轻松地在较大的架构中添加、升级或删除服务。这对于动态可扩展性和容错能力都有一定的好处:可以在不占用大量基础架构的情况下按需扩展单个服务,或者可以在不影响其他服务的情况下进行故障转移。
哪种架构模式最为合适。下意识的反应是认为新的总是最好的,但重要的是应退后一步,评估什么最适合您想要的业务成果。Etsy 和 Netflix 的工程师就微服务持续部署和开发人员自主权的必要性在 Twitter 上展开了一场友好的辩论。Etsy 的工程师指出,他们拥有小规模、 基于功能的敏捷开发团队,可在运行单体式应用的情况下仍实现超快部署(每天约 60 次)。他们找到了一种适合自己和企业文化的系统。
对于企业而言,问题不在于我们能否用微服务来取代单体式架构,而在于我们的战略目标是什么,为了实现这一目标我们需要做些什么。了解沟通结构和文化、业务功能以及所需的工作流程之后,就会影响服务的耦合方式、服务的生命周期,以及最终的应用架构。
有关分布式计算的错误见解
必须要重视有关微服务的错误见解,原因很简单:没有任何系统是完美的。这么做的目的不是要找到解决问题的完美技术(或架构)。相反,专注于文化和沟通并不断完善流程将有助于创建一个成熟、有效的组织体系。在这个基础上,企业才有能力设计满足特定目标的有效架构。
1、增加了成本和交易费用
对于真正的分布式计算,所需的基础架构更改可能需要大量的费用。此外,还要涉及重新培训、 学习新技能、调整团队结构以及迁移系统等间接成本。当然,这部分费用将来会改善一些指标 (如上市时间和停机时间的缩短(如果有效实施了新架构)),但这些好处并非立竿见影。
2、增加了复杂性
不像单体式架构那样只有单个(灾难性)故障点,微服务架构可能有数百个不同的潜在故障点。 与单体式架构类似,这些故障往往很难跟踪,因为根本原因可能并不那么明显。不过,微服务会增加额外的复杂性,因为服务之间的依赖性更不明显。 甚至更快的发布周期和更敏捷的团队结构也会增加复杂性。有效的沟通对于微服务而言至关重要。每个软件架构都要平衡内在的复杂性。这种复杂性可能隐藏在应用本身中(单体式架构), 也可能融于团队沟通结构内(微服务)。
3、系统化思维与设计
要设计有效的微服务架构,需要缜密的系统化思维。您必须了解服务、业务功能与用户体验之间的相互影响。这种系统化思维还必须扩展到企业文化中的沟通结构和流程层面。Gartner 指出, 在不了解整个系统的情况下,微服务架构的性能与刻板的单体式架构非常像:“如果不采用统筹考虑软件架构、开发基础架构和开发流程的整体化方法,则无法提供最佳结果,会继续遭受单体式软件系统的诸多弊端所带来的切肤之痛。”
4、资源限制
鉴于在扩展方面存在的问题,单体式架构的资源限制是显而易见的。系统要么有足够的硬件容量来处理繁重服务上的峰值负载,从而导致不必要的容量冗余,要么就会面对没有足够的容量来处理高峰期的风险。 借助微服务,架构将变得灵活自如,并且由于各个服务的规模都非常小,因此很容易在轻量级的临时资源(例如容器或云实例)上扩展新服务。 因为给定服务的单个资源需求相对较少,所以有时可以忽略整个架构的独特资源需求,或将其压缩到最小。当然,这是基于以下假设:
- 网络始终可靠。
- 无延迟。
- 无限带宽。
- 网络保持安全。
- 基础架构拓扑不会改变。
- 有一个管理员。
- 传输成本为零。
- 网络同构。
重新思考有意义的应用
很多有关数字化转型的讨论都是集中在基础架构和文化上。鉴于它们属于基本要素,这样做是有道理的。但是,基础架构和文化毕竟是“方法”,它对应的“目的”是创建一个对用户有用、与企业相关的应用。
有意义的应用具有以下特征:
- 可以响应用户
- 反映核心业务功能或商业目的
- 对环境的动态变化具有适应性或应变性
- 跨环境互联互通
- 轻便、灵活,可进行功能的添加和维护
当某个应用满足以上这些特征时,它就是一个有意义的应用。单体式和微服务架构都可以反映这些特征。
七、快速可靠的驱动技术
数字化转型的主要目标之一是加快应用发布速度。但是,速度只是效率的提高。要想实现转型, 速度还需要有一定的目的性⸺实现快速创新,交付新功能,以及检验新创意。
评估一个好创意的方法是进行全面、有效的测试,其中不仅包括代码质量,还包括用户体验和偏好。实践出真知。这正是持续交付和高级部署技术的目的。
CI/CD 是一个快速部署平台;部署技术则是进行实验和完善的工具。 这两个阶段背后则是文化的改变,即鼓励创新并支持失败和冒险。
自助服务、自动化和 CI/CD
在数字化转型中,最初的重构举措之一就是转向采用小型动态团队并倡导相互沟通的 DevOps 文化。接下来是技术方面,旨在提供一个支持快速开发周期的基础架构。
这里有两个密切相关的技术阶段:
弹性、自助服务式基础结构 ― 可以根据确切的规范近乎实时地请求和接收实例。
自动化或编排 ― 可以在整个环境中自动创建和管理多个实例。
这些技术具有互补性:没有弹性环境,也就无法实现自动化;没有工具来确保一致性和可重复性,也就难以管理数百个实例。弹性基础架构既可以是云(公共云或私有云)、虚拟机,也可以是容器。自动化既可以是基础架构系统中的组件,也可以是外部工具(例如 Kubernetes)。
容器之所以与 CI/CD 如此密切相关,原因之一就是它们都可以提供严格且可重复的系统环境,这也意味着在完全不同的企业环境之间迁移时问题会更少。
这种一致性为 CI/CD 的第一部分(持续集成)奠定了良好的基础。借助持续集成,可以在每次检入时不断编译和构建开发中的变更,因而更容易暴露问题。这项工作通常与自动化测试套件结合在一起,用于验证稳定性或功能性。检入、构建和测试所构成的连续过程可确保代码的更高质量。
一旦持续集成投入运行,企业即可实现持续部署,从而更快地将变更转化为生产。这种速度的提升既有利于开发人员,也有利于运维团队。
对于庞大的单体式架构(采用完善的流程和技术,以及更传统的应用架构),可以每周发布一次,且进行一次性整体更新,此时对敏捷冲刺流程的要求构成了唯一的约束条件。对于微服务,由于任何服务都可以进行更新,而且冲刺周期可以重叠,因此可以每天对整个架构进行更新。
高级部署和创新
用于实验的应用基础架构
多语言编程代表了敏捷开发环境的核心需求之一。创建实验用平台时,必须考虑开发环境的灵活性和有关的选项。实验用环境必须支持:
- 多种语言。
- 多个运行时。
- 灵活的部署环境。例如云环境、物理环境或混合环境。
- 灵活或可变的应用架构。让应用可在整个生命周期中适应环境的变化。
- 开放标准,或实现迭代标准化的能力。
容器就是这种支持的一个范例。
创新的部署模式
先进的部署技术能在结构和透明度方面实现创新。成熟的部署方法能够构建一个真正实现实验、 反馈和分析的环境。更好的实验有助于实现更好的创新。
这些是常见的部署模式。任何一种方法或全部方法都可能适用,具体取决于您的应用和用户环境的性质。
蓝绿环境
蓝绿环境是缓解因推广更改而带来的风险的一种方法。新的构建版本会穿过 CI/CD 管道中的所有环境。对于生产而言,有两个相同的环境(蓝和绿),但只有一个处于活动状态。所做的更改会被推广至生产中的空闲环境。然后,待环境完成验证后,将会切换路由并将流量移至已更新的环境。
金丝雀发布(Canary releases)
金丝雀发布与蓝绿部署类似,不同之处在于其初始发布只针对环境中的部分用户。随着从用户那里不断收集反馈,可以逐渐增加人数,直到最终切换至所有用户为止。
这可以用作测试技术的一部分,以针对当前生产环境中的一小部分用户,借助实际的流量和使用模式来评估应用的不同功能或设计。
A/B 测试**
A/B 测试将向用户展示两种不同的设计,然后根据所需的指标来评估哪种设计效果更好。既可以直接让用户对自己的体验进行评分或提供反馈,也可以用更加不易察觉的方式完成。例如,将 A/B 测试与金丝雀发布结合在一起,可以对比两种潜在的设计甚至隐藏的功能,然后以当前环境为基准评估用户对不同设计的反应。
如同金丝雀发布一样,一旦给出的设计取得成功,就可以将它发布到更大的环境中。如果一切进展顺利,还可以将生产环境转变为实验环境,这样团队在设计中就会更具创新性和关联性。
这种测试正是“数据胜过直觉”的核心所在。
八、如何教大象跳舞
1、选择现有阶段
在更传统的瀑布式环境与完全分布式的微服务之间,有很多阶段。因为数字化转型的目标是让文化、流程、架构和技术发生显著改变。这就意味着您要了解这种变更所要实现的目标,然后清楚地评估实现该目标所需的条件。请思考几个问题:
- 您当前有哪些团队或小组?
- 这些小组之间采用什么沟通方式?
- 规划周期内目前涉及哪些人?
- 从功能角度看,当前应用架构与目标应用架构之间有多大差距?
- 您的企业对风险或失败的容忍度有多高?
- 对自己材料和信息流的了解程度如何?(这是企业价值的体现。)
- 您需要多久发布一次更新,以满足客户或运营需求?
- 业务目标或开发需求需要哪些新功能?
2、制定操作规则
文化的改变是企业针对数字化转型所做的所有流程、技术或架构改变的基础。 尽管道理浅显易懂,但制定一系列得到管理层和不同团队支持的核心规则确实有助于强化数字化转型计划并统一队伍。
这些规则可能比较简单,但保持清晰明了的态度和行为却大有用处,而这些对于文化的改变而言最为重要,尤其是在其中一些态度或行为(例如鼓励冒险和实验)与当前文化背道而驰的情况下。例如:
- 失败不可避免
- 要敢于实验
- 企业(人员)优先
- 追求持续改进
- 终身学习
- 始终负责
- 保持透明
3、告别庞然大物
数字化转型会影响您当前的应用和架构。如果您现在采用的是单体式应用,则有两种相关的方法可以开始解决该技术债务:
- 在需要更新或替换时,中断现有服务(strangling)。
- 在另外的独立服务中创建新功能(starving)。
这些都不需要全面采用微服务。Gartner 建议将这种渐进式方法应用于分布式架构,因为它“迭代的同时专注于价值领域”。
无论企业数字化演进的最后阶段是什么,所选择的方法都应涵盖三个基本方面:
- 架构设计的敏捷性。
- 实验性。
- 自动化。
实现敏捷性设计架构
无论您的侧重点是简化流程以改进单体式架构的性能还是创建微服务,架构基础都必须具有敏捷性。通常,敏捷就意味着混合。
Gartner 建议新项目以单体式架构开始,待成熟后再推出微服务。Gartner 研究得出的结论:先采用单体式架构的方法可以降低风险、提高初始生产率,并确保将应用分离和分解为正确的微服务集。”
请认真阅读 Martin Fowler 的 DesignStaminaHypothesis,创建一个侧重于清晰性和简易性的开发流程。代码应做到易于理解。功能和用途要明确。随着应用不断成熟,就可以将其发展成更具分布特性的架构形式。拥有良好的开发和部署流程会让这一途径保持敏捷。
预留试验用的时间和预算
必须要留出试验新技术和应用功能的预算空间。技术本身并不是目标,但是,数字化战略目标经常需要技术变革作为支撑。缩短服务上市时间可能需要移至容器。 还要预留资源,让开发人员和运维团队可以识别有用的技术并培养相关的技能,以支持最终部署的任何基础架构。
一切皆自动化
自动化主要有两个明显的优势:通过消除手动步骤来提高效率,以及内在的一致性和可重复性。实现每个开发(开始时)和部署(随着流程不断成熟)步骤的自动化,也就是可就每个步骤的改变以及在利益相关者从开发向运营再向客户转换时为您的团队提供反馈回路。这种方法提高了整体代码质量。
第一步,为企业的当前状态设置一条基线,以将其纳入自动化策略。接下来的步骤包括:
- 定义相关指标。
- 可视化或图解当前的工作流。
- 确定不同步骤的主要参与者。
九、总结
长期以来,企业应用往往会演变成死板僵化的庞然大物⸺不够透明、更新起来繁琐,且迟迟无法纳入新的功能。然而,这些企业应用同时也提供了开展业务和实现创收的核心功能。这就像是房间里的大象。
只要对最终状态有明确的认识,就可以将那头大象训练得敏捷并且具备转变能力。数字化转型是个进化过程,没有一种所谓理想的结果,每条演变路径都反映了企业本身的独特意图和个性。
评估数字化演进的每个阶段:DevOps、自助服务或弹性环境、自动化、CI/CD 管道、高级部署和微服务。围绕最能满足您业务需求的进化阶段,构建自己的数字化转型策略。
聚焦于打造文化,并在技术变更与相应的流程变更之间取得平衡,以确保您的技术得到团队的全力支持。
随着流程不断成熟,开始评估您的应用和架构。必要时,隔离或开发独立的服务,并创建可以随着业务优先级变化或出现而调整的敏捷架构。
最后,培养创新能力。这意味着对风险和失败要有一定的容忍度(在业务目标和客户需求的范围内)。这就要求架构规范在时间、成本和基础架构方面预留出一定资源。
试验是创新的根本,也为数字化转型的成功提供了更好的机会。此外,试验也让人们重拾最初的喜悦,正是这些喜悦吸引着众多开发人员和运维人员热爱技术, 从事创造性工作并见证创新的产生。