阿里云云原生架构实践读书笔记.docx
《阿里云云原生架构实践读书笔记.docx》由会员分享,可在线阅读,更多相关《阿里云云原生架构实践读书笔记.docx(10页珍藏版)》请在冰豆网上搜索。
阿里云云原生架构实践读书笔记
第二章云原生架构的定义和原则
前面讲到,云原生架构是云原生中非常重要的一个技术领域,是帮助企业和开发人员改善应用的技术体系、降低现代化应用的构建复杂性、更好地适配与运用云计算平台的能力和体系的关键。
同时,云原生架构作为一种现代架构,其技术栈和范围也是随着不断发展的云计算及其服务的演进而动态演进的。
云原生架构的构建和演进都是围绕云计算的核心价值(例如,弹性、自动化、韧性)进行的,因此云原生实践在架构等方面必然有一定的原则和规律可循。
本章将抽象出阿里云原生架构的典型架构原则,并针对每个原则列举一些代表性案例,帮助大家更深入地体会和理解云原生架构及其构建方式。
2.1、云原生架构定义
从技术的角度出发,云原生架构是基于云原生技术的一组架构原则和设计模式的集合,旨在帮助企业和开发人员充分利用云平台所提供的平台化能力和弹性资源能力。
对比传统架构与云原生架构(如图2-1所示),可以清楚地看到两者的区别。
一方面,云原生架构可以最大化地剥离云应用中的非业务代码部分,从而让云设施接管应用中原有的大量非功能特性(例如,弹性、韧性、安全、可观测性、灰度等),使业务能够摆脱被非功能性业务中断的困扰,同时具备轻量、敏捷、高度自动化等特点。
另一方面,云原生架构可以通过与基础设施深度整合与优化,将计算、存储、网络资源管理以及相应的自动化部署和运维能力,交由云基础设施执行,应用自身会因此变得更为灵活,且具有弹性和韧性,从而大大降低管理成本。
下面就来详细讲解云原生架构所带来的相关优势。
2.1.1、降低研发成本和项目维护复杂度
首先,云原生架构大幅度降低了研发成本和项目维护复杂度
总的来说,任何应用都提供了两类特性:
功能性特性和非功能性特性。
功能性特性由为业务实现带来直接价值的代码实现,比如,如何建立客户资料、如何处理订单、如何安全支付等,即使是一些通用的业务功能特性(比如组织管理、业务字典管理、搜索等),也是紧贴业务需求的。
而非功能性特性是指虽不能为业务实现带来直接价值,但又必不可少的特性,比如,高可用能力、容灾能力、安全特性、可运维性、易用性、可测试性、灰度发布能力等。
图2-1展示了在传统架构和云原生架构中代码通常包含的三个部分:
非功能性代码、业务代码和三方软件调用。
在以上三个部分中,业务代码最为核心,能真正为业务带来直接价值,另外两个部分都用于支持业务代码的实现。
然而,由于软件和业务模块规模扩大,部署环境趋于繁杂,分布式复杂性增强等,为了应对这些变化带来的挑战,应用中的支持型代码在整个研发流程中的占比越来越大,这直接导致了软件构建变得越来越复杂,对开发人员的技能要求越来越严苛。
相较于传统架构,云原生架构强调业务研发应充分利用云平台所提供的IaaS和PaaS的通用能力。
虽然云计算不能解决所有的非功能性问题,但是云平台确实能够处理大量的非功能性问题,特别是分布式环境下的复杂非功能性问题。
以最具挑战性的高可用性为例,云平台在多个层面为应用提供了解决方案,具体说明如下。
(1)虚拟机层面
当虚拟机检测到底层硬件异常时,可以自动将应用热迁移,且迁移后的应用无须重新启动就具备对外服务的能力,应用对整个迁移过程甚至都不会有任何感知。
(2)容器层面
有时,虽然应用所在的物理机运行正常,但应用由于自身的问题(比如,出现Bug、资源耗尽等)而无法正常对外提供服务。
对于这种情况,如果采用容器,就能够通过监控探测到进程的异常状态,从而实施异常节点下线、新节点上线和生产流量切换等操作。
整个过程自动完成,无须运维人员人工干预
(3)云服务层面
云服务具备极强的高可用特性和7×24小时服务能力,如果应用把“有状态”部分(如缓存、数据库、对象存储等)全部交给云服务,加上进程内存中全局对象的持有小型化和应用快速重构能力(比如基于快照快速恢复到最新状态),那么应用本身就会变成更轻量的“无状态”应用,从而使可用性故障造成的业务中断时间降至分钟级;如果应用采用的是N-M对等架构模式,那么结合负载均衡产品则可获得几乎无损的高可用能力。
借助云原生架构,业务研发可以降低原本大量耦合的非业务逻辑占比,缩减业务代码开发人员的技术关注范围,并通过云平台提供的服务提升应用的稳定性和可持续发展性。
2.1.2加快软件迭代速度,降低管理和运行成本
具备云原生架构的应用,能够最大程度地利用云服务提升软件的交付能力,进一步加快软件的迭代速度,降低管理和运行的成本。
(1)面向单机资源变为面向云服务与云API研发
云原生架构对开发人员的最大影响就是,它使编程模型发生了巨大变化。
如今,大部分编程语言都包含文件、网络、线程等元素,这些元素虽然为充分利用单机资源带来了好处,但也增加了分布式编程的复杂性,因此市场上不断涌现出大量的框架和产品,意在解决分布式环境中的网络调用、高可用性、CPU争用、分布式存储等问题。
而在云平台中,“获取存储”变成了若干个服务,比如,对象存储服务、块存储服务和文件存储服务的访问和使用等。
云原生不仅为开发人员提供了解决上述问题的技术支持,而且通过OpenAPI及开源SDK,提供了解决分布式场景中的高可用性、自动扩缩容、安全、运维升级等诸多挑战的界面。
开发人员不用再关心诸如节点宕机后如何在代码中将本地保存的内容同步到远端,或者当业务峰值到来时如何对存储节点进行扩容等问题;运维人员也不用再考虑诸如在发现零安全天问题时如何紧急升级第三方存储软件等问题。
这些改变不仅降低了开发者的工作难度,也大大提高了软件的性能和可维护性。
云平台将软硬件能力升级成了服务,使开发人员的开发复杂度和运维人员的运维工作量都得到了极大降低。
可以预见,这样的云服务用得越多,开发人员和运维人员的工作就越轻松,那么企业在非核心业务实现上的支出就会从必须负担变得可控。
一些开发能力较强的公司,过去往往会将这些第三方软硬件能力的处理交给应用框架(或者公司自研的中间件),而在云计算时代,云平台提供了服务等级协议(Service-LevelAgreement,SLA),使得所有软件公司都可以从中获益。
开发人员不再需要掌握文件及其分布式处理技术,也不再需要掌握各种复杂的网络技术,技术栈的简化让业务开发变得更敏捷。
(2)高度自动化的软件交付能力
软件开发完成后,需要在公司内外部的各类环境中进行部署和交付,以将软件价值交付给最终客户。
公司环境与客户环境之间的差异,以及软件交付与运维人员的技能差异,都会影响软件交付的质量。
以往用于填补这些差异的是各种用户手册、安装手册、运维手册和培训文档,容器的出现改变了这一现状。
容器就像集装箱一样,以一种标准的方式对软件进行打包,利用容器及其相关技术屏蔽了不同环境之间的差异,提供了标准化的软件交付能力。
对自动化交付而言,还需要能够描述不同环境的工具,使得软件能够“理解”目标环境、交付内容和配置清单。
具体来说就是,通过代码识别目标环境的差异,根据交付内容以“面向终态”的方式完成软件的安装、配置、运行和变更。
基于云原生的自动化软件交付相较于当前的人工软件交付,是一个巨大的进步。
以微服务为例,应用微服务化以后,往往会被部署到成千上万个节点上,如果系统不具备高度的自动化能力,那么任何一次新业务的上线,都将带来极大的工作量挑战,严重时还会导致业务部署时长超过上线窗口期而不可用。
2.2云原生架构原则
作为一种架构模式,云原生架构通过若干原则来对应用架构进行核心控制。
这些原则可以帮助技术主管和架构师在进行技术选型时更加高效、准确,下面将展开具体介绍。
2.2.1服务化原则
在软件开发过程中,当代码数量与开发团队规模都扩张到一定程度后,就需要重构应用,通过模块化与组件化的手段分离关注点,降低应用的复杂度,提升软件的开发效率,降低维护成本。
如图2-2所示,随着业务的不断发展,单体应用能够承载的容量将逐渐到达上限,即使通过应用改造来突破垂直扩展(ScaleUp)的瓶颈,并将其转化为支撑水平扩展(ScaleOut)的能力,在全局并发访问的情况下,也依然会面临数据计算复杂度和存储容量的问题。
因此,需要将单体应用进一步拆分,按业务边界重新划分成分布式应用,使应用与应用之间不再直接共享数据,而是通过约定好的契约进行通信,以提高扩展性。
服务化设计原则是指通过服务化架构拆分不同生命周期的业务单元,实现业务单元的独立迭代,从而加快整体的迭代速度,保证迭代的稳定性。
同时,服务化架构采用的是面向接口编程方式,增加了软件的复用程度,增强了水平扩展的能力。
服务化设计原则还强调在架构层面抽象化业务模块之间的关系,从而帮助业务模块实现基于服务流量(而非网络流量)的策略控制和治理,而无须关注这些服务是基于何种编程语言开发的。
有关服务化设计原则的实践在业界已有很多成功案例。
其中影响最广、最为业界称道的是Netflix在生产系统上所进行的大规模微服务化实践。
通过这次实践,Netflix在全球不仅承接了多达1.67亿订阅用户以及全球互联网带宽容量15%以上的流量,而且在开源领域贡献了Eureka、Zuul、Hystrix等出色的微服务组件。
不仅海外公司正在不断进行服务化实践,国内公司对服务化也有很高的认知。
随着近几年互联网化的发展,无论是新锐互联网公司,还是传统大型企业,在服务化实践上都有很好的实践和成功案例。
阿里巴巴的服务化实践发端于2008年的五彩石项目,历经10年的发展,稳定支撑历年大促活动。
以2019年“双11”当天数据为例,阿里巴巴的分布式系统创单峰值为每秒54.4万笔,实时计算处理为每秒25.5亿笔。
阿里巴巴在服务化领域的实践,已通过ApacheDubbo、Nacos、Sentinel、Seata、ChaosBlade等开源项目分享给业界,同时,这些组件与SpringCloud的集成SpringCloudAlibaba已成为SpringCloudNetflix的继任者。
2.2.2弹性原则
弹性原则是指系统部署规模可以随着业务量变化自动调整大小,而无须根据事先的容量规划准备固定的硬件和软件资源。
优秀的弹性能力不仅能够改变企业的IT成本模式,使得企业不用再考虑额外的软硬件资源成本支出(闲置成本),也能更好地支持业务规模的爆发式扩张,不再因为软硬件资源储备不足而留下遗憾。
在云原生时代,企业构建IT系统的门槛大幅降低,这极大地提升了企业将业务规划落地为产品与服务的效率。
这一点在移动互联网和游戏行业中显得尤为突出。
一款应用成为爆款后,其用户数量呈现指数级增长的案例不在少数。
而业务呈指数级增长会对企业IT系统的性能带来巨大考验。
面对这样的挑战,在传统架构中,通常是开发人员、运维人员疲于调优系统性能,但是,即使他们使出浑身解数,也未必能够完全解决系统的瓶颈问题,最终因系统无法应对不断涌入的海量用户而造成应用瘫痪。
除了面临业务呈指数级增长的考验之外,业务的峰值特征将是另一个重要的挑战。
比如,电影票订票系统下午时段的流量远超凌晨时段,而周末的流量相比工作日甚至会翻好几倍;还有外卖订餐系统,在午餐和晚餐前后往往会出现订单峰值时段。
在传统架构中,为了应对这类具有明显峰值特征的场景,企业需要为峰值时段的流量提前准备大量的计算、存储及网络资源并为这些资源付费,而这些资源在大部分时间内却处于闲置状态。
因此,在云原生时代,企业在构建IT系统时,应该尽早考虑让应用架构具备弹性能力,以便在快速发展的业务规模面前灵活应对各种场景需求,充分利用云原生技术及成本优势。
要想构建弹性的系统架构,需要遵循如下四个基本原则。
(1)按功能切割应用
一个大型的复杂系统可能由成百上千个服务组成,架构师在设计架构时,需要遵循的原则是:
将相关的逻辑放到一起,不相关的逻辑拆解到独立的服务中,各服务之间通过标准的服务发现(ServiceDiscovery)找到对方,并使用标准的接口进行通信。
各服务之间松耦合,这使得每一个服务能够各自独立地完成弹性伸缩,从而避免服务上下游关联故障的发生。
(2)支持水平切分
按功能切割应用并没有完全解决弹性的问题。
一个应用被拆解为众多服务后,随着用户流量的增长,单个服务最终也会遇到系统瓶颈。
因此在设计上,每个服务都需要具备可水平切分的能力,以便将服务切分为不同的逻辑单元,由每个单元处理一部分用户流量,从而使服务自身具备良好的扩展能力。
这其中最大的挑战在于数据库系统,因为数据库系统自身是有状态的,所以合理地切分数据并提供正确的事务机制将是一个非常复杂的工程。
不过,在云原生时代,云平台所提供的云原生数据库服务可以解决大部分复杂的分布式系统问
题,因此,如果企业是通过云平台提供的能力来构建弹性系统,自然就会拥有数据库系统的弹性能力。
(3)自动化部署
系统突发流量通常无法预计,因此常用的解决方案是,通过人工扩容系统的方式,使系统具备支持更大规模用户访问的能力。
在完成架构拆分之后,弹性系统还需要具备自动化部署能力,以便根据既定的规则或者外部流量突发信号触发系统的自动化扩容功能,满足系统对于缩短突发流量影响时长的及时性要求,同时在峰值时段结束后自动缩容系统,降低系统运行的资源占用成本。
(4)支持服务降级
弹性系统需要提前设计异常应对方案,比如,对服务进行分级治理,在弹性机制失效、弹性资源不足或者流量峰值超出预期等异常情况下,系统架构需要具备服务降级的能力,通过降低部分非关键服务的质量,或者关闭部分增强功能来让出资源,并扩容重要功能对应的服务容量,以确保产品的主要功能不受影响。
国内外已有很多成功构建大规模弹性系统的实践案例,其中最具代表性的是阿里巴巴一年一度的“双11”大促活动。
为了应对相较于平时上百倍的流量峰值,阿里巴巴每年从阿里云采买弹性资源部署自己的应用,并在“双11”活动之后释放这一批资源,按需付费,从而大幅降低大促活动的资源成本。
另一个例子是新浪微博的弹性架构,在社会热点事件发生时,新浪微博通过弹性系统将应用容器扩容到阿里云,以应对热点事件导致的大量搜索和转发请求。
系统通过分钟级的按需扩容响应能力,大幅降低了热搜所产生的资源成本。
随着云原生技术的发展,FaaS、Serverless等技术生态逐步成熟,构建大规模弹性系统的难度逐步降低。
当企业以FaaS、Serverless等技术理念作为系统架构的设计原则时,系统就具备了弹性伸缩的能力,企业也就无须额外为“维护弹性系统自身”付出成本。
2.2.3可观测原则
与监控、业务探活、APM(ApplicationPerformanceManagement,应用性能管理)等系统提供的被动能力不同,可观测性更强调主动性,在云计算这样的分布式系统中,主动通过日志、链路跟踪和度量等手段,让一次App点击所产生的多次服务调用耗时、返回值和参数都清晰可见,甚至可以下钻到每次第三方软件调用、SQL请求、节点拓扑、网络响应等信息中。
运维、开发和业务人员通过这样的观测能力可以实时掌握软件的运行情况,并获得前所未有的关联分析能力,以便不断优化业务的健康度和用户体验。
随着云计算的全面发展,企业的应用架构发生了显著变化,正逐步从传统的单体应用向微服务过渡。
在微服务架构中,各服务之间松耦合的设计方式使得版本迭代更快、周期更短;基础设施层中的Kubernetes等已经成为容器的默认平台;服务可以通过流水线实现持续集成与部署。
这些变化可将服务的变更风险降到最低,提升了研发的效率。
在微服务架构中,系统的故障点可能出现在任何地方,因此我们需要针对可观测性进行体系化设计,以降低MTTR(故障平均修复时间)。
要想构建可观测性体系,需要遵循如下三个基本原则。
1.数据的全面采集
指标(Metric)、链路跟踪(Tracing)和日志(Logging)这三类数据是构建一个完整的可观测性系统的“三大支柱”。
而系统的可观测性就是需要完整地采集、分析和展示这三类数据。
(1)指标
指标是指在多个连续的时间周期里用于度量的KPI数值。
一般情况下,指标会按软件架构进行分层,分为系统资源指标(如CPU使用率、磁盘使用率和网络带宽情况等)、应用指标(如出错率、服务等级协议SLA、服务满意度APDEX、平均延时等)、业务指标(如用户会话数、订单数量和营业额等)。
(2)链路跟踪
链路跟踪是指通过TraceId的唯一标识来记录并还原发生一次分布式调用的完整过程,贯穿数据从浏览器或移动端经过服务器处理,到执行SQL或发起远程调用的整个过程。
(3)日志
日志通常用来记录应用运行的执行过程、代码调试、错误异常等信息,如Nginx日志可以记录远端IP、发生请求时间、数据大小等信息。
日志数据需要集中化存储,并具备可检索的能力。
2.数据的关联分析
让各数据之间产生更多的关联,这一点对于一个可观测性系统而言尤为重要。
出现故障时,有效的关联分析可以实现对故障的快速定界与定位,从而提升故障处理效率,减少不必要的损失。
一般情况下,我们会将应用的服务器地址、服务接口等信息作为附加属性,与指标、调用链、日志等信息绑定,并且赋予可观测系统一定的定制能力,以便灵活满足更加复杂的运维场景需求。
3.统一的监控视图与展现
多种形式、多个维度的监控视图可以帮助运维和开发人员快速发现系统瓶颈,消除系统隐患。
监控数据的呈现形式应该不仅仅是指标趋势图表、柱状图等,还需要结合复杂的实际应用场景需要,让视图具备下钻分析和定制能力,以满足运维监控、版本发布管理、故障排除等多场景需求。
随着云原生技术的发展,基于异构微服务架构的场景会越来越多、越来越复杂,而可观测性是一切自动化能力构建的基础。
只有实现全面的可观测性,才能真正提升系统的稳定性、降低MTTR。
因此,如何构建系统资源、容器、网络、应用、业务的全栈可观测体系,是每个企业都需要思考的问题。
2.2.4韧性原则
韧性是指当软件所依赖的软硬件组件出现异常时,软件所表现出来的抵御能力。
这些异常通常包括硬件故障、硬件资源瓶颈(如CPU或网卡带宽耗尽)、业务流量超出软件设计承受能力、影响机房正常工作的故障或灾难、所依赖软件发生故障等可能造成业务不可用的潜在影响因素。
业务上线之后,在运行期的大部分时间里,可能还会遇到各种不确定性输入和不稳定依赖的情况。
当这些非正常场景出现时,业务需要尽可能地保证服务质量,满足当前以联网服务为代表的“永远在线”的要求。
因此,韧性能力的核心设计理念是面向失败设计,即考虑如何在各种依赖不正常的情况下,减小异常对系统及服务质量的影响并尽快恢复正常。
韧性原则的实践与常见架构主要包括服务异步化能力、重试/限流/降级/熔断/反压、主从模式、集群模式、多AZ(AvailabilityZone,可用区)的高可用、单元化、跨区域(Region)容灾、异地多活容灾等。
2.2.5所有过程自动化原则
技术是把“双刃剑”,容器、微服务、DevOps以及大量第三方组件的使用,在降低分布式复杂性和提升迭代速度的同时,也提高了软件技术栈的复杂度,加大了组件规模,从而不可避免地导致了软件交付的复杂性。
如果控制不当,应用就会无法体会到云原生技术的优势。
通过IaC、GitOps、OAM、Operator和大量自动化交付工具在CI/CD(持续集成/持续交付)流水线中的实践,企业可以标准化企业内部的软件交付过程,也可以在标准化的基础上实现自动化,即通过配置数据自描述和面向终态的交付过程,实现整个软件交付和运维的自动化。