老男孩微服务kubernetesspring cloud架构工程师怎么样 值得学吗?

北京 电子工业出版社 2020

互联网络 网络服务器

本书采用“知识点+实例”形式编写,共有“39个基于知识点的实例+1个综合性项目”,讲解了Spring Cloud的各类组件、微服务架构的解决方案和开发实践,以及容器、Kubernetes和Jenkins等DevOps(开发运维一体化)相关知识。

}

云架构师负责管理一个组织中的云计算架构,特别是随着云技术日益复杂化。云计算架构涵盖了与云计算相关的一切,包括管理云存储所需的前端平台、服务器、存储、交付和网络。

本文作者从如下几个方面全面剖析云架构师的进阶攻略:

  • 架构的三个维度和六个层面
  • 了解云计算的历史演进与基本原理
  • 了解数据中心和网络基础知识
  • 基于 KVM 了解计算虚拟化

架构的三个维度和六个层面

在互联网时代,要做好一个合格的云架构师,需要熟悉三大架构。

IT 架构其实就是计算,网络,存储。这是云架构师的基本功,也是最传统的云架构师应该首先掌握的部分。

良好设计的 IT 架构,可以降低 CAPEX 和 OPEX,减轻运维的负担。数据中心,虚拟化,云平台,容器平台都属于 IT 架构的范畴。

随着应用从传统应用向互联网应用转型,仅仅搞定资源层面的弹性还不够,常常会出现创建了大批机器,仍然撑不住高并发流量。因而基于微服务的互联网架构,越来越成为云架构师所必需的技能。

良好设计的应用架构,可以实现快速迭代和高并发。数据库,缓存,消息队列等 PaaS,以及基于 Spring Cloud 和 Dubbo 的微服务框架,都属于应用架构的范畴。

数据成为人工智能时代的核心资产,在做互联网化转型的同时,往往进行的也是数字化转型,并有战略的进行数据收集,这就需要云架构师同时有大数据思维。

有意识的建设统一的数据平台,并给予数据进行数字化运营。搜索引擎,Hadoop,Spark,人工智能都属于数据架构的范畴。

上面的三个维度是从人的角度出发的,如果从系统的角度出发,架构分六个层次。

在数据中心里面,会有大量的机架,大量的服务器,并通过交换机和路由器将服务器连接起来,有的应用例如 Oracle 是需要部署在物理机上的。

为了管理的方便,在物理机之上会部署虚拟化,例如 Vmware,可以将对于物理机复杂的运维简化为虚拟机灵活的运维。

虚拟化采取的运维方式多是由运维部门统一管理,当一个公司里面部门非常多的时候,往往要引入良好的租户管理。

基于 Quota 和 QoS 的资源控制,基于 VPC 的网络规划等,实现从运维集中管理到租户自助使用模式的转换,托生于公有云的 OpenStack 在这方面做的是比较好的。

随着应用架构越来越重要,对于标准化交付和弹性伸缩的需求越来越大,容器做为软件交付的集装箱,可以实现基于镜像的跨环境迁移,Kubernetes 是容器管理平台的事实标准。

数据层,也即一个应用的中军大营,如果是传统应用,可能会使用 Oracle,并使用大量的存储过程,有大量的表联合查询,成本也往往比较高。

但是对于高并发的互联网应用,需要进行微服务的拆分,数据库实例会比较多,使用开源的 MySQL 是常见的选择。

大量的存储过程和联合查询往往会使得微服务无法拆分,性能会比较差,因而需要放到应用层去做复杂的业务逻辑,而且数据库表和索引的设计非常重要。

当并发量比较大的时候,需要实现横向扩展,就需要基于分布式数据库,也是需要基于单库良好的表和索引设计。

对于结构比较灵活的数据,可以使用 MongoDB 数据库,横向扩展能力比较好。

对于大量的联合查询需求,可以使用 ElasticSearch 之类的搜索引擎来做,速度快,更加灵活。

因为数据库层往往需要保证数据的不丢失以及一些事务,因而并发性能不可能非常大。

所以我们经常说,数据库是中军大营,不能所有的请求都到这里来,因而需要一层缓存层,用来拦截大部分的热点请求。

Memcached 适合做简单的 key-value 存储,内存使用率比较高,而且由于是多核处理,对于比较大的数据,性能较好。

但是缺点也比较明显,Memcached 严格来讲没有集群机制,横向扩展完全靠客户端来实现。

另外 Memcached 无法持久化,一旦挂了数据就都丢失了,如果想实现高可用,也是需要客户端进行双写才可以。

Redis 的数据结构比较丰富,提供持久化的功能,提供成熟的主备同步,故障切换的功能,从而保证了高可用性。

另外微服务拆分以后,有时候处理一个订单要经过非常多的服务,处理过程会比较慢,这个时候需要使用消息队列,让服务之间的调用变成对于消息的订阅,实现异步处理。

RabbitMQ 和 Kafka 是常用的消息队列,当事件比较重要的时候,会结合数据库实现可靠消息队列。

有的时候成为中台层,将通用的能力抽象为服务对外提供原子化接口。

这样上层可以根据业务需求,通过灵活的组合这些原子化接口,灵活的应对业务需求的变化,实现能力的复用,以及数据的统一管理,例如用户数据,支付数据,不会分散到各个应用中。

另外基础服务层称为应用、数据库和缓存的一个分界线,不应该所有的应用都直接连数据库,一旦出现分库分表,数据库迁移,缓存选型改变等,影响面会非常大,几乎无法执行。

如果将这些底层的变更拦截在基础服务层,上层仅仅使用基础服务层的接口,这样底层的变化会对上层透明,可以逐步演进。

业务服务层或者组合服务层

大部分的业务逻辑都是在这个层面实现,业务逻辑比较面向用户,因而会经常改变,所以需要组合基础服务的接口进行实现。

在这一层,会经常进行服务的拆分,实现开发独立,上线独立,扩容独立,容灾降级独立。

微服务的拆分不应该是一个运动,而应该是一个遇到耦合痛点的时候,不断解决,不断演进的一个过程。

微服务拆分之后,有时候需要通过分布式事务,保证多个操作的原子性,也是在组合服务层来实现的。

用户接口层,也即对终端客户呈现出来的界面和 App,但是却不仅仅是界面这么简单。

这一层有时候称为接入层。在这一层,动态资源和静态资源应该分离,静态资源应该在接入层做缓存,使用 CDN 进行缓存。

也应该 UI 和 API 分离,界面应该通过组合 API 进行数据拼装。API 会通过统一的 API 网关进行统一的管理和治理。

一方面后端组合服务层的拆分对 APP 是透明的;另一方面当并发量比较大的时候,可以在这一层实现限流和降级。

为了支撑这六个层次,在上图的左侧是一些公共能力:

  • 持续集成和持续发布是保证微服务拆分过程中的快速迭代,以及变更后保证功能不变的,不引入新的 Bug。
  • 服务发现和服务治理是微服务之间互相的调用,以及调用过程中出现异常情况下的熔断,限流,降级策略。
  • 大数据和人工智能是通过收集各个层面的数据,例如用户访问数据,用户下单数据,客服询问数据等,结合统一的中台,对数据进行分析,实现智能推荐。
  • 监控与 APM 是基础设施的监控和应用的监控,发现资源层面的问题以及应用调用的问题。

作为一个云架构师还是很复杂的,千里之行,始于足下,让我们慢慢来。

了解云计算的历史演进与基本原理

在一头扎进云计算的汪洋大海之前,我们应该先有一个全貌的了解,有人说了解一个知识的起点,就是了解它的历史,也就是知道它是如何一步一步到今天的,这样如此庞大的一个体系,其实是逐步加进来的。

这样的知识体系对我们来说,就不是一个冷冰冰的知识网,而是一个有血有肉的人,我们只要沿着演进的线索,一步一步摸清楚“它”的脾气就可以了。

如何把云计算讲的通俗易懂,我本人思考了半天,最终写下了下面这篇文章:终于有人把云计算、大数据和人工智能讲明白了!在这里,我把核心的要点在这里写一下。

第一:云计算的本质是实现从资源到架构的全面弹性。

所谓的弹性就是时间灵活性和空间灵活性,也即想什么时候要就什么时候要,想要多少就要多少。

资源层面的弹性也即实现计算、网络、存储资源的弹性。这个过程经历了从物理机,到虚拟化,到云计算的一个演进过程。

架构层面的弹性也即实现通用应用和自有应用的弹性扩展。对于通用的应用,多集成为 PaaS 平台。

对于自己的应用,通过基于脚本的 Puppet、Chef、Ansible 到基于容器镜像的容器平台 CaaS。

第二:大数据包含数据的收集,数据的传输,数据的存储,数据的处理和分析,数据的检索和挖掘等几个过程。

当数据量很小时,很少的几台机器就能解决。慢慢的,当数据量越来越大,最牛的服务器都解决不了问题时,怎么办呢?

这时就要聚合多台机器的力量,大家齐心协力一起把这个事搞定,众人拾柴火焰高。

第三:人工智能经历了基于专家系统的计划经济,基于统计的宏观调控,基于神经网络的微观经济学三个阶段。

架构师除了要掌握大的架构和理论之外,指导落地也是必备的技能,所谓既要懂设计模式,也要懂代码。那从哪里去学习这些良好的,有借鉴意义的,可以落地的架构实践呢?

这个世界上还是有很多有情怀的大牛的,尤其是程序员里面,他们喜欢做一件什么事情呢?答案是开源。很多软件都是有闭源就有开源,源就是源代码。

当某个软件做的好,所有人都爱用,这个软件的代码呢,我封闭起来只有我公司知道,其他人不知道,如果其他人想用这个软件,就要付我钱,这就叫闭源。但是世界上总有一些大牛看不惯钱都让一家赚了去。

大牛们觉得,这个技术你会我也会,你能开发出来,我也能,我开发出来就是不收钱,把代码拿出来分享给大家,全世界谁用都可以,所有的人都可以享受到好处,这个叫做开源。

非常建议大家了解,深入研究,甚至参与贡献开源软件,因为收益匪浅。

第一:通过开源软件,我们可以了解大牛们的架构原则,设计模式。

其实咱们平时的工作中,是很难碰到大牛的,他可能是你渴望而不可及的公司的员工,甚至在国外,你要想进这种公司,不刷个几年题目,面试个 N 轮是进不去的。

即便进去了,他可能是公司的高层,每天很忙,不怎么见得到他,就算当面讨教,时间也不会很长,很难深入交流。

也有的大牛会选择自主创业,或者是自由职业者,神龙见首不见尾,到了大公司都见不到。

但是感谢互联网和开源社区,将大牛们拉到了我们身边,你可以订阅邮件组,可以加入讨论群,可以看到大牛们的设计,看到很多人的评论,提问,还有大牛的回答,可以看到大牛的设计也不是一蹴而就完美的,看到逐渐演进的过程,等等。

这些都是能够帮助我们快速提升水平的地方,有的时候,拿到一篇设计,都要查资料看半天,一开始都可能好多的术语都看不懂,没关系肯下功夫,当你看 blueprints 越来越顺畅的时候,你就进步了。

第二:通过开源软件,我们可以学习到代码级的落地实践。

有时候我们能看到很多大牛写的书和文章,也能看到很多理论的书籍,但是存在一个问题是,理论都懂,但是还是做不好架构。

这是因为没有看到代码,所有的理论都是空中楼阁,当你到了具体的代码设计层面,那些学会的设计模式,无法转化为你自己的实践。

好在开源软件的代码都是公开的,凝结了大牛的心血,也能够看到大牛在具体落地时候的取舍,一切那么真实,看得见,摸得着。

通过代码进行学习,配合理论知识,更容易获得第一手的经验,并且在自己做设计和写代码的时候,马上能够映射到可以参考的场景,让我们在做自己的系统的时候,少走弯路。

第三:通过开源软件,我们可以加入社区,和其他技术人员在同一背景下共同进步。

大牛我们往往不容易接触到,正面讨论技术问题的时间更是难能可贵,但是没有关系,开源软件构建了一个社区,大家可以在一起讨论。

你是怎么理解的,别人是怎么理解的,越讨论越交流,越明晰,有时候和比你经验稍微丰富一点的技术人员交流,可能比直接和大牛对话更加有直接作用。

大牛的话可能让你消化半天,依然不知所云,大牛可能觉得很多普通人觉得的难点是显而易见的,不屑去解释。

但是社区里面的技术人员,可能和你一样慢慢进步过来的,知道哪些点是当年自己困惑的,如果踩过这一个个的坑,他们一点拨,你就会豁然开朗。

而且每个人遇到的具体情况不同,从事的行业不同,客户的需求不同,因而软件设计的时候考虑的因素不同。

大牛是牛,但是不一定能够遇到和你一样的场景,但是社区里面,有你的同行业的,背景相近的技术人员,你们可以讨论出符合你们特定场景的解决方案。

第四:通过开源软件,我们作为个人,比较容易找到工作。

我们面试的时候,常常遇到的问题是,怎么能够把在原来工作中自己的贡献,理解,设计,技术能力展现出来。

其实我发现很多程序员不能很好的做到这一点,所以造成很多人面试很吃亏。

原因之一:背景信息不对称。例如原来面临的业务上很难的问题,面试官由于不理解背景,而且短时间解释不清楚,轻视候选人的水平。

我也遇到过很多面试官才听了几分钟,就会说,这不挺简单的,你这样这样不就行了,然后彻底否定你们一个团队忙了三年的事情。

原因之二:很多有能力的程序员不会表达,导致真正写代码的说不明白。可能原来在公司里面一个绩效非常好,一个绩效非常差,但是到了面试官那里就拉平了。

原因之三:新的公司不能确定你在上家公司做的工作,到这一家都能用的。例如你做的工作有 30% 是和具体业务场景相关的,70% 是通用技术,可能下家公司只会为你的通用技术部分买单。

开源软件的好处就是,参与的人所掌握的技能都是通的,而且大家在同一个上下文里面对话,面试官和候选人之间的信息差比较少。掌握某个开源软件有多难,不用候选人自己说,大家心里都有数。

代码呈上去,就能够表现出实力来了,而且面试官也不需要根据短短的半个小时了解一个人,可以做很多背景调查。

另外由于掌握的技术是通用的,你到下一家公司,马上就能够上手,几乎不需要预热时间,对于双方都有好处。

第五:通过开源软件,我们作为招聘方,比较容易招到相应人员。

如果在创业公司待过的朋友会了解到创业公司招人很难,人员流失很快,而且创业公司往往对于开发进度要求很快,因为大家都在抢时间。

因而开源软件对于招聘方来讲,也是好消息。首先创业公司没办法像大公司一样,弄这么多的技术大牛,自己完全落地一套自己的体系,使用开源软件快速搭建一套平台先上线是最好的选择。

其次使用开源软件,会使得招聘相对容易,市场上火的开源软件会有大批的从业者,参与各种论坛和社区,比较容易挖到人。

最后,开源软件的使用使得新人来了之后没有预热时间,来了就上手,保证开发速度。

那如何快速上手一款开源软件呢?我总结了如下九个步骤:

  • 手动安装起来,一定要手动。
  • 读文档,读所有的官方文档,记不住,看不懂也要读下来。
  • 看一本源码分析的书,会让你的源码阅读之旅事半功倍。
  • 开始阅读核心逻辑源代码。
  • 开发一个插件,或者对组件做少量的修改。
  • 大量的运维实践经验和面向真实场景的定制开发。
  • 所以做一个云架构师,一定不能脱离代码,反而要不断的拥抱开源软件。

作为一个云架构师,首要的一点,就是要熟悉 Linux 的基础知识,基本原理了。

说到操作系统,一般有三个维度:

当然因为办公的原因,平时使用 Windows 的比较多,所以在学校里,很多同学接触到的操作系统基本上都是 Windows,但是一旦从事计算机行业,就一定要跨过 Linux 这道坎。

从这个统计可以看出,随着云计算的发展,软件 SaaS 化,服务化,甚至微服务化,大部分的计算都是在服务端做的,因而要成为云架构师,就必须懂 Linux。

随着移动互联网的发展,客户端基本上以 Android 和 iOS 为主,下图是 Gartner 的统计。

Android 是基于 Linux 内核的。因而客户端也进入了 Linux 阵营,很多智能终端,智能设备等开发职位,都需要懂 Linux 的人员。

学习 Linux 主要包含两部分,一个是怎么用,一个是怎么编程,背后原理是什么。

对于怎么用,上手的话,推荐《鸟哥的 Linux 私房菜》,按着这个手册,就能够学会基本的 Linux 的使用,如果再深入一点,推荐《Linux 系统管理技术手册》,砖头厚的一本书,是 Linux 运维手边必备。

对于怎么编程,上手的话,推荐《Unix 环境高级编程》,有代码,有介绍,有原理,如果对内核的原理感兴趣,推荐《深入理解 Linux 内核》。

Linux 的架构如下图:

我们知道,一台物理机上有很多的硬件,最重要的是 CPU,内存,硬盘,网络,但是一个物理机上要跑很多的程序,这些资源应该给谁用呢?当然是大家轮着用,谁也别独占,谁也别饿死。

为了完成这件事情,操作系统的内核就起到了大管家的作用,将硬件资源分配给不同的用户程序使用,并且在适当的时间将资源拿回来,再分配给其他的用户进程,这个过程称为调度。

操作系统的功能之一:系统调用

当用户程序想请求资源的时候,需要调用操作系统的系统调用接口,这是内核和用户态程序的分界线。

就像你要打车,要通过打车软件的界面,下发打车指令一样,这样打车软件才会给你调度一辆车。

操作系统的功能之二:进程管理

当一个用户进程运行的时候,内核为它分配的资源,总要有一个数据结构保存,哪些资源分配给了这个进程。分配给这个进程的资源往往包括打开的文件,内存空间等。

操作系统的功能之三:内存管理

每个进程有独立的内存空间,内存空间是进程用来存放数据的,就像一间一间的仓库。

为了进程使用方便,每个进程内存空间,在进程的角度来看都是独立的,也即都是从 0 号仓库,1 号仓库,一直到 N 号仓库,都是独享的。

但是从操作系统内核的角度来看,当然不可能独享,而是大家共享,M 号仓库只有一个,你用他就不能用,这就需要一个仓库调度系统,将用户进程的仓库号和实际使用的仓库号对应起来。

例如进程 1 的 10 号仓库,对应到真实的仓库是 110 号,进程 2 的 20 号仓库,对应到真实的仓库是 120 号。

操作系统功能之四:文件系统

对于 Linux 来讲,很多东西都是文件,例如进程号会对应一个文件,建立一个网络连接也对应一个文件。文件系统多种多样,为了能够统一适配,有一个虚拟文件系统的中间层 VFS。

操作系统功能之五:设备管理

设备分两种,一种是块设备,一种是字符设备,例如硬盘就是块设备,可以格式化为文件系统,再如鼠标和键盘的输入输出是字符设备。

操作系统功能之六:网络管理

对于 Linux 来讲,网络也是基于设备和文件系统的,但是由于网络有自己的协议栈,要遵循 TCP/IP 协议栈标准。

了解数据中心和网络基础知识

云平台当然会部署在数据中心里面,由于数据中心里面的硬件设备也是非常专业的,因而很多地方机房部门和云计算部门是两个部门。

但是作为一个云架构师,需要和机房部门进行沟通,因而需要一定的数据中心知识,在数据中心里面,最难搞定的是网络,因而这里面网络知识是重中之重。

下面这个图是一个典型的数据中心图:

  • 提供高可用性连接 HA。

第三层是 Access Layer,就是一个个机架的服务器,用接入交换机连接在一起。

这是一个典型的三层网络结构,也即接入层、汇聚层、核心层三层。除了数据中心以外,哪怕是做应用架构,对于网络的了解也是必须的。

云架构说到底是分布式架构,既然是分布式,就是去中心化的,因而就需要系统之间通过网络进行互通,因而网络是作为大规模系统架构绕不过去的一个坎。

对于网络的基本原理,推荐书籍《计算机网络-严伟与潘爱民译》,《计算机网络:自顶向下方法》。

对于网络程序设计,推荐书籍《Unix 网络编程》,如果你想了解网络协议栈的实现,推荐书籍《深入理解 Linux 网络内幕》 。

基于 KVM 了解计算虚拟化

当物理机搭建完毕之后,接下来就是基于物理机上面搭建虚拟机了。

没有了解虚拟机的同学,可以在自己的笔记本电脑上用 VirtualBox 或者 Vmware 创建虚拟机,你会发现,很容易就能在物理机的操作系统之内再安装多个操作系统。

通过这种方式,你可以很方便的在 Windows 办公系统之内安装一个 Linux 系统,从而保持 Linux 系统的持续学习。

前面讲 Linux 操作系统的时候,说到操作系统,就是整个系统的管家。应用程序要申请资源,都需要通过操作系统的系统调用接口,向操作系统内核申请将 CPU,内存,网络,硬盘等资源分配给他。

这时候你会发现,虚拟机也是物理机上的一个普通进程,当虚拟机内部的应用程序申请资源的时候,需要向虚拟机的操作系统请求。

然而虚拟机的操作系统自己本身也没有权限操作资源,因而又需要像物理机的操作系统申请资源。

这中间要多一次翻译的工作,完成这件事情的称为虚拟化软件。例如上面说的 VirtualBox 和 Vmware 都是虚拟化软件。

但是多一层翻译,就多一层性能损耗,如果虚拟机里面的每一个操作都要翻译,都不能直接操作硬件,性能就会差很多,简直没办法用,于是就出现了上图中的硬件辅助虚拟化,也即通过硬件的特殊配置。

例如 VT-x 和 VT-d 等,让虚拟机里面的操作系统知道,它不是一个原生的操作系统了,是一个虚拟机的操作系统,不能按照原来的模式操作资源了,而是通过特殊的驱动以硬件辅助的方式抄近道操作物理资源。

刚才说的是桌面虚拟化,也就是在你的笔记本电脑上,在数据中心里面,也可以使用 Vmware 进行虚拟化,但是价格比较贵,如果规模比较大,会采取开源的虚拟化软件 qemu-kvm。

对于 qemu-kvm 来说,和上面的原理是一样的,其中 qemu 的 emu 是 emulator 的意思,也即模拟器,就是翻译的意思。

KVM 是一个可以使用 CPU 的硬件辅助虚拟化的方式,而网络和存储的,需要通过特殊的 virtio 的方式,提供高性能的设备虚拟化功能。

另外 KVM 和 qemu 的官方文档也是必须要看的,还有 Redhat 的官网很多文章非常值得学习。

当虚拟机创建出来了,最主要的诉求就是要能上网,它能访问到网上的资源,如果虚拟机里面部署一个网站,也希望别人能够访问到它。

这一方面依赖于 qemu-KVM 的网络虚拟化,将网络包从虚拟机里面传播到虚拟机外面,这需要物理机内核转换一把,形成虚拟机内部的网卡和虚拟机外部的虚拟网卡。

另外一方面就是虚拟机的网络如何能够连接到物理网络里面。物理网络常常称为 underlay network,虚拟网络常常称为 overlay network。

从物理网络到虚拟网络称为网络虚拟化,能非常好的完成这件事情的是一个叫 Openvswitch 的虚拟交换机软件。

Openvswitch 会有一个内核驱动,监听物理网卡,可以将物理网卡上收到的包拿进来。

虚拟机创建出来的外部的虚拟网卡也可以添加到 Openvswitch 上,而 Openvswitch 可以设定各种的网络包处理策略,将网络包在虚拟机和物理机之间进行传递,从而实现了网络虚拟化。

对于 Openvswitch,我主要是通过官方文档进行研究。

当有了虚拟机,并且虚拟机能够上网了之后,接下来就是搭建云平台的时候了。

云是基于计算,网络,存储虚拟化技术的,云和虚拟化的主要区别在于,管理员的管理模式不同,用户的使用模式也不同。

虚拟化平台没有多层次的丰富的租户管理,没有灵活 quota 配额的限制,没有灵活的 QoS 的限制。

多采用虚拟网络和物理网络打平的桥接模式,虚拟机直接使用机房网络,没有虚拟子网 VPC 的概念,虚拟网络的管理和隔离不能和租户隔离完全映射起来。

对于存储也是,公司采购了统一的存储,也不能和租户的隔离完全映射起来。

使用虚拟化平台的特点是,对于这个平台的操作完全由运维部门统一管理,而不能将权限下放给业务部门自己进行操作。

因为一旦允许不同的部门自己操作,大家都用机房网络,在没有统一管控的情况下,很容易网段冲突了。

如果业务部门想申请虚拟机,需要通过工单向运维部门提统一的申请。当然这个运维部门很适应这种方式,因为原来物理机就是这样管理的。

但是公有云,例如 AWS 就没办法这样,租户千千万万,只能他们自己操作。

在私有云里面,随着服务化甚至微服务化的进行,服务数目越来越多,迭代速度越来越快,业务部门需要更加频繁的创建和消耗虚拟机,如果还是由运维部统一审批,统一操作,会使得运维部门压力非常大。

而且还会极大限制了迭代速度,因而要引入租户管理,运维部灵活配置每个租户的配额 quota 和 QoS,在这个配额里面,业务部门随时可以按照自己的需要,创建和删除虚拟机,无需知会运维部门。

每个部门都可以创建自己的虚拟网络 VPC,不同租户的 VPC 之前完全隔离。

所以网段可以冲突,每个业务部门自己规划自己的网络架构,只有少数的机器需要被外网或者机房访问的时候,需要少数的机房 IP。

这个也是和租户映射起来的,可以在分配给业务部门机房网 IP 的个数范围内,自由的使用。这样每个部门自主操作,迭代速度就能够加快了。

云平台中的开源软件的代表是 OpenStack,建议大家研究 OpenStack 的设计机制,是在云里面通用的,了解了 OpenStack,对于公有云,容器云,都能发现相似的概念和机制。

通过我们研究 OpenStack,我们会发现很多非常好的云平台设计模式。

如果我们要实现一个 Restful API,希望有个统一的认证中心的话,Keystone 的三角形工作模式是常用的。

当我们要访问一个资源,通过用户名密码或者 AK/SK 登录之后,如果认证通过,接下来对于资源的访问,不应该总带着用户名密码,而是登录的时候形成一个 Token,然后访问资源的时候带着 Token,服务端通过 Token 去认证中心进行验证即可。

如果每次验证都去认证中心,效率比较差,后来就有了 PKI Token,也即 Token 解密出来是一个有详细租户信息的字符串,这样本地就可以进行认证和鉴权。

对于权限控制,我们学会比较通用的 Role Based Access Control 的权限控制模式, 形成“用户-角色-权限”的授权模型。

在这种模型中,用户与角色之间,角色与权限之间,一般两者是多对多的关系,可以非常灵活的控制权限。

第三:基于 Quota 的配额管理

可以通过设置计算,网络,存储的 quota,设置某个租户自己可以自主操作的资源量。

第四:基于预选和优选两阶段的 Scheduler 机制

当需要从一个资源池里面,选择一个节点,使用这个节点上的资源的时候,一个通用的 Scheduler 机制是:

首先进行预选,也即通过 Filter,将不满足条件的过滤掉。

然后进行优选,也即对于过滤后,满足条件的候选人,通过计算权重,选择其中最优的。

第五:基于独立虚拟子网的网络模式

为了每个租户可以独立操作,因而虚拟网络应该是独立于物理网络的,这样不同的租户可以进行独立的网络规划而互不影响,也不影响物理网络,当需要跨租户访问,或者要访问物理网络的时候,需要通过路由器。

有时候我们在虚拟机里面做了一些操作以后,希望能够把这个时候的镜像保存下来,好随时恢复到这个时间点,一个最最简单的方法就是完全复制一份,但是由于镜像太大了,这样效率很差。

因而采取 Copy On Write 的机制,当打镜像的时刻,并没有新的存储消耗,而是当写入新的东西的时候,将原来的数据找一个地方复制保存下来,这就是 Copy On Write。

对于 Openstack,有一种镜像 qcow2 就是采取的这样的机制。

这样镜像就像分层一样,一层一层的罗列上去。

网络的 QoS 使用 TC 来隔离的。

有时候,我们希望网络中的节点之间不能相互访问,作为最简单的防火墙,iptables 起到了很重要的作用,以后实现 ACL 机制的,都可以考虑使用 iptables。

搭建完毕虚拟化层和云平台层,接下来就是容器层了。Docker 有几个核心技术,一个是镜像,一个是运行时,运行时又分看起来隔离的 namespace 和用起来隔离的 cgroup。

Docker 的镜像也是一种 Copy On Write 的镜像格式,下面的层级是只读的,所有的写入都在最上层。

可见容器并没有使用更新的技术,而是一种新型的交付方式,也即应用的交付应该是一容器镜像的方式交付,容器一旦启动起来,就不应该进入容器做各种修改,这就是不可改变基础设施。

由于容器的镜像不包含操作系统内核,因而小的多,可以进行跨环境的迁移和弹性伸缩。

有了容器之后,接下来就是容器平台的选型,其实 Swarm、Mesos、Kubernetes 各有优势,也可以在不同的阶段,选择使用不同的容器平台。

基于 Mesos 的 DCOS 更像是一个数据中心管理平台,而非仅仅容器管理平台,它可以兼容 Kubernetes 的编排,同时也能跑各种大数据应用。

在容器领域,基于 Kubernetes 的容器编排已经成为事实标准。

当我们深入分析 Kubernetes 管理容器模式的时候,我们也能看到熟悉的面孔。

当 Kubernetes 想选择一个节点运行 pod 的时候,选择的过程也是通过预选和优选两个阶段:

Kubernetes 规定了以下的网络模型定义:

  • 所有的容器都可以在不使用 NAT 的情况下同别的容器通信。
  • 所有的节点都可以在不使用 NAT 的情况下同所有的容器通信。
  • 容器的地址和别人看到的地址一样。

也即容器平台应该有自己的私有子网,常用的有 Flannel、Calico、Openvswitch 都是可以的。

Map-Reduce 的过程将一个大任务,split 成为多个 Map Task,分散到多台机器并行处理,将处理的结果保存到本地,第二个阶段,Reduce Task 将中间结果拷贝过来,将结果集中处理,取得最终结果。

在 Map-Reduce 1.0 的时候,跑任务的方式只有这一种,为了应对复杂的场景,将任务的调度和资源的调度分成两层。

其中资源的调用由 Yarn 进行,Yarn 不管是 Map 还是 Reduce,只要向它请求,它就找到空闲的资源分配给它。

这里 Yarn 相当于外包公司的老板,所有的员工都是 Worker,都是他的资源,外包公司的老板是不清楚接的每一个项目的。

Application Master 相当于接的每个项目的项目经理,他是知道项目的具体情况的,他在执行项目的时候,如果需要员工干活,需要向外包公司老板申请。

Spark 之所以比较快,是因为前期规划做的好,不是像 Map-Reduce 一样,每一次分配任务和聚合任务都要写一次硬盘,而是将任务分成多个阶段,将所有在一个 Map 都做了的合成一个阶段,这样中间不用落盘,但是到了需要合并的地方,还是需要落盘的。

当大数据将收集好的数据处理完毕之后,一般会保存在两个地方,一个是正向索引,可以用 Hbase,Cassandra 等文档存储,一个是反向索引,方便搜索,就会保存在基于 Lucene 的 ElasticSearch 里面。

最后到了应用架构,也即微服务。接下来细说微服务架构设计中不得不知的十大要点。

设计要点一:负载均衡 + API 网关

在实施微服务的过程中,不免要面临服务的聚合与拆分。

当后端服务的拆分相对比较频繁的时候,作为手机 App 来讲,往往需要一个统一的入口,将不同的请求路由到不同的服务,无论后面如何拆分与聚合,对于手机端来讲都是透明的。

有了 API 网关以后,简单的数据聚合可以在网关层完成,这样就不用在手机 App 端完成,从而手机 App 耗电量较小,用户体验较好。

有了统一的 API 网关,还可以进行统一的认证和鉴权,尽管服务之间的相互调用比较复杂,接口也会比较多。

API 网关往往只暴露必须的对外接口,并且对接口进行统一的认证和鉴权,使得内部的服务相互访问的时候,不用再进行认证和鉴权,效率会比较高。

有了统一的 API 网关,可以在这一层设定一定的策略,进行 A/B 测试,蓝绿发布,预发环境导流等等。API 网关往往是无状态的,可以横向扩展,从而不会成为性能瓶颈。

设计要点二:无状态化与独立有状态集群

影响应用迁移和横向扩展的重要因素就是应用的状态。无状态服务,是要把这个状态往外移,将 Session 数据,文件数据,结构化数据保存在后端统一的存储中,从而应用仅仅包含商务逻辑。

状态是不可避免的,例如 ZooKeeper,DB,Cache 等,把这些所有有状态的东西收敛在一个非常集中的集群里面。整个业务就分两部分,一个是无状态的部分,一个是有状态的部分。

无状态的部分能实现两点:

  • 跨机房随意地部署,也即迁移性。
  • 弹性伸缩,很容易地进行扩容。

有状态的部分,如 ZooKeeper,DB,Cache 有自己的高可用机制,要利用到它们自己高可用的机制来实现这个状态的集群。

虽说无状态化,但是当前处理的数据,还是会在内存里面的,当前的进程挂掉数据,肯定也是有一部分丢失的。

为了实现这一点,服务要有重试的机制,接口要有幂等的机制,通过服务发现机制,重新调用一次后端服务的另一个实例就可以了。

设计要点三:数据库的横向扩展

数据库是保存状态,是最重要的也是最容易出现瓶颈的。有了分布式数据库可以使数据库的性能随着节点增加线性地增加。

分布式数据库最最下面是 RDS,是主备的,通过 MySQL 的内核开发能力,我们能够实现主备切换数据零丢失。

所以数据落在这个 RDS 里面,是非常放心的,哪怕是挂了一个节点,切换完了以后,你的数据也是不会丢的。

再往上就是横向怎么承载大的吞吐量的问题,上面有一个负载均衡 NLB,用 LVS,HAProxy,Keepalived,下面接了一层 Query Server。

Query Server 是可以根据监控数据进行横向扩展的,如果出现了故障,可以随时进行替换的修复,对于业务层是没有任何感知的。

另外一个就是双机房的部署,DDB 开发了一个数据运河 NDC 的组件,可以使得不同的 DDB 之间在不同的机房里面进行同步。

这时候不但在一个数据中心里面是分布式的,在多个数据中心里面也会有一个类似双活的一个备份,高可用性有非常好的保证。

在高并发场景下缓存是非常重要的。要有层次的缓存,使得数据尽量靠近用户。数据越靠近用户能承载的并发量也越大,响应时间越短。

在手机客户端 App 上就应该有一层缓存,不是所有的数据都每时每刻从后端拿,而是只拿重要的,关键的,时常变化的数据。

尤其对于静态数据,可以过一段时间去取一次,而且也没必要到数据中心去取,可以通过 CDN,将数据缓存在距离客户端最近的节点上,进行就近下载。

有时候 CDN 里面没有,还是要回到数据中心去下载,称为回源,在数据中心的最外层,我们称为接入层,可以设置一层缓存,将大部分的请求拦截,从而不会对后台的数据库造成压力。

如果是动态数据,还是需要访问应用,通过应用中的商务逻辑生成,或者去数据库读取,为了减轻数据库的压力,应用可以使用本地的缓存,也可以使用分布式缓存。

如 Memcached 或者 Redis,使得大部分请求读取缓存即可,不必访问数据库。

当然动态数据还可以做一定的静态化,也即降级成静态数据,从而减少后端的压力。

设计要点五:服务拆分与服务发现

当系统扛不住,应用变化快的时候,往往要考虑将比较大的服务拆分为一系列小的服务。

这样第一个好处就是开发比较独立,当非常多的人在维护同一个代码仓库的时候,往往对代码的修改就会相互影响。

常常会出现我没改什么测试就不通过了,而且代码提交的时候,经常会出现冲突,需要进行代码合并,大大降低了开发的效率。

另一个好处就是上线独立,物流模块对接了一家新的快递公司,需要连同下单一起上线,这是非常不合理的行为。

我没改还要我重启,我没改还让我发布,我没改还要我开会,都是应该拆分的时机。

再就是高并发时段的扩容,往往只有最关键的下单和支付流程是核心,只要将关键的交易链路进行扩容即可,如果这时候附带很多其他的服务,扩容既是不经济的,也是很有风险的。

另外的容灾和降级,在大促的时候,可能需要牺牲一部分的边角功能,但是如果所有的代码耦合在一起,很难将边角的部分功能进行降级。

当然拆分完毕以后,应用之间的关系就更加复杂了,因而需要服务发现的机制,来管理应用相互的关系,实现自动的修复,自动的关联,自动的负载均衡,自动的容错切换。

设计要点六:服务编排与弹性伸缩

当服务拆分了,进程就会非常的多,因而需要服务编排来管理服务之间的依赖关系,以及将服务的部署代码化,也就是我们常说的基础设施即代码。

这样对于服务的发布,更新,回滚,扩容,缩容,都可以通过修改编排文件来实现,从而增加了可追溯性,易管理性,和自动化的能力。

既然编排文件也可以用代码仓库进行管理,就可以实现一百个服务中,更新其中五个服务,只要修改编排文件中的五个服务的配置就可以。

当编排文件提交的时候,代码仓库自动触发自动部署升级脚本,从而更新线上的环境。

当发现新的环境有问题时,当然希望将这五个服务原子性地回滚,如果没有编排文件,需要人工记录这次升级了哪五个服务。

有了编排文件,只要在代码仓库里面 Revert,就回滚到上一个版本了。所有的操作在代码仓库里都是可以看到的。

设计要点七:统一配置中心

服务拆分以后,服务的数量非常多,如果所有的配置都以配置文件的方式放在应用本地的话,非常难以管理。

可以想象当有几百上千个进程中有一个配置出现了问题,是很难将它找出来的,因而需要有统一的配置中心,来管理所有的配置,进行统一的配置下发。

在微服务中,配置往往分为以下几类:

一类是几乎不变的配置,这种配置可以直接打在容器镜像里面。

第二类是启动时就会确定的配置,这种配置往往通过环境变量,在容器启动的时候传进去。

第三类就是统一的配置,需要通过配置中心进行下发。例如在大促的情况下,有些功能需要降级,哪些功能可以降级,哪些功能不能降级,都可以在配置文件中统一配置。

设计要点八:统一日志中心

同样是进程数目非常多的时候,很难对成千上百个容器,一个一个登录进去查看日志,所以需要统一的日志中心来收集日志。

为了使收集到的日志容易分析,对于日志的规范,需要有一定的要求,当所有的服务都遵守统一的日志规范的时候,在日志中心就可以对一个交易流程进行统一的追溯。

例如在最后的日志搜索引擎中,搜索交易号,就能够看到在哪个过程出现了错误或者异常。

设计要点九:熔断,限流,降级

服务要有熔断,限流,降级的能力,当一个服务调用另一个服务,出现超时的时候,应及时返回,而非阻塞在那个地方,从而影响其他用户的交易,可以返回默认的托底数据。

当一个服务发现被调用的服务,因为过于繁忙,线程池满,连接池满,或者总是出错,则应该及时熔断,防止因为下一个服务的错误或繁忙,导致本服务的不正常,从而逐渐往前传导,导致整个应用的雪崩。

当发现整个系统的确负载过高的时候,可以选择降级某些功能或某些调用,保证最重要的交易流程的通过,以及最重要的资源全部用于保证最核心的流程。

还有一种手段就是限流,当既设置了熔断策略,又设置了降级策略,通过全链路的压力测试,应该能够知道整个系统的支撑能力。

因而就需要制定限流策略,保证系统在测试过的支撑能力范围内进行服务,超出支撑能力范围的,可拒绝服务。

当你下单的时候,系统弹出对话框说 “系统忙,请重试”,并不代表系统挂了,而是说明系统是正常工作的,只不过限流策略起到了作用。

设计要点十:全方位的监控

当系统非常复杂的时候,要有统一的监控,主要有两个方面,一个是是否健康,一个是性能瓶颈在哪里。

当系统出现异常的时候,监控系统可以配合告警系统,及时地发现,通知,干预,从而保障系统的顺利运行。

当压力测试的时候,往往会遭遇瓶颈,也需要有全方位的监控来找出瓶颈点,同时能够保留现场,从而可以追溯和分析,进行全方位的优化。

}

之前写过两篇关于微服务架构的文章,发现阅读量挺高的,所以打算再聊聊云原生和微服务架构,过去的文章如下:

  • 什么是微服务?为什么要用微服务

本篇分享主要围绕以下 4 个主题进行:

  • 为什么要用云原生架构 ?

云计算不同于传统的自建机房,云计算就是将计算的抽象为基础设施然后通过网络分发,得益于云计算的无限扩展能力,使得“云计算”就像自来水厂一样,我们可以随时接水,并且不限量,按照自己家的用水量,付费给自来水厂就可以。以下云计算的五个基本特征。

以下是一些目前比较主流的公有云厂商:

云原生顾名思义,就是基于云计算特性所设计的应用服务,得益于云计算快速发展,基于云计算特性所设计的云原生应用相比传统的单体应用在安全性,扩展性,快速迭代,运维等各方便都有巨大的领先优势。云原生并不是指某一种技术,它是一种架构设计理念,只要符合这种架构设计理念的应用,都可以称为 云原生应用, 看看 CNCF 官方对于云原生的定义:

云原生是依赖容器作为技术技术来实现的,但是容器并不是什么新潮技术,以下是容器云技术的发展历史,其中有几个关键的历史节点

  • 早在 06 年的时候 Amazon 基于容器技术构建的 IaaS 平台 AWS,成为所有云计算厂商的鼻祖,由于技术领先的优势 AWS 现在依然也是云计算行业老大
  • 13 年 Docker 的诞生进一步简化容器技术的使用门槛,Docker 公司自以为掌握云时代的核心技术,开始野心勃勃的有意挑战传统的云计算大厂例如 RedHat,Google 的江湖地位,公司股价也是一骑绝尘,却不料被 RedHat 联合 Google 发布的 Kubernetes 击溃,Kubernetes 的成功让大家以为容器技术并非云时代的核心技术,容器编排 才是核心技术。(备注:2020 年 K8S 官方宣布只要满足 K8S CRI 接口的容器均可以被 K8S 进行编排,Docker 被时代抛弃)
  • 2015 年借助 Kubernetes 的成功,Google 宣布成立 CNCF 基金会,这是云原生时代的代表性的组织。致力于完善云时代的基础设施,帮助开发者构建更出色的产品

下图是 CNCF 的全景图:

为什么用云原生架构 ?

主要从 4 个方面来聊聊:

早期刚参加工作的时候接手过一个年久失修的遗留系统,这个系统又一个很神奇的 Bug 每天晚上会自动宕机,谁也不知道什么原因。只要重启就能恢复正常,当时为了保证业务系统的正常使用,我总是在半夜爬起来重启服务器,我当时就在想:要是有一种工具可以检测到系统宕机后,就自动重启恢复就好了,这样我就可以睡一个好觉了

这就是云原生架构想要解决的第一个问题:应用系统挂掉后,无需人工的介入,可以自动在最短的时间恢复来保证系统的健壮性

当然除了未知的 BUG,还有诡异的异常会导致服务崩溃了,例如:

  • 代码没写好,系统发生 OOM
  • 死锁,磁盘,网络等问题
  • Always:当容器终止退出后,总是重启容器,默认策略
  • OnFailure:当容器异常退出(退出状态码非 0)时,才重启容器
  • Never:当容器终止退出,从不重启容器

在微服务架构的大型分布式系统,服务和服务之间是通过熔断建立安全的保护隔离机制

云原生架构保障系统的安全性主要体现 2 个方面:

先来看看服务调用的安全隔离,如图:

假如服务 A 和服务 B 之间存在依赖的调用关系,它的处理逻辑如下:

  1. 如果服务 B 宕机或者异常下线,注册中心会发送服务 B 的状态给服务 A,服务 A 就会启动熔断保护机制
  2. 服务 A 采用降级策略或者不再发送向服务 B 发送请求,避免产生调用链雪崩,同时也保护服务 A 的可用性
  3. 服务 B 再次被拉起的时候,服务 A 收到注册中心对服务 B 的健康检查,恢复对服务 B 的调用或者移除降级策略

云原生架构对于服务的保护机制也体现在对资源的使用上,以前多套系统共享一台主机的资源,总是容易出现木桶的短板效应,就是只要有一个系统把主机资源占满,那么其他的系统都会因为资源不足受到影响。进而产生连锁反应,同主机上的所有系统都会崩溃。

现在基于容器部署的微服务系统,你的系统在生产环境的真实部署情况就像被关进一个个小房间里面,预先安排的资源设置就是这个服务房间的大小,它只能在指定的大小范围内活动,就算程序内部异常导致把资源全部占用,也不会影响其他房间的小伙伴的正常活动,从而保证整个系统的可用性

通过服务隔离,资源隔离的方式为云原生系统提供安全和可用性,这里仅仅做一个入门的介绍,如果展开来讲的话,内容还有很多,有兴趣的同学可以自行去研究和探索。

传统的单体的应用,往往部署在机房的服务器主机内,那么自购的服务器难以应对业务快速增长,存在以下问题:

  • 时间成本:采购服务器需要事先填好配置清单,走各种流程,等物流,等机器送到接上电源,估计 1~2 周都过去了
  • 空间成本:要腾出很大的空间来放置这些大家伙
  • 其他成本:24 小时开空调,专人轮班值守,机器的维护,服务下线后服务器容易闲置,闲鱼不好出手等等。。

在基于云计算的基本特征所设计的云原生系统,则不存在以上这些问题,在主流的公有云厂商提供 ECS 主机基本可以任意扩展和伸缩配置,在资源使用上也提供 按量付费 的运行模式,有效避免对于计算资源的限制和浪费。如下:

随着类似 Kubernetes 等云原生基础设置的完善,现代应用的部署方式也跟以前大不相同。相比传统低效的停机发布,云原生服务提供的 Rolling Update 滚动升级帮我们实现不停机升级系统的目标,对于需要快速响应市场需求的企业,快速迭代的业务系统的功能对于企业取得市场竞争力显得来说尤为重要。

另外,我们可以通过kubectl rollout undo 将 deployment 回滚到指定的版本,来解决微服务的快速回滚的问题。

以上就是云原生架构相比传统系统所带来的巨大优势,我们目前也是处于云时代架构演进的早期。我个人认为,我们程序员作为知识工作者非常值得投入时间去学习下一代的主流架构设计。这将为我们带来巨大的技术优势和技术领先。

微服务并不特指某一种具体的技术,它是一个抽象的概念,只要满足它的所有规范,那么就可以理解为你的系统实现了微服务。

关于你的项目何时应该引入微服务架构,行业一直有两种声音:

  • 方案 A 单体优先:随着架构的演进逐渐替换为微服务架构
  • 方案 B 微服务优先:避免后期的大范围架构重构

早期(2015 年左右)微服务使用成本和上手门槛很高,生产效率不如单体应用,但是伴随系统的业务复杂度逐渐上升,单体应用的生产效率逐渐降低,在到达临界点的时候微服务的优势逐渐出现,微服务的生产效率开始超过单体应用。

所以在 2015 年的时候结合成本和收益的权衡,大多数人会选择 单体优先 的架构方案,后续再逐步演化成为微服务。

早在 2015 年的 CNCF 基金会刚诞生,社区的微服务基础设置非常不完善,Netflix + Pivotal 公司作为微服务的实践的探索者,通过应用层面提供许多微服务的基础组件来实现微服务架构。关于 Netflix 提供的微服务全家桶解决方案称作 Netflix OSS(Open Source Software Center)

关于组件的详细介绍,我在 一文了解基于 Netflix OSS 的微服务架构 中也有介绍,这里就不再赘述了。

的快速发展,云原生的基础设施逐渐的完善和成熟,微服务的使用成本逐年降低,微服务的实现成本已经趋向于单体,甚至未来会优于单体,我的个人看法是,微服务如果能够解决使用和学习成本的问题,那么未来微服务也将完全取代单体应用。从长期主义来说,任何新项目都应该优先选择微服务架构,不仅可以保证业务系统的生产效率、扩展性,还可以避免未来产生大规模的重构。

市面上微服务框架很多,目前行业的大公司基本都会有自己的微服务框架,我们只看几款主流并且具备代表性微服务框架:

我们通过功能对比,看看都是如何根据自己的理解实现微服务的基本理论概念

我们将主流框架从微服务的基础关注点,运维架构,产品背景进行三方面维度的比较:

如果使用住房来比喻的话,前者就像毛坯房,还要自己装修,Kubernetes 则是精装修的商品房,帮你解决所有问题,拎包入驻即可。另外,自建 Kubernetes 集群成本比较高,推荐使用公有云厂商提供的 Kubernetes 服务

如果把分布式的微服务系统比喻成一家公司的话,那么网关就是该公司的前台,当有用户要访问公司必须在前台登记确认身份,疫情期间可能还需要量一下体温什么的。这一步骤就叫 网关鉴权,根据用户描述的任务和身上携带的证明,网关用户的业务类型将用户带到所属业务范围内办公室,这一步骤就叫做 网关路由。如果用户太多一个前台处理不过来,就会多开设几个窗口来分流,这一步骤就叫做 网关层面的负载均衡。网关是微服务的大门,对于微服务至关重要。

以下是网关常见的工作方式:

除了上述的鉴权,动态路由,负载均衡,通过网关还可以实现以下高级特性:

  • 网关限流(人太多,把门关起来,或者在门口排队)
  • 金丝雀发布(将小部分用户带到还未开放的新办公场地去体验一下)

网关是微服务的大门,因为网关对于对微服务来说至关重要,是微服务弹性伸缩的能力来源。并且网关的开发成本其实并不高,所以市场面有很多单独的网关产品,我们可以简单看看,如图:

早期分布式单体应用的会话管理

早期的单体应用用户会话方案都是通过服务端存储 sessionid + cookid + filter 来保存和管理用户状态会话,但是这种有状态服务有很多弊端,例如服务重启用户状态丢失,难以横向扩展等等,后单体应用时代大家开始把用户会话状态放在类似 Redis 等存储中间件中,来解决系统的横向扩展和重启后会话不丢失的问题。

微服务中基于 Auth 的认证方案

在的微服务体系中,身份认证模块将被统一抽取出来交给单独的服务处理,该服务通常称为 Auth Service。访问令牌通常由 Auth 颁发,由网关统一鉴权,AuthService 身份认证职责的分离,可以让微服务本身更加关注业务。

不过这种基于 Auth 认证服务的方案会将所有请求发往 Auth 进行验证,认证服务承受的压力大,架构方案重,造成不必要的性能损失。其实大部分的应用系统都不需要这么严格的安全认证等级。那么有没有一种轻量级的技术是可以由认证服务颁发令牌后,不在需要依赖 Auth 鉴权,由服务自行验证令牌的有效性,这样就可以大大减少对 Auth 的鉴权请求。答案是有的。它就是目前非常流行的 JWT

JWT 结合 RBAC 角色权限模型是目前非常主流的轻量级认证方案。它的工作流程如下:

JWT 备受推崇,广泛使用的原因,是因为它在由 Auth 服务颁发令牌后,在网关即可验证令牌合法性,无需再请求认证服务,请求少,性能好。令牌本身还可以自包含少量的用户信息,JWT 大概是一串这样的编码,它由三个部分组成,你可以通过 JWT IO 这个网站对 JWT 进行解码,从而获取 JWT 中的信息:

JWT 的详细生成和解码过程就这里不在赘述了,JWT 并非没有缺点,我们看看它的优缺点:

一旦颁发无法吊销,只能自动过期
包含信息越多,传输开销越大

RBAC 角色模型 + JWT 鉴权方案是目前微服务主流的安全认证体系,也能应对大多数系统对于安全认证的需求,也是目前市面上大部分的企业应用生产中的最佳实践

说完了开发环节,最后来说说微服务是怎么运维的。我们知道仅仅只是 完成功能(Feature-Complete) 只是软件开发流程中很少的一部分,那么从完成编码到 生产就绪(Production Ready),还需要经历哪些环节 ?我们可以参考下图:

  • 集成测试:用户功能的准确性,性能和压力测试

  • 日志管理:日志要规范,要区分:Info,Wrong,Error 等不同的等级,日志格式统一,方便日志收集,监控和排查

  • 监控预警:包含业务指标监控,应用指标监控,CPU,内存,磁盘网络 IO 监控等等,设定合理的预警信息

  • 调用链监控:呈现分布式系统的调用关系,调用性能,找到性能瓶颈,快速定位问题

  • 高可用考量:双机备份,主从备份,异地多活,容灾策略,应用弹性机制等

当我们确保应用满足生产就绪(Production Ready)的要求,我们就可以发布到生产,交付价值了

基于 EFK 的日志采集方案

基于容器部署的微服务架构不可能像传统应用那样通过 SSH 登录服务器上扒日志信息,所以只能采取统一的收集机制。

分布式系统的服务监控方案

  1. 通过 Grafana 展现和监控服务的运行各项指标

Skywalking 是无侵入分布式链路跟踪框架,可以在不添加一行代码的前提下完成对微服务分布式系统的链路跟踪,是目前主流的分布式链路跟踪的解决方案,2019 年 SkyWalking 成为 Apache 顶级项目,SkyWalking 的作者吴晟也因此当选为 Apache 软件基金会首位华人董事,这里就不展开讲了,SkyWalking 工作大致工作原理如下:

本文从云原生的发展历史,讲述了我们程序员为什么要拥抱选择云原生。讲解了基于云计算的基础底座所衍生出来的云原生系统对传统单体应用所带来的颠覆性改变,然后讲述一些微服务的工作原理,架构布局和运维方案。但是在真正生产级云原生应用中,远远不止要要考虑以上的内容,还有更多需要考虑的因素,例如:

  • 编码规范,测试覆盖率,E2E 测试
  • 持续集成:CI/CD 流水线

更多细节就不展开讲了,期待跟大家共同学习和交流,谢谢大家。

}

我要回帖

更多关于 springcloud完整项目 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信