云原生架构总结-读书笔记

云原生架构进阶实战-读书笔记

云原生概念

云原生(Cloud Native)概念是由Pivotal的Matt Stine在2013年首次提出的。这个概念得到了社区的不断完善,内容越来越丰富,目前已经**包括了DevOps(Development和Operations的组合)、持续交付(Continuous Delivery,CD)、微服务(MicroServices)、敏捷基础设施(Agile Infrastructure)和十二要素(The Twelve-Factor App)**等几大主题。

2015年云原生计算基金会(CNCF)成立,对云原生定义进行了修改,认为云原生需要包含应用容器化、面向微服务架构以及支持容器编排调度等方面的内容。

在这里插入图片描述

云三层模型 VS 云原生架构

在这里插入图片描述

云原生架构内容

2015年云原生计算基金会(CNCF)成立,对云原生定义进行了修改,认为云原生需要包含应用容器化、面向微服务架构以及支持容器编排调度等方面的内容。

云原生主要包括两部分内容:云原生基础架构和云原生应用。

为什么需要云原生

在这里插入图片描述

云的核心理念是弹性。

从技术发展的角度看:

开源让云计算变得越来越标准化,容器已经成为企业应用分发和交付的标准,可以将应用与底层运行环境解耦;

Kubernetes成为资源调度和编排的标准,屏蔽了底层架构的差异性,帮助应用平滑运行在不同的基础设施上;

在此基础上建立上层应用抽象(如微服务和服务网格),逐步形成应用架构现代化演进的标准,

开发者只需要关注自身的业务逻辑,无须关注底层实现。

云原生正在通过方法论、工具集和理念重塑整个软件技术栈和生命周期,帮助企业和开发者在云上构建和运行可弹性扩展、容错性好、易于管理、便于观察的系统。

云原生的设计原则

1、去中心化原则

SOA一般有一个中心化的企业服务总线(Enterprise Service Bus,ESB)负责所有服务的注册发现以及调用路由;

微服务架构虽然也有一个服务注册中心,但服务注册中心只负责应用启动或者状态变更时做服务推送,真正在运行过程中微服务之间的相互调用都是点对点直接调用,即运行时是去中心化的。

2、松耦合原则

1、实现的松耦合

服务消费端不需要依赖服务契约的某个特定实现,消费端未来还可以自由切换到该契约的其他服务提供方。

2、时间的松耦合

典型的是异步消息队列系统,由于有中介者(broker),因此生产者和消费者不必在同一时间都保持可用性以及相同的吞吐量,而且生产者也不需要马上等到回复。

3、位置的松耦合

典型的是服务注册中心,消费端完全不需要直接知道提供服务端的具体位置,而都通过注册中心查找服务来访问。

4、版本的松耦合

消费端不需要依赖服务契约的某个特定版本来工作,这就要求服务的契约在升级时要尽可能地提供向下兼容性。

3、面向失败设计原则

在发生异常时能够快速失败,然后快速恢复,以保证业务永远在线,不能让业务半死不活地僵持着。

面向失败设计(design for failure),意味着所有的外部调用都有容错处理。

系统架构设计时需要考虑到应用系统的每一个层面,包括硬件和软件是可能出现故障的,并据此在应用系统架构设计上消除单一故障点,从而实现高可用性(High Availability,HA)的系统架构。

4、无状态化原则

云原生的应用服务设计尽可能是无状态的,使得业务天生具有扩展性,在业务流量高峰和低峰时期,依赖云的特性自动弹性扩容、缩容,满足业务需求。

无状态指的是服务在处理请求时,不依赖除请求本身以外的其他内容,也不会有除响应请求之外的额外操作。

将“有状态”的业务处理过程改造成“无状态”的过程,思路比较简单,主要有以下两种手段。

(1)状态分离:服务端所有的状态信息统一保存在外部独立的分布式存储中(如缓存、消息队列、数据库)。(2)请求附带全部状态信息:将状态信息前置,丰富请求的入参,将需要处理的数据尽可能都通过上游的客户端放到入参中传过来。

基于状态的Web服务

在基于状态的Web服务中,Client与Server交互的信息(如:用户登录状态)会保存在Server的Session中。再这样的前提下,Client中的用户请求只能被保存有此用户相关状态信息的服务器所接受和理解,这也就意味着在基于状态的Web系统中的Server无法对用户请求进行负载均衡等自由的调度(一个Client请求只能由一个指定的Server处理)。同时这也会导致另外一个容错性的问题,如果指定的Server在Client的用户发出请求的过程中宕机,那么此用户最近的所有交互操作将无法被转移至别的Server上,即此请求将无效化。

基于无状态的Web服务

在无状态的Web服务中,每一个Web请求都必须是独立的,请求之间是完全分离的。Server没有保存Client的状态信息,所以Client发送的请求必须包含有能够让服务器理解请求的全部信息,包括自己的状态信息。使得一个Client的Web请求能够被任何可用的Server应答,从而将Web系统扩展到大量的Client中。

有状态和无状态是相对于计算机系统中的应用程序而言的:

  • 有状态:指应用程序会保存一些数据,这些数据反映了应用程序的运行状态。也就是说,在不同的请求之间,应用程序的运行状态可能会改变。这些数据通常存储在内存或数据库中,并且可以被多个用户或客户端共享访问。
  • 无状态:指应用程序没有保存任何数据,每次请求都是独立的,不依赖于之前的请求。也就是说,应用程序对于每一个请求都是重新生成结果,不会基于之前的结果进行优化或者缓存。在这种情况下,数据可以通过请求的参数来传递。
    举个例子,计算器程序可以是一个无状态的应用程序。每一次计算都仅依赖于输入的数据(例如加数、减数),不会基于之前的计算结果进行优化。
    而网上购物应用程序则通常是一个有状态的应用程序。因为它需要记录用户的购物车、订单等信息,这些信息随着用户的登录和操作而变化。如果该应用程序是一个无状态的应用程序,那么每次购买商品时,都需要重新输入订单和配送信息,用户体验将非常不好。
    Java Web 应用程序大多数情况下都是有状态的,它们需要处理会话(session)和状态(state)等概念。但是,如果一个Web应用程序使用了RESTful架构风格,那么它就是一个无状态的应用程序,不保存会话信息或其他相关数据。

5、不变性原则

希望所有的服务(包括环境)无差异化配置,实现标准化可迁移,而不希望在部署任何服务的过程中还需要手动操作。

实现不变性原则的前提是,基础设施中的每个服务、组件都可以自动安装、部署,不需要人工干预。所有的资源都可以随时拉起、随时释放,同时以API的方式提供弹性、按需的计算、存储能力。

为了提升可用性,应该尽量减少故障修复时间,要知道替换的速度远远快于修复的速度。

6、自动化驱动原则

自动化驱动分为持续集成、持续部署、持续交付等阶段,用来确保需求的提出、设计开发测试,再到代码快速、安全地部署到生产环境中。

持续集成是指每当开发人员提交了一次改动,就立刻进行构建、自动化测试,确保业务应用和服务均能符合预期,从而可以确定新代码和原有代码能否正确地集成在一起。

持续部署是指使用完全的自动化过程把每个变更自动提交到测试环境中,触发自动化测试用例,测试验证通过后将应用安全地部署到生产环境中,打通开发、测试、生产等各个环节。

持续交付是软件发布的能力,在持续集成完成后,能够提供到预发布之类的环境上,满足生产环境的条件。

云原生基础架构

云原生基础架构是隐藏在抽象背后的由软件管理并由API进行控制的基础架构,它的目标是运行应用系统。

云原生基础架构不仅仅是在公有云上运行基础架构,也不是在容器中运行应用程序,所以公有云和容器化不是云原生基础架构的代名词。

但是云原生基础架构可以借助容器化技术和公有云技术去实现。

公有云仅仅是IaaS层的实现,一般的公有云还是要借助人力去申请、分配。

而云原生基础架构则是用程序代码自动去申请。

容器仅仅是应用程序的一种打包方式,这并不意味着这些应用程序具备自治功能。

即使应用程序是通过持续集成和持续交付等DevOps流水线自动构建和部署的,也并不一定就是云原生基础架构。

Kubernetes也不能简单地称为云原生基础架构。

Kubernetes的容器编排技术为云原生基础架构提供了必要的平台支撑功能。

是否是云原生基础架构的关键在于是否使用自动化处理的方式。

例如在Kubernetes中手工分配物理卷,就不能称为云原生基础架构,因为物理卷不是自动分配的。

而如果使用动态卷,依靠卷声明来分配容量,进而分配使用该卷的容器,则满足了云原生基础架构的要求。

云原生应用对基础架构的基本要求有:

● 运行时间和隔离。● 资源分配和调度。● 环境隔离。

● 服务发现。● 状态管理。● 监测和日志记录。

● 度量聚合。● 调试和追踪。

云原生应用程序和基础架构协作以发现其相关依赖服务。

Prometheus实现了一种服务发现方式,主动感知系统监控目标的变化,自动添加、删除和更新服务。以下是一个Kubernetes上的服务允许Prometheus自动发现的代码,其中的prometheus.io/scrape:"true"就是为了让Prometheus感知到该服务。该服务暴露了HTTP协议访问,端口为8080,端点为/metrics。

在这里插入图片描述

通常,云原生应用程序构建为在Docker容器中运行的一组微服务,在Kubernetes中编排,并使用DevOps和Git Ops工作流进行部署和管理。

云原生架构是一种包含技术实现与管理(组织流程)的软件开发方法论。技术实现部分主要包括敏捷基础设施、云公共基础服务和微服务;组织流程部分主要包括持续交付和DevOps。

云原生应用架构包含3个特征:容器化、微服务和DevOps。

云原生应用

云原生应用程序的关键在于提供弹性、敏捷性、可操作性和可观察性。

弹性的概念隐含了允许应用程序失败而不是试图阻止程序失败的意思。

敏捷性允许应用快速部署和快速迭代,这就需要引入DevOps文化。

可操作性是指从应用程序内部控制应用程序的生命周期,而不是依赖外部进程和监视器。

可观察性是指应用程序需要提供信息以反映应用程序的状态。

目前实现云原生应用程序所需特性的常用方法有:

● 微服务。

● 健康状况报告。

● 自动测量数据。

● 弹性。

● 声明模式而不是响应模式。

微服务

传统应用程序是以单个实体为目标进行管理和部署的,称为单体应用程序。

单体应用程序的好处是显而易见的,但是它无法解决面向大量互联网用户提供服务的并发量问题,且使得开发过程变得臃肿,开发进程变得缓慢,维护也越来越困难。解决这些问题最好的方法之一就是分解单体应用为众多小的服务模块。

这些服务模块相互独立,使得开发人员可以独立维护这些小系统,而且开发和维护过程也变得敏捷。

分解成微服务后,各服务的编写语言也可以自行确定,只需要遵守总体的API优先和通信要求即可。

在这里插入图片描述

微服务架构

微服务更像是UNIX哲学的实践和改造。UNIX哲学是“程序应该只关注一个目标,并尽可能把它做好。让程序能够互相协同工作。”

微服务也是如此,服务更专注于其用途,也就是只应做一件事,并把这件事做好。

但是微服务不能等同于云原生架构,微服务只是云原生文化的一种实现。

健康状况报告

为了能够由软件控制一切,应用程序必须提供可供管理软件监测的度量指标。而一个应用程序的度量指标只有创建应用程序的作者最清楚,因此在应用程序中内置度量指标是最好的设计方式。

这要求各应用程序提供必要的端点,供管理软件访问以判断应用程序状态。例如Kubernetes、ETCD都通过HTTP提供了大量的度量指标。

此外,应用程序应该提供更加丰富且必要的状态报告。

在云原生架构下,一切皆是代码,一切皆可由软件控制。

为了可以控制,各应用程序必须提供度量接口让管理软件获知应用程序运行状态以做出必要的反应,例如应用程序崩溃时,管理程序可做出停掉当前应用程序实例然后启动新实例的操作。应用程序的健康状况只是能够自动执行应用程序声明周期的一部分,管理程序还需要知道应用程序是否正在工作。

自动测量数据

自动测量数据是做出决定所必需的信息,这些数据与健康状况报告的数据是有重叠的,但是它们的用途不一样。

健康报告是告知管理程序所辖应用程序的生命周期状态,

而自动测量数据是告知应用程序的业务度量指标。

度量的指标一般称为服务级别指标(Service Level Indicator,SLI)或关键绩效指标(Key Performance Indicator,KPI)。这些指标是特定于应用程序的数据,让管理程序监测应用程序的性能在服务级别目标(Service Level Objectives,SLO)内。自动测量数据可以解决以下问题:

● 应用程序每分钟收到的请求数。● 是否有任何错误。

● 应用程序延迟多久。● 业务处理需要多长时间。

监测数据经常被抓取或推送到时间序列数据库(如Prometheus或InfluxDB),然后再由度量指标模型进行处理分析,以便后续提醒或者大屏展示。

在一个动态可自我修复的环境中,管理程序几乎不关心单个应用程序的生命周期,而更多关心应用程序的SLO,因为若是一个程序崩溃,管理程序可以动态重启应用程序实例以恢复正常运行状态。

举一个例子,在Kubernetes中运行以下命令可以看到coredns重启过两次和3次,但是管理程序不关心这个行为,只关心它是否在正常运转,因为管理程序的SLO就是要正常运转。

在这里插入图片描述

SLO:Service Level Objective,服务质量目标,它通常指的是维护系统的最高级别的目标,是为期望的系统的可用性设定的目标,以一段时间内的百分比表示。

弹性处理故障

云原生应用程序应当正视故障而不是竭力避免故障。唯一不应该有故障的系统是那些维持生命的系统。任何系统都应该有一个合理的SLO,如果无视SLO而去避免故障发生,则花费的成本将非常巨大。为此,必须假设应用程序可能发生故障,并采取必要的措施应对故障,这是云原生应用的一种模式。

无论发生什么样的故障,云原生应用都必须适应,并采取合理的调整措施应对。

此外,云原生应用还需要设计一种方法应对过载,处理过载的一种常见方法是适度降级。

云原生应用要求具备服务优雅降级的能力。最现实的处理方式是服务降级,返回部分回应或使用本地缓存中的旧信息进行回应。

声明式通信

由于云原生应用程序在云环境中运行,因此它们与基础架构和支持应用程序的交互方式与传统应用程序不同。在云本机应用程序中,与任何内容进行通信的方式都是通过网络。

很多时候,网络通信是通过RESTful HTTP调用完成的,但也可以通过其他接口实现,例如远程过程调用(RPC)。

在传统应用程序中,通信的介质可能是文件或者消息队列,但是这些方式都是尝试构建避免失败的方式,它们在云原生架构下存在一些问题。例如应用程序把结果写入到文件,写完后应用程序崩溃了。此时会出现了一种情况:应用程序崩溃之前,计算结果已经写入文件中。按照云原生理念,此时应用程序将重启,再次执行计算过程,计算结果再次写到文件中。因此,开发人员应该停止使用反应式通信,开始使用声明式通信,从而提高应用程序的健壮性,并且减少应用程序的依赖。

命令式编程(Imperative):详细的命令机器怎么(How)去处理一件事情以达到你想要的结果(What);

声明式编程(Declarative):

  • 29
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

碳学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值