人类璀璨浩瀚的科技发展历程中,每一个宏观与微观领域都离不开计算的参与。计算机的出现,让我们从发现到解决问题的速度呈指数级增长,极大加快了创造的效率。
云计算,是结合人类社会顶端智囊与最尖端 IT 科技而诞生的最新互联网技术之一,已成为当前互联网的基础设施,计算能力、存储能力、网络能力、安全能力,作为新一代互联网计算资源的基石,云计算支撑着互联网几乎所有的上层数据处理系统。
为什么一定要学云原生技术?
BAT、美团、字节跳动、快手等一线大厂都在加速推进业务的容器化、云原生化。
作为容器领域的事实标准,Kubernetes 已经成为后端开发工程师的必修技术栈。
云原生属于新赛道,目前,行业内云原生、Kubernetes、容器工程师供不应求。
云原生工程师
云原生是一条最佳路径或者最佳实践。它为用户指定了一条低心智负担的、敏捷的、能够以可扩展、可复制的方式最大化地利用云的能力、发挥云的价值的最佳路径。按照云原生思想设计出来的软件天然就“生在云上,长在云上”。
关于云原生的概念,业内有没有统一的定义,比较主流的还是CNCF(Cloud Native Computing Foundation,云原生计算基金会)对云原生的定义。原文如下:
Cloud native technologies empower organizations to build and run scalable applications in public, private, and hybrid clouds.
Features such as containers, service meshes, microservices, immutable infrastructure, and declarative application programming interfaces (APIs) best illustrate this approach.
云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论。简单来说,云原生是一种最佳实践。云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行弹性、分布式的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。将其称之为云原生(Cloud Native)也可从字面意思理解,其中Cloud表示应用程序位于云中,而不是传统的数据中心;Native表示应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳姿势运行,充分利用和发挥云平台的基础设施等能力。关于云原生的定义,可以用一张图来直观的表示:
云原生基础要素
接下来将详细介绍云原生的代表技术:容器、服务网格、微服务、不可变基础设施和声明式API。
容器(Container)
容器(Docker已成为主流)是基于IT基础设施层概念,是比虚拟机更轻量化的隔离工具。使用容器编排框架(Kubernetes已成为主流)实现容器的资源调度和容器编排,可以实现容器更优雅的管理。容器体系结构和虚拟机体系结构架构上的差异见下图:
虚拟机上运行的是完整的操作系统,而容器在主机操作系统的内核(可以将其视为操作系统的隐藏管道)上构建,只包含应用和一些轻型操作系统 API 以及在用户模式下运行的服务。
云原生领域,在容器中运行微服务已经成为事实标准,对一些常见的容器操作命令有必要学习掌握。
服务网格(Service Mesh)
服务网格是从微服务概念演化而来,最初的微服务需要自行处理服务间的通信,也就是说各微服务需要承载网络层的职责。而服务网格就是从服务中分离出这部分关注点。这里,再明确下服务网格概念。服务网格,作为服务间通信的基础设施层,是轻量级高性能网络代理,提供安全的、快速的、可靠地服务间通讯,与实际应用部署一起,但对应用透明。应用作为服务的发起方,只需要用最简单的方式将请求发送给本地的服务网格代理,然后网格代理会进行后续的操作,如服务发现,负载均衡,最后将请求转发给目标服务。经典的服务网格架构如下:
服务网格作为 Sidecar (边车) 运行,对应用程序来说是透明,所有应用程序间的流量都会通过它,所以对应用程序流量控制、超时、熔断等网络层功能都可以在 serivce mesh 中实现。主流的服务网格以Istio为主。
微服务(Microservice)
业内对于微服务并没有统一的概念,但是Martin Fowler和James Lewis获得了大部分软件工作者的认可。原文如下:
微服务架构从单体架构演进而来,后面会单独写一篇文章,梳理微服务架构的演进。微服务架构风格是一种将单一应用开发为一组小型服务的方法。在微服务架构中,每个微服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常使用HTTP资源API)。这些服务围绕业务能力构建,并且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开发,使用不同的数据存储技术。马丁福勒等人还总结了微服务架构的九大特征:
(1) Componentization via Services(服务组件化)。组件是一个可独立替换和独立升级的软件单元。使用服务作为组件而不是使用库的主要原因:(a)服务是可独立部署的;(b)更加明确的组件接口:服务通过明确的远程调用机制可以避免组件间的紧耦合。但使用服务作为组件也有一些缺点。如(a)远程调用比进程内调用更昂贵;(b)会远程API设计成粗粒度,不便于使用(为了屏蔽一些对用户透明的内部实现细节)。
(2) Organized around Business Capabilities(围绕业务能力组织)。为推广微服务架构,还需考虑组织结构,这理论主要来源于康威定律。康威定律内容如下:任何组织在设计一套系统时,所交付的设计方案在结构上都与该组织的沟通结构保持一致。
(3) Products not Projects(是产品,而不是项目)。微服务架构认为一个团队应该负责产品的整个生命周期。相比单体应用,微服务的粒度更小,更容易在服务开发者和用户之间建立个人关系。
(4) Smart endpoints and dumb pipes(智能端点和哑巴管道)。智能端点是指各微服务功能内聚,哑巴管道是指微服务间使用轻量级进程通信协议。如REST、gRPC等
(5) Decentralized Governance(去中心化治理)。集中治理的一个后果是技术平台的单一标准化发展趋势。使用单一的技术栈,最大的坏处是面对变化时,无法快速的响应。当服务规模庞大时,对单一技术平台进行技术栈变更的代价是巨大的。去中心化治理的最高境界就是亚马逊广为流传的"you build it, you run it"理念:团队要对他们构建的软件的各方面负责,包括724小时的运营。
(6) Decentralized Data Management(去中心化数据管理)。微服务更倾向于让每个服务管理自己的数据库,或者同一数据库技术的不同实例,或完全不同的数据库系统。使用微服务开发后,必然会引入分布式事务问题。后面会单独介绍分布式事务,这里不再展开介绍。
(7) Infrastructure Automation(基础设施自动化)。当微服务规模化后,对微服务的管理还应实现自动化,特别是基础设置的自动化。如容器的构建、服务实例的启动、监控、日志等等。这里涉及到一个概念——微服务治理。
(8) Design for failure(为失效设计)。使用服务作为组件的一个后果:应用需要被设计成能够容忍服务失效。任何服务调用方都可能因为服务提供方不可用而失败,服务调用方必须尽可能优雅地应对这种失败。
(9) Evolutionary Design(进化式设计)。微服务强调可替代性,通过变更模式来驱动模块化:同时变化的东西保持在同一模块中。系统中很少变更的部分应该和正在经历大量扰动的部分放在不同的服务里。服务的拆分与合并不是一成不变的,应随着对业务理解加深,合理的拆分或合并各微服务。
不可变基础设施(Immutable Infrastructure)
不可变基础设施中的“不可变”类似程序设计中的不可变变量(Immutable Variable),就是在完成赋值后就不能发生更改,只能创建新的来整体替换旧的。由于具有这样的特性这种变量可以在并发环境下安全的使用。对于基础设施的不可变性,最基本的就是指运行服务的服务器在完成部署后,就不再更改。之所以推崇不可变基础设施,是意味可变基础设施会导致以下问题:
(1) 在灾难发生时,服务难以重新构建。过多的手工操作,缺乏记录,会导致很难由标准初始化后的服务器来重新构建起等效的服务。
(2) 在服务运行过程中,持续的修改服务器,就犹如程序中的可变变量的值发生变化而引入的状态不一致的并发风险。这些对于服务器的修改,同样会引入中间状态,从而导致不可预知的问题。
不可变基础设施的发展离不开虚拟化技术的发展。虚拟机技术、容器技术、容器编排技术等,降低了获取不可变基础设施的成本。
声明式API(Declarative API)
声明式(Declarative)与命令式(Imperative)相对。两者的区别是:在Declarative中,描述的是目标状态(Goal State),而在Imperative模式中,描述的是一系列的动作。这一系列的动作如果被正确的顺利执行,最终结果是这个事物达到了我们期望的目标状态的。
SQL 其实就是一种常见的声明式『编程语言』,它能够让开发者自己去指定想要的数据是什么。或者说,告诉数据库想要的结果是什么,数据库会帮助获取这个结果集的执行路径,并返回结果集。众所周知,使用 SQL 语言获取数据,要比自行编程去获取数据容易的多。
声明式 API 使系统更加健壮,在分布式系统中,任何组件都可能随时出现故障。当组件恢复时,需要弄清楚要做什么,使用命令式 API 时,处理起来就很棘手。但是使用声明式 API ,组件只需查看 API 服务器的当前状态,即可确定它需要执行的操作。声明式设计的好处是:
(1)简单。我们不需要关心任何过程细节。过程是由工具自己内部figure out的、内部执行的。
(2)自描述。我们描述的就是希望一个事物变成什么样子,而不是“发育”过程。 声明式的方式能够大量地减少使用者的工作量,极大地增加开发的效率,这是因为声明式能够简化需要的代码,减少开发人员的工作,如果我们使用命令式的方式进行开发,虽然在配置上比较灵活,但是带来了更多的工作。
十二要素(12-Factor)
十二要素为构建微服务应用提供了方法论。具有如下好处:
(1) 使用标准化流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目。
(2) 和操作系统之间尽可能的划清界限,在各个系统中提供最大的可移植性。
(3) 适合部署在现代的云计算平台,从而在服务器和系统管理方面节省资源。
(4) 将开发环境和生产环境的差异降至最低,并使用持续交付实施敏捷开发。
(5) 可以在工具、架构和开发流程不发生明显变化的前提下实现扩展。
十二要素的内容如下:
(1) Codebase(基准代码)。一份基准代码,多份环境部署。
(2) Dependencies(依赖)。显式声明依赖关系。
(3) Config(配置)。在环境中存储配置。
(4) Backing services(后端服务)。把后端服务当作附加资源。
(5) Build, release, run(构建,发布,运行)。严格分离构建、部署、发布。
(6) Processes(进程)。以一个或多个无状态的进程运行应用。
(7) Port binding(端口绑定)。通过端口绑定提供服务。
(8) Concurrency(并发)。通过进程横向扩展应对并发。
(9) Disposability(易处理)。快速启动和优雅终止可最大化健壮性。
(10) Dev/prod parity(开发环境与线上环境等价)。尽可能的保持开发,预发布,线上环境相同。
(11) Logs(日志)。把日志当作事件流。
(12) Admin processes(管理进程)。后台管理任务当作一次性进程运行。
十二要素就是从软件生命周期对软件开发的总结。需要说明的是,十二要素只是需要参考的因素,不是必需的,切不可为了遵循十二要素而过分的设计系统。如尽可能的保持开发,预发布,线上环境相同这一条,其实现难度要比想象中困难的多。
最后,补充一下十二要素在软件生命周期各阶段示意图:
参考
https://landscape.cncf.io/ 云原生全景图
https://blog.csdn.net/u012234419/article/details/115440317 CNCF和云原生
https://github.com/cncf/foundation/blob/master/charter.md cloud-native
https://docs.microsoft.com/en-us/dotnet/architecture/cloud-native/definition Cloud Native Definition
https://blog.csdn.net/s15212790607/article/details/124378659 云原生概述
https://blog.csdn.net/qq_45400861/article/details/124803467 云原生概念
https://docs.microsoft.com/zh-cn/virtualization/windowscontainers/about/containers-vs-vm 容器与虚拟机
https://cloud.tencent.com/developer/article/1876488 服务网格
https://jimmysong.io/istio-handbook/concepts/what-is-service-mesh.html 理解服务网格
https://www.jianshu.com/p/8c3d8b067f26 微服务概念
https://www.martinfowler.com/articles/microservices.html Microservices definition
https://www.jianshu.com/p/df87c6b4d3b7 Martin Fowler的《Microservices-微服务》
https://blog.csdn.net/chaocai2004/article/details/103827372 云原生定义解析—不可变基础设施
https://www.bookstack.cn/read/learning-cloudnative/7bb7c6d9505bf389.md 声明式设计
https://12factor.net/zh_cn/ 十二要素