架构的演进之路与前沿技术

系统架构演进

首先以演进的方式来了解不同的系统架构。

单体架构

在这里插入图片描述
一个项目中的多个服务,混合部署在一个进程内,服务之间的交互都是通过进程内调用完成的,正如图中 Service 之间的红色箭头所示。这样做的好处是可以快速开发、部署服务,服务之间调用的性能也最好。

当然,这种架构缺点也非常多,比如:

●随着业务的增长,项目越来越臃肿;

●服务之间因为 JAR 包引用导致频繁的依赖冲突;

●服务资源变更困难,因为一个服务可能被多个不同的业务引用,升级资源需要多个业务方同时升级;

●因为不同业务方都可以直连服务的数据资源,这个架构也存在明显的数据安全风险;

●修改代码后回归困难、架构难以调整等等。

以上所有问题都是因为服务耦合在一起导致的。在服务规模不大的情况下,比较适合采用单体架构,方便快速迭代。但是当服务规模变大时,单体架构就不是一个好的选择。

微服务架构

当服务的规模变大时,为了解决服务耦合的问题,出现了 SOA 就是面向服务架构,它的起源是为了解决企业应用问题,随着不断演进,发展到目前业界普遍采用的微服务架构,微服务架构如下所示。

在这里插入图片描述
微服务架构的思想就是让服务尽可能做到高内聚、低耦合,不同的服务单独开发、单独测试、单独部署。服务之间通过 RPC 或者 HTTP 进行远程交互,如图中的蓝色加粗箭头所示。

微服务架构解决了单体架构的耦合问题,但同时也带来了新的问题。因为服务部署在不同的进程或服务器中,要使用服务前需要先找到服务,即所谓的服务发现。

一般微服务使用两种发现方式,一种是前面课程介绍过的 RPC 方式,通过注册中心进行服务的注册和订阅,来完成服务发现,比如图中间灰色的 Registry 模块。这种方式由服务的调用端获得到全部可用服务节点,由 Client 侧进行负载均衡,调用服务。另外一种是通过 HTTP 协议调用服务端提供的 RESTful 接口,这种方式不需要 Client 侧做服务发现,而是在 Server 端通过 Nignx 这样的反向代理来提供 Server 侧的负载均衡。

不论哪种方式,服务的交互都从进程内通信变成了远程通信,所以性能必然会受到一些影响。此外由于很多不确定性的因素,例如网络拥塞、Server 端服务器宕机、挖掘机铲断机房光纤等等,需要许多额外的功能和措施才能保证微服务流畅稳定的工作。前面在 Spring Cloud 内容中提到的 Hystrix 熔断器、Ribbon客户端负载均衡器、Eureka注册中心等等都是用来解决这些问题的微服务组件。

CAP 原则与 BASE 理论

在微服务架构中,有必要了解一下分布式系统中的 CAP 原则与 BASE 理论。如下图所示,CAP 原则指的是在一个分布式系统中,Consistency 一致性、 Availability 可用性、Partition tolerance 分区容错性,这三个特性最多只能同时满足两个,三者不可兼得。

在这里插入图片描述
其中一致性指所有节点在同一时间的数据完全一致;可用性指任何时候对分布式系统总是可以成功读和写;分区容错性是指当某些节点或网络分区故障的时候,仍然能够提供满足一致性和可用性的服务。

既然无法同时满足三个特征,那就会有三种取舍。

第一个选择是 CA,就是放弃分区容错,这也就等同于放弃了分布式系统,所以 CA 只存在于单机系统。

第二个选择是 CP,也就是选择强一致和分区容错,允许极端情况下出现短时的服务不可用。采用 CP 原则实现的分布式系统比如 ZooKeeper。ZooKeeper是一个分布式协调系统,强一致性是 ZK 的主要目标,允许出现短时的系统不可用。也正是因为这个原因,ZK 其实并不适合用来做微服务的注册中心。其他选择 CP 实现的系统还有 Consul、etcd 等。

第三个选择是 AP,也就是选择分区容错和高可用,允许数据出现短时间不一致。采用 AP 原则的分布式系统有 Eureka、Nacos。在服务注册的场景,短期的不一致一般不会对服务交互产生影响,因此采用 AP 原则的注册中心才是微服务比较适合的选择。

然后,介绍一下 BASE 理论,如上图底部的词汇所示,BASE 是指 Basically Available 基本可用,Soft-state 软状态,Eventual Consistency 最终一致性,它是对 CAP 中一致性和可用性权衡的结果。BASE 的核心思想是即使无法做到强一致性,也可以根据系统特点,采用适当的方式达到最终一致性。

云原生服务

继续讲解系统架构的演进。微服务架构的思路是服务解耦合,这会导致一个大的业务拆分成众多小的服务,每个服务的部署需要考虑单点问题,需要多机房多节点部署,会造成系统资源的浪费。

另外在服务扩容时需要重新整理服务运行依赖的环境,对微服务的普及有一定阻碍。容器化技术把服务的运行环境进行打包管理,解决了服务扩缩容时对运行环境的管理问题以及服务器的利用率问题。因此随着容器技术逐渐成熟,微服务架构也快速普及。

云原生架构由微服务组成,它不是一种业务系统架构,而是一种能够快速、持续、可靠、规模化地交付业务服务的模式。

如下图所示,图上部列出了云原生的三个特征:

●容器化的微服务,这是云原生的主体;

●Devops,是对微服务的动态管理;

●持续交付能力,这是云原生的目的。

在这里插入图片描述
云原生服务需要底层的云服务提供 IaaS 基础设施或者 PaaS 平台设施来运行,IaaS 可以理解为提供了服务器资源,PaaS 平台可以理解为提供了运行环境。

常见的实现方式有两种:自建的私有云和云厂商提供的公有云。公有云比如阿里云、AWS、腾讯云等等,像新浪微博内部使用的是私有云与公有云结合的混合云模式。

接下来看云原生应用开发的最佳实践原则:12 要素,如下图所示。

在这里插入图片描述
12 要素定义了设计 SaaS 应用时需要遵循的一些基本原则,SaaS 是软件即服务的缩写,通过云原生应用来提供服务。

第 1 个要素是基准代码,是指代码由版本管理工具来管理,一个应用只有一份基准代码,运行时有多个的部署实例。

第 2 个要素依赖,是指要在应用中显示的声明依赖,方便服务进行构建。

第 3 个要素配置,指要在环境中存储配置,而不是写在代码配置文件中。也就是说,配置与代码要分开管理,从代码外部进行加载,例如测试环境的配置、仿真环境的配置以及生产环境的配置都应该从对应的环境中进行加载。

第 4 个要素后端服务,是指要把依赖的后端服务统一看作资源来对待。不论是 DB、缓存还是 HTTP 服务。

第 5 个要素是构建、发布、运行,是指要严格区分应用的构建、发布、运行这三个步骤,并且必须按顺序进行。

第 6 个要素进程,是指应用以一个或多个进程运行,要保证应用的无状态性。

第 7 个要素端口绑定,是指不同的应用使用不同的端口提供服务。应用与端口是绑定的,不是指具体的某个端口号,而是指一旦服务启动确定了端口,那么这个端口就能够提供对应的服务,直到应用进程停止。

第 8 个要素并发,是指应用进程之间可以并发处理,因此可以通过多进程方式进行水平扩展。

第 9 个要素易处理,是指应用应该容易被管理,可以通过优雅停机和快速启动,构建最健壮的服务。

第 10 个要素开发/生产等价,是指要保证在开发、预览、生产等不同环境下的应用,尽可能一致。

第 11 个要素日志,是指要合理记录应用的运行日志,并把日志当作一种事件流来对待,方便对日志的收集和处理。

第 12 个要素管理进程,是指要把后台管理任务当作一次性进程来运行,而不是常驻后台进程的方式。

以上 12 要素是对设计云原生服务的指导原则,在实际项目中可以结合实际业务场景进行架构设计,不一定完全照搬。

Service Mesh

云原生应用是目前大部分互联网公司的服务架构推进方向,那么下一代的服务架构是什么样呢?这里介绍一个最新的服务化趋势,它离实际应用可能还有些遥远,我们可以静待它的发展。

Service Mesh 是 2017 年逐渐在国内进入大家视野的一种架构方式,被誉为下一代的微服务。Service Mesh 在微服务的基础上引入了一个 Sidecar 边车的概念,如图中左下方的放大图所示,每个服务会伴生着部署一个 Sidecar,服务之间的交互不再由服务自身来完成,服务所有的出、入请求都交由这个 Sidecar 来进行处理,通过管理平面对所有的 Sidecar 进行统一管理,由 Sidecar 来实现服务发现、负载均衡、流量调度等能力。

在这里插入图片描述
目前最有代表性的 Service Mesh 开源实现,是由 Google、IBM、Lyft 三家一起维护的 Istio,有兴趣的话可以持续关注,这里就不详细展开了。

那么 Service Mesh 与微服务的区别是什么呢?Service Mesh 又可以解决哪些问题呢?如下图所示。

在这里插入图片描述
微服务的出现是为了解决多个服务之间耦合的问题,如图中绿色的竖线,就是微服务架构做的事情,把 Service A、B、C 进行了解耦,服务单独部署、单独管理。这时每个服务都需要实现例如服务发现、服务的远程交互、交互过程中的负载均衡、高可用策略、服务熔断等等一系列的功能,这些功能与服务自身的业务逻辑没有任何关系。

Service Mesh 的思路是把业务逻辑与业务无关的功能进行解耦,如图中红色的线,对服务进行横切,把与服务交互相关的功能从服务中剥离出来,统一交给 Sidecar 去实现,让服务更聚焦于业务逻辑,提高研发效率。同时由于功能相对独立,Sidecar 可以更专注于服务的交互与管理,更方便实现极致的功能与性能。

所以,Service Mesh 不是一个全新的技术,它对业务与服务交互、管理进行了拆分,提供统一、强大的服务管理能力,是在微服务基础上的演进。

另外,Service Mesh 由于使用独立的 Sidecar 进程,天然适合为不同语言的服务提供统一的服务治理能力,因此跨语言服务治理也是 Service Mesh 的一个重要特点,像微博基于 Motan 研发的 Weibo Mesh,初衷就是为了解决内部不同语言之间服务化的问题。

由于引入了额外的 Sidecar,Service Mesh 的架构复杂度更高,也会带来额外的可用性和性能问题,这也是 Service Mesh 架构需要努力解决的问题。

架构设计的意义

通过了解系统架构的演进,我们发现,从单体架构到微服务架构,实现了服务之间解耦,但带来了额外的服务发现与交互问题;从微服务到 Service Mesh,实现了业务与服务治理功能的解耦,但是引入了额外的可用性和性能问题,架构复杂度也随之提高。那么这样做的意义在哪里?

系统架构的设计从来就是一个权衡的艺术,很多情况下,我们只是让问题进行了转移,方便对问题进行集中整治和处理,让服务更聚焦业务研发,不同的功能就交给专门的组件来处理,正所谓术业有专攻。通过架构的演进,虽然当下没有消灭复杂度,但可以成功的让问题变的透明化,变的业务无感知,提升服务整体的开发效率与扩展能力,拓宽服务能力的上限。

容器化基础

微服务之所以能够快速发展,很重要的一个原因就是:容器化技术的发展和容器管理系统的成熟。所以接下来学习微服务架构的基础,容器化技术 Docker 和容器集群管理系统 Kubernetes。

Docker 作用

Docker 的作用主要是快速的构建、部署、运行服务,通过服务镜像能够为服务提供版本管理。

通过容器化技术可以屏蔽不同运行环境的差异,让服务在任何 Docker 环境中运行,就像 Java 的一次编译到处运行。

Docker 是轻量虚拟化技术,可以在一台宿主机上运行多个服务,对运行的服务之间进行了有效的隔离,提高宿主机的资源利用率。

Docker 特点

1.开源,意味着可以免费使用 Docker 容器技术。

2.基于 LXC 实现的轻量虚拟化,Docker 容器直接运行进程,不需要模拟,运行效率非常高。

3.能够支持大规模构建。

4.Docker 的架构十分灵活,可扩展不同的实现,例如支持不同存储驱动实现。

5.Docker 提供可视化 UI,管理非常简单。

Docker 主要概念

1.镜像,就是服务代码和运行环境的封装,服务的版本管理就是通过镜像来实现的,镜像是部署的基础。

2.容器,就是 Container,容器是基于镜像的服务运行状态,可以基于一个镜像运行多个容器。

3.守护进程是运行在宿主机上的管理进程,用户通过 Client 与守护进程进行交互。

4.客户端是用来和守护进程交互的命令行工具,也可以通过 Socket 或者 RESTful API 访问远程的 Docker 守护进程。

5.镜像仓库,类似我们的 Git 代码仓库,镜像仓库用来保存、管理不同服务不同版本的镜像。服务部署时会从镜像仓库拉取对应版本的镜像进行部署。

Docker 实现原理

Docker 是通过对不同运行进程进行隔离来实现虚拟化,主要利用三种方式来实现服务的隔离,如下图所示。

在这里插入图片描述
首先是利用 Linux 的 Namespace 命名空间,来隔离进程之间的可见性,不同的服务进程彼此属于不同的 Namespace,互相无法感知对方的存在。

Docker 实现了 Host、Container、None 和 Bridge 四种网络模式,默认使用 Bridge 桥接模式。每一个容器在创建时都会创建一对虚拟网卡,两个虚拟网卡组成了数据的通道,其中一个会放在容器中,另一个会加入到 Docker0 的网桥中。Docker0 网桥通过 iptables 中的配置与宿主机上的网卡相连,所有符合条件的请求都会通过 iptables 转发到 Docker0 并由网桥分发给对应的容器网卡。为了防止容器进程修改宿主机的文件目录,Docker 通过改变进程访问文件目录的根节点,结合 Namespace 来隔离不同容器进程可以访问的文件目录。

然后,通过 Namespace,Docker 隔离了进程、网络和文件目录,但是在进程运行中的 CPU 和内存等还是共享状态。Docker 通过 Control Groups 也就是 Cgroups 来对进程使用的资源进行限制,包括 CPU、内存和网络带宽等。

那么,Docker 是如何把镜像运行起来的呢?Docker 的镜像是分层结构,例如一个服务镜像可以由操作系统层、基础环境层、Web 容器层、服务代码层,层层依赖构成。通过 UnionFS 就是联合文件系统把 Image 中的不同分层作为不同的只读目录,而 Container 是在只读的镜像目录上创建的可读可写的目录,通过这种方式来把镜像运行起来的。Docker 提供了 AUFS、Overlay、Devicemapper、ZFS 等多种不同存储驱动实现。

Kubernetes 作用

Kubernetes 也叫 K8s,因为 K 与 s 之间一共有 8 个字母。K8s 是一个容器集群管理系统,不是一个 PaaS 平台,PaaS 平台是可以运行在 K8s 之上的。

K8s 的作用是进行容器集群管理,它只针对容器管理,不部署源码不编译应用。它能够实现服务容器的自动部署与按指定条件进行自动扩缩容服务,来实现对应用的管理,支持应用的负载均衡、滚动更新、资源监控等等。

Kubernetes 特点

1.可移植,支持在公有云,私有云,混合云中运行;

2.可扩展,K8s 采用模块化实现方式,插件化的架构,可挂载,可组合;

3.自动化,支持服务的自动部署,自动重启,自动复制,自动伸缩。

Kubernetes 重要概念

K8s 中的概念非常的多,这里列出了比较重要的几个。

K8s 是容器集群管理系统,容器首先需要运行在宿主机上,因此,K8s 首先要管理宿主机集群,K8s 分为 Master 节点和 Node 节点,也叫 Worker Node。

Master 负责管理节点,管理 K8s 集群。Master 协调集群中的所有行为/活动,例如应用的运行、修改、更新等。

Node 节点用来运行容器。Node 上可以运行多个 Pod,Pod 是 K8s 创建或部署的基本单位,Pod 中可以运行多个 Container,一个 Container 就是一个运行中的服务镜像。

Pod 中的 Container 共享网络与存储。

Service 是 K8s 中的一个逻辑概念,通过对不同的 Pod 添加标签,来划分为不同的 Service。

Deployment 表示用户对 K8s 集群的一次更新操作,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。

Kubernetes 架构

下图是 K8s 架构图,图左侧绿色的模块代表 Master 节点,右侧蓝色的模块代表运行容器的Worker Node 节点。

在这里插入图片描述
先来看 Master 节点中的架构,灰色的部分是 Master 中的模块,其中 API Server 是用户对 K8s 中资源操作的唯一入口,创建应用部署、管理部署状态等都需要通过 api server 进行。API Server 提供了认证、授权、访问控制、API 注册和发现等机制。

Controller Manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等,Controller Manager 包含多个可以扩展 Controller,例如 Node Controller 负责初始化 Node 节点,获取运行中的 Node 信息、Route Controller 负责配置集群间通信的路由信息、Service Controller 负责监听服务创建、更新、删除等事件来调整负载均衡信息等等。

Scheduler 负责资源的调度,按照预定的调度策略选择哪个 Pod 运行在哪个节点上。

另外图下方的绿色模块是用来保存整个集群的状态的 etcd。

图最左侧的 kubectl 是用于运行 K8s 命令的管理工具,kubectl 与 API Server 进行交互,通过 API Server 下发对 K8s 集群的指令。

再来看图右侧的 Worker Node。刚才介绍概念时提过,Node 用来运行应用容器,所以 Node 中必须要有一个容器运行时,可以是 Docker,也可以是其他的容器技术,例如 Rkt。

Node 中部署应用时,每个应用都由一个 Pod 组成,可以把 Pod 看作一个虚拟服务器,上面可以运行一个或多个 Container 容器。当应用服务需要多个进程共同协作时,可以把这些协作的镜像打包放在一个 Pod 中,共享 Pod 的存储和网络。比如 istio 中的 Sidecar 代理模式,就是通过在服务的 Pod 中注入一个 Sidecar 镜像来实现与服务 IP 绑定,进行流量控制的。

看到右面图中灰色的两个 Node 模块,kubelet 负责与 Master 通信,它周期性地访问 APIcontroller 进行检查和报告、执行容器的操作,维护容器的生命周期,也负责 Volume(CVI)和网络(CNI)的管理。

kube-proxy 处理网络代理和每个容器的负载均衡,它通过改变 iptables 规则来控制在容器上的 TCP 和 UDP 包。

K8s 把所有被管理的资源看作对象,对资源的管理就变成了对对象属性的设置。K8s 对对象的配置采用 YAML 格式进行描述。K8s 中的对象概念非常多,大致可以分为四类:

●资源对象,例如 Pod、Job;

●配置对象,例如 Node、Namespace、Service;

●存储对象,例如 Volume、PresidentVolume;

●策略对象,例如 SecurityContext、ResourceQuota、LimitRange 等等。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Andrew.J

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

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

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

打赏作者

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

抵扣说明:

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

余额充值