《凤凰架构》读书笔记
@[toc]
前言
本篇博客是在阅读《凤凰架构》书籍的读书笔记,若文章中出现相关问题,请指出!
所有博客文件目录索引:博客目录索引(持续更新)
导航
一、演进中的架构
①原始分布式时代
为了突破硬件算力的限制,寻找使用多台计算机共同协作来支撑同一套软件系统运行的可行方案,此时是对分布式架构最原始的探索。
- 惠普公司(及后来被惠普收购的 Apollo)提出的网络运算架构(Network Computing Architecture,NCA)是未来远程服务调用的雏形
- 卡内基·梅隆大学提出的AFS 文件系统(Andrew File System)是日后分布式文件系统的最早实现(Andrew 意为纪念 Andrew Carnegie 和 Andrew Mellon)
- 麻省理工学院提出的Kerberos 协议是服务认证和访问控制的基础性协议,是分布式服务安全性的重要支撑,目前仍被用于实现包括 Windows 和 MacOS 在内众多操作系统的登录、认证功能。
DCE
(Distributed Computing Environment):分布式运算环境,DCE 包含一套相对完整的分布式服务组件规范与参考实现。
- 源自 NCA 的远程服务调用规范(Remote Procedure Call,RPC),当时被称为DCE/RPC,与Sun 公司提交的基于通用 TCP/IP 协议的远程服务标准ONC RPC被认为是现代 RPC 的共同鼻祖。
- 源自 AFS 的分布式文件系统(Distributed File System,DFS)规范,当时被称为DCE/DFS;源自 Kerberos 的服务认证规范。
- 有时间服务、命名与目录服务,就连现在程序中很常用的通用唯一识别符 UUID 也是在 DCE 中发明出来的。
调用远程方法:随之带来的问题的是服务发现、负载均衡、(熔断、隔离、降级)、序列化协议、传输协议、(认证、授权)、网络安全层、分布式数据一致性。
- 服务发现:远程的服务在哪里。
- 负载均衡:有多少个服务。
- 熔断、隔离、降级:网络出现分区、超时或者服务出错了怎么办。
- 序列化协议:方法的参数与返回结果如何表示。
- 传输协议:信息如何传输。
- 认证、授权:服务权限管理。
- 网络安全层:保证通信安全。
- 分布式数据一致性:如何令调用不同机器的服务返回相同的结果。
对于解决上面这些问题,DCE不仅从零开始,构建出大量的分布式基础组件与协议,将一个系统拆分到不同的机器中运行,这样做带来的服务发现、跟踪、通信、容错、隔离、配置、传输、数据一致性和编码复杂度等方面的问题,所付出的代价远远超过了分布式所取得的收益。
此次DEC的研究探索:最大的收获就是对 RPC、DFS 等概念的开创,以及得到了一个价值千金的教训:某个功能能够进行分布式,并不意味着它就应该进行分布式,强行追求透明的分布式操作,只会自寻苦果。”
某个功能能够进行分布式,并不意味着它就应该进行分布式,强行追求透明的分布式操作,只会自寻苦果!
②单体系统时代
单体架构
(Monolithic):“单体”只是表明系统中主要的过程调用都是进程内调用,不会发生进程间通信,仅此而已。
单体最大的问题:不可拆分,难以扩展。
- 最关键问题:拆分之后的隔离与自治能力上的欠缺。
- 由于所有代码都运行在同一个进程空间之内,所有模块、方法的调用都无须考虑网络分区、对象复制这些麻烦的事和性能损失。获得了进程内调用的简单、高效等好处的同时,也意味着如果任何一部分代码出现了缺陷,过度消耗了进程空间内的资源,所造成的影响也是全局性的、难以隔离的。譬如内存泄漏、线程爆炸、阻塞、死循环等问题,都将会影响整个程序,而不仅仅是影响某一个功能、模块本身的正常运作。如果消耗的是某些更高层次的公共资源,譬如端口号或者数据库连接池泄漏,影响还将会波及整台机器,甚至是集群中其他单体副本的正常工作。
- 单体应用:不能混用语言,往往都只能够使用一种语言来进行编写。对于JNI技术架构就可以让 Java 混用 C 或 C++,但是这往往是迫不得已的,
无论是单体还是微服务,都会采用分层架构,对代码进行纵向层划分,收到的外部请求在各层之间以不同形式的数据结构进行流转传递,触及最末端的数据库后按相反的顺序回馈响应。
在这个分层架构上,单体架构也变得"可拆分",更容易开发、部署、测试而获得一些便捷性上的好处。
为了允许程序出错,为了获得隔离、自治的能力,为了可以技术异构等目标,是继为了性能与算力之后,让程序再次选择分布式的理由。
- 人们曾经探索过几种服务拆分方法,将一个大的单体系统拆分为若干个更小的、不运行在同一个进程的独立服务,这些服务拆分方法后来导致了面向服务架构(Service-Oriented Architecture)的一段兴盛期,我们称其为“SOA 时代”。
③SOA时代
SOA 架构(Service-Oriented Architecture):面向服务的架构是一次具体地、系统性地成功解决分布式服务主要问题的架构模式。
- Gartner 公司在 1994 年提出,于2006年情况才有所变。明确了采用 SOAP 作为远程调用的协议,依靠 SOAP 协议族(WSDL、UDDI 和一大票 WS-*协议)来完成服务的发布、发现和治理
目的:对大型的单体系统进行拆分,让每一个子系统都能独立地部署、运行、更新。
④微服务时代
微服务架构
(Microservices):微服务是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言,不同的数据存储技术,运行在不同的进程之中。服务采取轻量级的通信机制和自动化的部署机制实现通信与运维。
- “微服务”这个技术名词最早在 2005 年就已经被提出。
- 微服务真正的崛起是在 2014 年。
九个核心业务和技术特征:
- 围绕业务能力构建(Organized around Business Capability):有怎样结构、规模、能力的团队,就会产生出对应结构、规模、能力的产品。
- 分散治理(Decentralized Governance):微服务更加强调的是确实有必要技术异构时,应能够有选择“不统一”的权利,譬如不应该强迫 Node.js 去开发报表页面,要做人工智能训练模型时,应该可以选择 Python,等等。
- 通过服务来实现独立自治的组件(Componentization via Services):区别于类库,因为类库在编译期静态链接到程序中,通过本地调用来提供功能,而服务是进程外组件,通过远程调用来提供功能。
- 产品化思维(Products not Projects):避免把软件研发视作要去完成某种功能,而是视作一种持续改进、提升的过程。以前在单体架构下,程序的规模决定了无法让全部人员都关注完整的产品,组织中会有开发、运维、支持等细致的分工的成员,各人只关注于自己的一块工作,但在微服务下,要求开发团队中每个人都具有产品化思维,关心整个产品的全部方面是具有可行性的。
- 数据去中心化(Decentralized Data Management):微服务明确地提倡数据应该按领域分散管理、更新、维护、存储。
- 强终端弱管道(Smart Endpoint and Dumb Pipe):微服务提倡类似于经典 UNIX 过滤器那样简单直接的通信方式,RESTful 风格的通信在微服务中会是更加合适的选择。
- 容错性设计(Design for Failure):不再虚幻地追求服务永远稳定,而是接受服务总会出错的现实,要求在微服务的设计中,有自动的机制对其依赖的服务能够进行快速故障检测,在持续出错的时候进行隔离,在服务恢复的时候重新联通。
- 演进式设计(Evolutionary Design):容错性设计承认服务会出错,演进式设计则是承认服务会被报废淘汰。一个设计良好的服务,应该是能够报废的,而不是期望得到长存永生。
- 基础设施自动化(Infrastructure Automation):基础设施自动化,如 CI/CD 的长足发展,显著减少了构建、发布、运维工作的复杂性。
一个简单服务,并不见得就会同时面临分布式中所有的问题,也就没有必要背上 SOA 那百宝袋般沉重的技术包袱。需要解决什么问题,就引入什么工具;团队熟悉什么技术,就使用什么框架。
⑤后微服务时代
后微服务时代(Cloud Native):从软件层面独力应对微服务架构问题,发展到软、硬一体,合力应对架构问题的时代,此即为“后微服务时代”。
软件可以只使用键盘命令就能拆分出不同的服务,只通过拷贝、启动就能够伸缩扩容服务,硬件难道就不可以通过敲键盘就变出相应的应用服务器、负载均衡器、DNS 服务器、网络链路这些设施吗?
- 借助虚拟化与容器化技术来达到快速分发部署,其中关键就是Docker。
服务调用时的负载均衡,往往需要根据流量特征,调整负载均衡的层次、算法,等等,而 DNS 尽管能实现一定程度的负载均衡,但通常并不能满足这些额外的需求。
为了解决这一类问题,虚拟化的基础设施很快完成了第二次进化,引入了今天被称为“服务网格”(Service Mesh)的“边车代理模式”(Sidecar Proxy)
未来 Kubernetes 将会成为服务器端标准的运行环境,如同现在 Linux 系统;服务网格将会成为微服务之间通信交互的主流模式,把“选择什么通信协议”、“怎样调度流量”、“如何认证授权”之类的技术问题隔离于程序代码之外,取代今天 Spring Cloud 全家桶中大部分组件的功能,微服务只需要考虑业务本身的逻辑,这才是最理想的Smart Endpoints解决方案。
⑥无服务架构
无服务架构
(Serverless):如果说微服务架构是分布式系统这条路的极致,那无服务架构,也许就是“不分布式”的云端系统这条路的起点。
- Serverless,应该翻译为“无服务器”才合适,但现在称“无服务”已形成习惯了。
绝对意义上的无限性能必然是不存在的,但在云计算落地已有十年时间的今日,相对意义的无限性能已经成为了现实。
主要涉及两个内容:后端设施(Backend)和函数(Function)。
- 后端设施是指数据库、消息队列、日志、存储,等等这一类用于支撑业务逻辑运行,但本身无业务含义的技术组件,这些后端设施都运行在云中,无服务中称其为“后端即服务”(Backend as a Service,BaaS)。
- 函数是指业务逻辑代码,这里函数的概念与粒度,都已经很接近于程序编码角度的函数了,其区别是无服务中的函数运行在云端,不必考虑算力问题,不必考虑容量规划(从技术角度可以不考虑,从计费的角度你的钱包够不够用还是要掂量一下的),无服务中称其为“函数即服务”(Function as a Service,FaaS)。
核心:无服务的愿景是让开发者只需要纯粹地关注业务,不需要考虑技术组件,后端的技术组件是现成的,可以直接取用,没有采购、版权和选型的烦恼;不需要考虑如何部署,部署过程完全是托管到云端的,工作由云端自动完成;不需要考虑算力,有整个数据中心支撑,算力可以认为是无限的;也不需要操心运维,维护系统持续平稳运行是云计算服务商的责任而不再是开发者的责任。在 UC Berkeley 的论文中,把无服务架构下开发者不再关心这些技术层面的细节,类比成当年软件开发从汇编语言踏进高级语言的发展过程,开发者可以不去关注寄存器、信号、中断等与机器底层相关的细节,从而令生产力得到极大地解放。
无论如何,云计算毕竟是大势所趋,今天信息系统建设的概念和观念,在(较长尺度的)明天都是会转变成适应云端的,笔者并不怀疑 Serverless+API 的设计方式会成为以后其中一种主流的软件形式,届时无服务还会有更广阔的应用空间。
总结
原始分布式时代:出现调用远程方法的想法,并且开始实施寻找解决的方式。
单体系统时代:整个服务一致运行在单体服务器中,没有调用远程服务的特点,缺点就是对于大型项目难扩展。
SOA时代:明确了采用 SOAP 作为远程调用的协议,依靠 SOAP 协议族来进行实现远程调用。
微服务时代:拆分为多个服务,并且有一系列远程调用方法的解决技术方案。
后微服务时代:借助容器来对服务进行发布、部署、监控等一系列自动化操作。
无服务结构:Serverless+API,无服务器时代,也就是说你不在需要考虑技术组件等等,只需要要纯粹关注业务实现,只需要调用serverless云函数即可!
我是长路,感谢你的耐心阅读。如有问题请指出,我会积极采纳!
欢迎关注我的公众号【长路Java】,分享Java学习文章及相关资料
Q群:851968786 我们可以一起探讨学习
注明:转载可,需要附带上文章链接
- 点赞
- 收藏
- 关注作者
评论(0)