凤凰架构-周志明

Posted 糊咕咕咕

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了凤凰架构-周志明相关的知识,希望对你有一定的参考价值。

一.演进

服务架构演进史

架构并不是被发明出来的,而是持续演进的结果。

原始分布式时代

UNIX 的分布式设计哲学

Simplicity of both the interface and the implementation are more
important than any other attributes of the system — including
correctness, consistency, and completeness

保持接口与实现的简单性,比系统的任何其他属性,包括准确性、一致性和完整性,都来得更加重要。

—— Richard P. Gabriel,The Rise of ‘Worse is Better’,1991

原始分布式时代的教训

Just because something can be distributed doesn’t mean it should be
distributed. Trying to make a distributed call act like a local call
always ends in tears

某个功能能够进行分布式,并不意味着它就应该进行分布式,强行追求透明的分布式操作,只会自寻苦果

—— Kyle Brown,IBM Fellow,Beyond Buzzwords: A Brief History of
Microservices Patterns,2016

单体系统时代

单体架构(Monolithic)

“单体”只是表明系统中主要的过程调用都是进程内调用,不会发生进程间通信,仅此而已。

单体系统的不足,必须基于软件的性能需求超过了单机,软件的开发人员规模明显超过了“2 Pizza Team”范畴的前提下才有讨论的价值,因此,本文后续讨论中所说的单体,均应该是特指“大型的单体系统”。

SOA 时代

SOA 架构(Service-Oriented Architecture)

面向服务的架构是一次具体地、系统性地成功解决分布式服务主要问题的架构模式。

微内核架构

事件驱动架构

经过了三十年的技术进步,信息系统经历了巨石、烟囱、插件、事件、SOA 等的架构模式,应用受架构复杂度的牵绊却是越来越大,已经距离“透明”二字越来越远了,这是否算不自觉间忘记掉了当年的初心?接下来我们所谈论的微服务时代,似乎正是带着这样的自省式的问句而开启的。

微服务时代

微服务架构(Microservices)

微服务是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言,不同的数据存储技术,运行在不同的进程之中。服务采取轻量级的通信机制和自动化的部署机制实现通信与运维。

wiki:

What is microservices

Microservices is a software development technique — a variant of the
service-oriented architecture (SOA) structural style.

微服务是一种软件开发技术,是一种 SOA 的变体形式。

—— Wikipedia,Microservices

Microservices and SOA

This common manifestation of SOA has led some microservice advocates
to reject the SOA label entirely, although others consider
microservices to be one form of SOA , perhaps service orientation done
right. Either way, the fact that SOA means such different things means
it’s valuable to have a term that more crisply defines this
architectural style

由于与 SOA 具有一致的表现形式,这让微服务的支持者更加迫切地拒绝再被打上 SOA 的标签,尽管有一些人坚持认为微服务就是 SOA
的一种变体形式,也许从面向服务方面这个方面来说是对的,但无论如何,SOA
与微服务都是两种不同的东西,正因如此,使用一个别的名称来简明地定义这种架构风格就显得更有必要。

—— Martin Fowler / James Lewis,Microservices

微服务时代充满着自由的气息,微服务时代充斥着迷茫的选择。

像 Spring Cloud 这样的胶水式的全家桶工具集,通过一致的接口、声明和配置,进一步屏蔽了源自于具体工具、框架的复杂性,降低了在不同工具、框架之间切换的成本,所以,作为一个普通的服务开发者,微服务架构是友善的。

可是,微服务对架构者是满满的恶意,对架构能力要求已提升到史无前例的程度。

后微服务时代

后微服务时代(Cloud Native)

从软件层面独力应对微服务架构问题,发展到软、硬一体,合力应对架构问题的时代,此即为“后微服务时代”。

注册发现、跟踪治理、负载均衡、传输通信等这些问题一定要由软件系统自己来解决吗?

服务网格”(Service Mesh)的“边车代理模式”(Sidecar Proxy):

服务网格将会成为微服务之间通信交互的主流模式,把“选择什么通信协议”、“怎样调度流量”、“如何认证授权”之类的技术问题隔离于程序代码之外,取代今天 Spring Cloud 全家桶中大部分组件的功能,微服务只需要考虑业务本身的逻辑,这才是最理想的Smart Endpoints解决方案

无服务时代

无服务架构(Serverless)

如果说微服务架构是分布式系统这条路的极致,那无服务架构,也许就是“不分布式”的云端系统这条路的起点。

We predict that serverless computing will grow to dominate the future of cloud computing

我们预测无服务将会发展成为未来云计算的主要形式

—— Cloud Programming Simplified: A Berkeley View on Serverless
Computing, 2019

  1. 后端设施是指数据库、消息队列、日志、存储,等等这一类用于支撑业务逻辑运行,但本身无业务含义的技术组件,这些后端设施都运行在云中,无服务中称其为“后端即服务”(Backend as a Service,BaaS)。
  2. 函数是指业务逻辑代码,这里函数的概念与粒度,都已经很接近于程序编码角度的函数了,其区别是无服务中的函数运行在云端,不必考虑算力问题,不必考虑容量规划(从技术角度可以不考虑,从计费的角度你的钱包够不够用还是要掂量一下的),无服务中称其为“函数即服务”(Function as a Service,FaaS)。

软件开发的未来不会只存在某一种“最先进的”架构风格,多种具针对性的架构风格同时并存,是软件产业更有生命力的形态。

二. 细节

访问远程服务

远程服务调用
表示数据,传递数据, 确定方法
REST 设计风格

  1. RESTful 的系统(6大原则)
    服务端与客户端分离(Client-Server)
    无状态(Stateless)
    可缓存(Cacheability)
    分层系统(Layered System):cdn…
    统一接口(Uniform Interface)
    按需代码(Code-On-Demand)
  2. 不足与争议
    REST 缺乏对资源进行“部分”和“批量”的处理能力(GraphQL),REST 没有传输可靠性支持(POST Once Exactly)

事务处理

分布式事务
1.可靠事件队列(Best-Effort Delivery)

2. TCC 事务

SAGA 事务
SAGA 的目的是避免大事务长时间锁定数据库的资源,后来才发展成将一个分布式环境中的大事务分解为一系列本地事务的设计模式

  1. 正向恢复(Forward Recovery):如果 Ti事务提交失败,则一直对 Ti进行重试,直至成功为止(最大努力交付)。这种恢复方式不需要补偿,适用于事务最终都要成功的场景,譬如在别人的银行账号中扣了款,就一定要给别人发货。正向恢复的执行模式为:T1,T2,…,Ti(失败),Ti(重试)…,Ti+1,…,Tn。
  2. 反向恢复(Backward Recovery):如果 Ti事务提交失败,则一直执行 Ci对
    Ti进行补偿,直至成功为止(最大努力交付)。这里要求
    Ci必须(在持续重试后)执行成功。反向恢复的执行模式为:T1,T2,…,Ti(失败),Ci(补偿),…,C2,C1。

透明多级分流系统

奥卡姆剃刀原则

Entities should not be multiplied without necessity

如无必要,勿增实体

—— Occam’s Razor,William of Ockham

  1. 尽可能减少单点部件,如果某些单点是无可避免的,则应尽最大限度减少到达单点部件的流量
  2. 在能满足需求的前提下,最简单的系统就是最好的系统
  1. 客户端缓存
  2. 域名解析(DNS Lookup, 世界根域名服务器的 ZONE 文件只有 2MB )
  3. 传输链路优化(Transmission Optimization:连接数优化)
  4. 传输压缩
  5. 快速 UDP 网络连接
  6. 内容分发网络(CDN)
  7. 负载均衡

    8.服务端缓存


    缓存风险: 缓存穿透/缓存击穿/缓存雪崩/缓存污染

架构安全性

1.认证
http WebAuthn
敏感操作需双因子认证
3. 授权

授权方式:授权码模式(Authorization Code),隐式授权模式(Implicit),密码模式(Resource Owner Password Credentials),客户端模式(Client Credentials)
开始进行授权过程以前,第三方应用先要到授权服务器上进行注册,所谓注册,是指向认证服务器提供一个域名地址,然后从授权服务器中获取 ClientID 和 ClientSecret
隐式授权(第三方应用无需服务器)

http://bookstore.icyfenix.cn/#/detail/1, #后面的/detail/1便是 Fragment
密码模式

客户端模式

设备码模式

《凤凰架构》-RPC vs REST


周志明《凤凰架构:构建可靠的大型分布式系统》
https://icyfenix.cn/

RPC发展史、REST风格编程思想、两者的区别和联系


1
 RPC

RPC出现的最初目的,就是为了让计算机能够跟调用本地方法一样去调用远程方法。


进程间通信(Inter-Process Communication,IPC)方法:

  • 管道(Pipe):类似于两个进程间的桥梁,传递少量的字符流和字节流。如:ps -ef | grep java

  • 信号(Signal):通知目标进程有某种事件发生。如:kill -9 pid

  • 信号量(Semaphore):信号量用于两个进程之间同步协作手段。如:wait(),notify()

  • 消息队列(Message Queue):以上三种方式只适合传递传递少量信息,消息队列用于进程间数据量较多的通信。

  • 共享内存(Shared Memory):允许多个进程访问同一块公共的内存空间,这是效率最高的进程间通信形式。

  • 套接字接口(Socket):以上两种方式只适合单机多进程间的通信,套接字接口是更为普适的进程间通信机制,可用于不同机器之间的进程通信。

通信的成本

最后一种基于套接字接口的通信方式(IPC Socket),它不仅适用于本地相同机器的不同进程间通信,由于 Socket 是网络栈的统一接口,它也理所当然地能支持基于网络的跨机器的进程间通信。


由于 Socket 是各个操作系统都有提供的标准接口,完全有可能把远程方法调用的通信细节隐藏在操作系统底层,从应用层面上看来可以做到远程调用与本地的进程间通信在编码上完全一致。但这种透明的调用形式却反而造成了程序员误以为通信是无成本的假象。


在“透明的 RPC 调用”一度成为主流范式的时候,Andrew Tanenbaum教授对此提出了一系列质问。论文的中心观点是:本地调用与远程调用当做一样处理,这是犯了方向性的错误,把系统间的调用做成透明,反而会增加程序员工作的复杂度。


透明通信的支持者有之,反对者有之,经过此后几年的发展,逐渐证明了Andrew Tanenbaum教授的预言是正确的。最终大佬们共同总结了通过网络进行分布式运算的八宗罪。


潜台词就是如果远程服务调用要弄透明化的话,就必须为这些罪过买单。至此,RPC 应该是一种高层次的或者说语言层次的特征,而不是像 IPC 那样,是低层次的或者说系统层次的特征成为工业界、学术界的主流观点。


RPC三个基本问题
  • 如何表示数据:就是序列化与反序列化。Web Service 的XML Serialization

  • 如何传递数据:通常指的是应用层协议,实际传输一般是基于标准的 TCP、UDP 等标准的传输层协议来完成的。Web Service 的Simple Object Access Protocol(SOAP)

  • 如何确定方法:一套语言无关的接口描述语言。Web Service 的Web Service Description Language(WSDL)


RPC的统一和分裂

统一

CORBA本身设计得实在是太过于啰嗦繁琐,制定的规范晦涩难懂脱离实际,没有把握住统一 RPC 的大好机遇。


后来XML 1.0 发布,并成为W3C的推荐标准,随后SOAP 1.0规范的发布,它代表着一种被称为“Web Service”的全新的 RPC 协议的诞生。随后提交给 W3C 投票成为国际标准,所以也被称为W3C Web Service。Web Service 采用了 XML 作为远程过程调用的序列化、接口描述、服务发现等所有编码的载体。


Web Service 的一大缺点是它那过于严格的数据和接口定义所带来的性能问题,XML本身信息密度就相对低下,Web Service又是跨语言的 RPC 协议,一个简单的字段为了不会产生歧义,XML严格描述的话,往往比原来多出几十倍的空间。

另外一点是,它希望在一套协议上一揽子解决分布式计算中可能遇到的所有问题,除它本身包括的 SOAP、WSDL、UDDI 协议外,还有一堆WS-*命名的、用于解决事务、一致性、事件、通知、业务描述、安全、防重放等子功能协议,这对开发者造成了非常沉重的学习负担。


分裂

由于一直没有一个同时满足以上三点的“完美 RPC 协议”出现。今时今日,任何一款具有生命力的 RPC 框架,都不再去追求大而全的“完美”,而是有自己的针对性特点作为主要的发展方向。


  • 朝着面向对象发展:RMI(Sun/Oracle)、.NET Remoting

  • 朝着性能发展,代表为 gRPC(Google)、Thrift(Facebook/Apache)

  • 朝着简化发展,代表为 JSON-RPC


到了最近几年,RPC 框架有明显的朝着更高层次(不仅仅负责调用远程服务,还管理远程服务)与插件化方向发展的趋势,不再追求独立地解决 RPC 的全部三个问题(表示数据、传递数据、表示方法),而是将一部分功能设计成扩展点,让用户自己去选择。

框架聚焦于提供核心的、更高层次的能力,譬如提供负载均衡、服务注册、可观察性等方面的支持。这一类框架的代表有 Facebook 的 Thrift 与阿里的 Dubbo。


2
 REST

REST并不是一种远程服务调用协议,它甚至就不是一种协议。虽然它有一些指导原则,但实际上并不受任何强制的约束。经常会有人批评说,某个系统接口“设计得不够 RESTful”,其实这句话本身就有些争议。因为 REST 只能说是一种风格。


REST是“表征状态转移”(Representational State Transfer)的缩写。可以理解为是“HTT”(Hyper Text Transfer,超文本传输)的进一步抽象,它们就像是接口与实现类之间的关系。


REST中关键概念:(以阅读文章为例)

  • 资源(Resource):可以将其视作是某种信息、数据。如:文章的内容,无论是网页还是报纸,你阅读的仍是同一个“资源”

  • 表征(Representation):指信息与用户交互时的表示形式。如:文章的PDF、Markdown等表现形式

  • 状态(State):在特定语境中才能产生的上下文信息就被称为“状态”。如:请求“下一篇”文章,依赖当前正在阅读的文章

  • 转移(Transfer):服务器通过某种方式,把“用户当前阅读的文章”转变成“下一篇文章”,这就被称为“表征状态转移”


RESTful的系统

REST风格的系统应该满足以下六大原则

  • 服务端与客户端分离(Client-Server)

  • 无状态(Stateless)

  • 可缓存(Cacheability)

  • 分层系统(Layered System)

  • 统一接口(Uniform Interface)

  • 按需代码(Code-On-Demand)


REST以资源为主体进行服务设计的风格,带来了什么好处:

  • 降低的服务接口的学习成本

  • 资源天然具有集合与层次结构

  • REST 绑定于 HTTP 协议


RMM成熟度模型

  • 0级. The Swamp of Plain Old XML:完全不REST,是RPC的风格

  • 1级. Resources:引入资源的概念

  • 2级. HTTP Verbs:引入统一接口,映射到HTTP协议的方法上(目前大部分的系统能够达到的REST界别)


编程思想的立场不同:

  • 面向过程编程时,为什么要以算法和处理过程为中心,输入数据,输出结果?当然是为了符合计算机世界中主流的交互方式。

  • 面向对象编程时,为什么要将数据和行为统一起来、封装成对象?当然是为了符合现实世界的主流的交互方式。

  • 面向资源编程时,为什么要将数据(资源)作为抽象的主体,把行为看作是统一的接口?当然是为了符合网络世界的主流的交互方式。


3
 RPC vs REST

REST 与 RPC 在思想上差异的核心是抽象的目标不一样,即面向资源的编程思想与面向过程的编程思想两者之间的区别。


至于使用范围,REST 与 RPC 作为主流的两种远程调用方式,在使用上是确有重合的,但重合的区域有多大就见仁见智了。


RPC一些发展方向,如分布式对象、提升调用效率、简化调用复杂性。

  • 分布式对象:这一条线的应用与 REST 可以说是毫无关联;

  • 提升调用效率:REST提升传输效率的潜力有限,对于传输协议、序列化器这两点都不会有什么选择的权力

  • 简化调用复杂性:追求简化调用的场景,众多 RPC 里也就 JSON-RPC 有机会与 REST 竞争


我们今天再去看这两种编程思想,虽然它们出现的时间有先后,但在人类使用计算机语言来处理数据的工作中,无论用哪种思维来抽象问题都是合乎逻辑的。


END




以上是关于凤凰架构-周志明的主要内容,如果未能解决你的问题,请参考以下文章

搞事情!深入理解Java虚拟机作者周志明直播预告 + 本文送礼

有事!速来《深入理解Java虚拟机》作者周志明首次直播+超多福利

从电竞选手到Java大神:对话《深入理解Java虚拟机》作者周志明

细品事务机制-分布式事务

细品事务机制-分布式事务

精选干货思维导图学Java虚拟机