作者:吴治辉
书名:架构解密:从分布式到微服务(第2版)
治辉的架构解密的第2版,上周在去北京的路上一边读一边做了一些笔记,涉猎广泛,由浅入深,循序渐进,非常推荐一读。
CHINANET:中国骨干网
○ 局域网需要上外网的时候,需要电信服务提供商(ISP)提供上网服务,将局域网对接到更大的网络——城域网。连接几个城域网的网络叫作国家骨干网,连接全球骨干网的网络叫作国际骨干网。中国大陆地区的海底光缆连接点有三个:青岛、上海和汕头,总共有6条光缆通向全球。
○ 中国的全国性骨干网是CHINANET,它是前邮电部经营管理的网络,1995年年初与国际互联网连通并向社会提供服务。CHINANET也是分层网络,由骨干网和汇接层层两部分组成:骨干网是其主要信息通路,由直辖市和各省会城市的网络节点构成;汇接层则用来连接各省(区)的城域网。
○ CHINANET由8个核心节点组成,这8个核心节点分别是北京、上海、广州、沈阳、南京、武汉、成都、西安。北上广”3个节点成为超级节点,也是CHINANET的3个国际出口,在这3个超级节点之间形成大三角电路,其他5个普通节点则与每个超级节点互联。
○ CHINANET的“汇接层”网络:这一层由54个汇接节点组成,除甘肃、山西、新疆、宁夏、贵州、青海、西藏、内蒙古等8个省份的单汇接节点外,每个省都有两个骨干网汇接节点,在第一和第二出入口节点之间通过一条省内中继连接。各各省份双方向上连接,分别连接到一个超级核心节点和一个普通核心节点
IDC机房
○IDC机房又被称为互联网数据中心(Internet Data Center)或者数据中心,IDC机房是标准化的电信专业级机房,为企业、政府提供服务器托管、租用及相关增值等方面的全方位服务。一开始,IDC机房主要是电信、联通等运营商建设的,后来很多企业也有了自己的IDC机房,BAT都自建了IDC机房。
○由于2002年5月国于2002年5月国内电信业大重组,原中国电信北方10个省份正式划入中国网通集团,南方21个省份重组为新的中国电信。这将把中国的互联网一分为二,导致互联互不通,使国内的IDC机房往往具备双线接入这一奇特特性。
○ 在IDC机房里通常采用传统的VLAN技术实现租户网络的隔离,VLAN基于IEEE的802.1Q协议,在该协议的帧格式里面定义了VLAN ID的位数为12比特,因此最多只能支持4094个VLAN。
HTTP
○ HTTP是全球最大规模的分布式系统网络的基础之一,也采用了传统的服务器-客户端的通信设计模式。在报文编码方式上,HTTP采用了面向程序员的文本(ASCII)编码方式而非面向计算机的二进制编编码方式。
○HTTP是无状态的请求-应答协议。在HTTP诞生之初网上没什么资源,也根本不存在可以跟用户交互的网站,因此这个设计思路也是完全可以理解的。
○ 最初的HTTP(0.9版)只提供了GET方法,这是因为其作者认为网上所有的资源(网页)都是静态的,远程用户是不能修改的,浏览器所能做的就是从远程服务器上“获取(GET)”指定网页并以只读方式展示给用户,在用户获取网页之后就立即中断与服务器的连接,从而节省宽带和服务器的宝贵资源。
○HTTP做了一个较大的升级(1.0版本):首先,增加了POST方法,使得客户端可以提交(上传)文件到服务器端;其次,通过引入Content-Type这个Header,支持除文本外的多媒体数据的传输支持。HTTP在1.0版本中引入了一个重要的设计,即在报文中增加了Header属性列表,每个Header都是一个Key/Value键值对,整个Header列表可以被视为一个Map的数据结构,用来在客户端(浏览器)与服务器端传递控制类数据。
○ 采用了HTTP作为通信协议的分布式系统天然具备了无侵入性的基础设施能力全面改进的优势。
Cookie && Session && Token
○ 即如何识别同一个用户的连续多次的请求?比如在典型的网购行为中一个客户网购的整个过程会涉及几十次甚至上百次的网页交互,这就意味着我们必须为无状态的HTTP引入某种状态机制,而具体的实现机制就是HTTP Cookie。HTTP Cookie新增了两个扩展性的HTTP Header,其中一个是Set-Cookie。Set-Cookie是服务端专用的Header,用来告知客户端(浏览器):“刚才的用户通过了身份验证,我现在设置了一个Cookie,里面记录了他的身份信息及有效期,你必须把它的内容保存下来,当该用户继续发送请求给我时,你自动在每个请求的HTTP Header上添加这个Cookie的内容后再发送过来,这样我就可以持续跟踪这个用户的后续请求了,请务必遵守要求,直到Cooker有效期结束才能删除Cookie,我不想用户反复登录及证明身份。”
○ Java开发人员最熟悉的Tomcat方式Set-Cookie,其中的jsessionid是Tomcat服务器用来标识用户的,而其他JEE Server各有各的名称,在PHP中则通常使用phpsessionid。
○Cookie是由RFC6265标准规范规定的一个概念,有对应的呈现标准和呈现方式,总体来说,我们可以将Cookie理解为HTTP的一部分,因此所有人都可以准确理解、表达并且进行标准化实现。
○ 与Cookie不同,Session属于Web应用开发中一个抽象的概念,它对应Cookie,用来在应用服务器端表示和保存用户的信息。但是,Session并没有标准化的定义及实现方式,因此在不同的Web编程语言里都有不同同的理解。Session中的数据通常被存储在应用服务器的内存中
○ Cookie的内容是被存放在磁盘中的,其他人是有可能直接访问到Cookie文件的;另外,Cookie中的信息是明文保存的,意味着攻击者可以通过猜测并伪造Cookie数据破解系统。避免这种漏洞的直接防护手段就是用数字证书对敏感数据进行加密签名,在
在加密签名后这串字符串就是我们所说的Token,这样攻击者就无法伪造Token了,因此Token在本质上是Session(SessionID)的改进版。
○与Session将用户状态保留在服务器端的常规做法不同,Token机制则把用户状态信息保存在Token字符串里,服务器端不再维护客户状态,服务器端就可以做到无状态,集群也更容易扩展。那么,Token数据是被放在哪里的呢?标准的做法是将其放在专用的HTTP Header“X-Auth-Token”中保存并传输,但客户端在拿到Token以后可以将其在本地保存,比如在App程序中,Token信息可以被保存在手机中,而Web应用中,Token也可以被保存到H5的localstorage中。
HTTP And Service Mesh
○在Service Mesh的各种实现类产品中一致选择了HTTP作为服务之间的基础通信协议,而不是其他二进制通信协议。并且,Service Mesh的核心功能或特性几乎全部依赖HTTP的特性才得以实现。
○在书特意将SideCar(边车)画成U型,这是为了方便表示Sidecar其实“包围但又不是完全包裹”它对应的Service实例的这一关键特性。即在进程角度,Sidecar是完全独立的进程(可以是一个或多个),与对应的Service实例不产生任何进程和代码级别的纠缠,非常像一个独立进程的代理。
○考虑到我们的Service其实是一个HTTP服务器进程(微服务),我们可以理解把SideCar理解为一个特殊定制的Nginx代理。另外一个细节需要注意:进入任意一个Service实例的请求都要从SideCar代理后才能抵达Service实例本身,在这个过程中,SideCar可以做任何HTTP能做的事情,比如黑白名单的检查、服务限速及服务路由等功能,这些恰恰就是Service Mesh的核心特性之一。
RPC
○古老又有生命力的RPC:RPC最初由Sun公司提出,即Sun RPC,后来也成为IETF国际标准,至今仍然重要的NFS协议就是最早的基于RPC的一个重要案例。
○谷歌于2015年开源的跨语语言的RPC框架——gRPC,gRPC采用的默认的编码机制也是谷歌设计的ProtoBuf。gRPC没有基于传统的自定义TCP Socket传输通道,而是基于现有的HTTP 2.0。
○用Go开发的的分布式系统,比较著名的如Kuberntes、Istio等,都是以gRPC作为分布式通信的接口协议的。
微服务架构
○最早提出微服务架构及实践微服务架构的公司有Google、Amazon、eBay和NetFlix等。在这种新的微服务架构下,整个系统被分解为独立的几个微服务,每个微服务都可以独立部署在多台机器上,前端应用可以通过负载均衡器(Load Balancer)来访问微服务,微服务之间也可以通过同样的接口进行远程通信。
○一般而言,如果一个分布式系统具备如下特点,则我们可以称之为“微服务架构”
- 任何一个服务都由多个独立的进程提供服务,这些进程可以分布在多台物理机上,任何进程宕机,都不会影响系统提供服务。
- 整个系统是由多个微服务有机组成的一个分布式系统,换而言之,不是一个巨大的单体架构。
○ 第1类:基于传统的高性能RPC技术和服务治理的微服务架构,这个领域的王者为ZeroC IceGrid。
○第2类:以HTTP REST为通信机制的通用性微服务架构,典型的为Spring Cloud。
○第3类:基于容器的技术,目标是部署在公有云平台上的微服务架构基础平台,这种微服务架构平台并没有提供特定的RPC通信机制,只保证TCP通信的可达性,所以理论
上,任何分布式应用都可以运行在微服务架构平台上,言外之意就是要选择合适的通信协议,比如REST、Thrift、gRPC或者自定义的某种TCP通信协议。这个领域的王者为Google的Kubernetes,
CPU与内存
○通常来说,CPU的运算速度与内存访问速度之间的差距不过是100倍。既然CPU的速度与内存的速度还是存在高达两个数量级的巨大鸿沟,所以它们注定不能“幸福地在一起”,于是CPU的亲密“伴侣”Cache闪亮登场。与来自DRAM家族的内存(Memory)出身不同,Cache来自SRAM家族。DRAM与SRAM最简单的区别是后者特别快,容量特别小,电路结构非常复杂,造价特别高。造成Cache与内存之间巨大性能差距的主要原因是工作原理和结构不同,如下所述。
● DRAM存储一位数据只需要一个电容加一个晶体管,SRAM则需要6个晶体管。由于DRAM的数据其实是被保存在电容里的,所以每次读写过程中的充放电环节也导致了DRAM读写数据有一个延时的问题,这个延时通常为十几到几十ns。内存可以被看作一个二维数组,每个存储单元都有其行地址和列地址。由于SRAM的容量很小,所以存储单元的地址(行与列)比较短,可以被一次性传输到SRAM中;DRAM则需要分别传送行与列的地址。
● SRAM的频率基本与CPU的频率保持一致;DRAM的频率直到DDR4以后才开始接近CPU的频率。Cache是被集成到CPU内部的一个存储单元,一级Cache(L1 Cache)通常只有32~64KB的容量,这个容量远远不能满足CPU大量、高速存取的需求。
○由于存储性能的大幅提升往往伴随着价格的同步飙升,所以出于对整体成本的控制,在现实中往采用金字塔形的多级Cache体系来实现最佳缓存效果,于是出现了二级Cache(L2 Cache)及三级Cache(L3 Cache),每一级Cache都牺牲了部分性能指标来换取更大的容量,目的是缓存更多的热点数据。以Intel家族Intel Sandy Bridge架构的CPU为例,其L1 Cache容量为64KB,访问速度为1ns左右;L2 Cache容量扩大4倍,达到256KB,访问速度则降低到3ns左右;L3 Cache的容量则扩大512倍,达到32MB,访问速度也下降到12ns左右,即便如此,也比访问主存的105ns(40ns+65ns)快一个数量级。此外,L3 Cache是被一个Socket上的所有CPU Core共享的,其实最早的L3 Cache被应用在AMD发布的K6-III处理器上,当时的L3 Cache受限于制造工艺,并没有被集成到CPU内部,而是被集成在主板上。
○DDR5内存条,除频率更高外,存储密度进一步提升,单条内存容量高达128GB。
Redis
○ 更加丰富的缓存失效策略及更加复杂的内存管理模型带来的高级特性。对缓存项的key与value的长度限制大大放宽,相对于Memcache最长250个字节的key及默认最大1MB的value,Redis的key与value则可以超过512MB。相对于Memcache的缓存功能只能针对字符串类型的数据,Memcache的缓存功能只能针对字符串类型的数据,Redis支持6种数据类型,这大大方便了程序员。
○Redis一直在NoSQL和分布式等热点领域积极突破,使得它的使用场景越来越广泛,支持数据持久化及主从复制的特性使得它在某些特定场合代替了数据库,而Redis 3.0在分布式方面的创新,也使它能够胜任更大规模的数据集
○采用了单线程模型在多核CPU的情况下如何充分发挥CPU的功能呢?答案就是分片(Sharding)
存储与文件系统
○分布式文件系统是大型分布式系统中非常重要的基础设施。Hadoop中最重要的技术不是Map Reduce,而是HDFS。除了HDFS,Spark还可以与老牌分布式文件系统GlusterFS结合使用。OpenStack中最重要且能独立运营的子系统是分布式对象存储系统Swift。Docker及Kubernetes容器技术依然需要通过分布式文件系统实现批量处理任务中的共享存储问题。
○数据存储进化史:1952年,磁带式驱动器的容量仅为2MB;2013年,IBM TS3500磁带库的容量可以达到125PB(1PB=1024TB)。
○磁带介质不仅能提供高容量、高可靠性(没有机械部件,不容易损坏)及可管理性,比光盘、磁盘等存储介质也便宜很多,因此,磁带机技术长期以来一直是唯一的数据存储备份(数据冷备)技术,从大型机时代到现在一直在演进。近年来,磁带存储的耐用性得到大幅提升,磁带库和一些磁带存储的解决方案能定期扫描磁带介质,确保它们是可读的且数据是有效的,如果检测到错误或数据损坏,则整个磁带或损坏的数据都是可以被复制到新磁带的,并且迁移到新磁带的技术同样实现了自动化。
○在大数据时代产生了一个新的存储概念——冷存储(Cold Storage),指长期闲置且很少被访问的数据的存储。以社交平台Facebook为例,其用户上传的新图片每个月多达7PB,每天平均上传3亿张。这些数据中有很大一部分被长期搁置,因此可
以将其存储在更低成本的存储介质中,而磁带无疑是存储介质的最佳选择。LTO(Linear Tape Open)机构发布的一份磁带出货量报告显示,虽然售出的产品数量自2008年开始就一路下降,但从2014年到2015年磁带产品的出货总容量增长了18%。由于磁带在大数据和云计算时代需求量增加,所以这方面的技术研究开始加速:2015年,IBM科学家与日本富士公司合作,在每平方英寸磁带上存储了1230亿bits数据,比IBM之前的企业级磁带产品的最大容量提升了22倍;2016年,索尼新一代磁带的存储容量达到了185TB,是传统磁带的74倍,是蓝光碟的3700倍。在2019年度“中国存储市场影响力排行榜”中IBM的新一代云存储库TS4500磁带库获得年度最佳产品奖,该磁带库的最大容量高达351 PB。TS4500磁带库采用了磁带库专用的文件系统——Linear Tape File System(LTFS),这项技术让读写磁带的数据变得更为容易,就像使用文件系统的磁盘一样好用。IBM将LTFS技术提交给了LTO Consortium联合会,供联合会的企业成员下载,该联合会的领先技术供应商包括惠普、IBM和Quamtum等,IBM还将其LTFS技术提交给了存储网络行业协会(SNIA)以实现标准化。任何使用或提供LTO技术的厂商都有权使用LTFS。
○1956年,第一款硬盘诞生,重达1吨,存储量仅为5MB;2016年4月初,希捷推出了10TB的机械硬盘,它是一款具有划时代意义的产品,主要面向云存储数据中心,华为、阿里巴巴均已采纳和部署。面向个人用户领域且内置WiFi的无线移动硬盘已经进入很多IT爱好者的家庭。2018年年底,希捷又宣布研发成功16TB的超大容量机械硬盘,并于2019年正式上市销售,2020年年底有望上市20TB的超大机械硬盘。
○大家看到的事实是CPU的效能每年大约增长30%~50%,而硬盘只能增长约7%。
伯克利大学研究小组希望找出一种新的技术,在短期内迅速提升硬盘的效能来平衡CPU的运算能力,他们想到了一种简单、有效的解决办法,即堆叠很多硬盘并模拟为一个有单一接口的、可以提供并发I/O操作和更高I/O带宽的大容量虚拟硬盘,这就是磁盘阵列(Redundant Arrays of Independent Disks,RAID)。磁盘阵列是一种重要的企业存储设备,除了能组合多个硬盘以提供更大的存储空间,还能提高I/O传输速率,RAID通过在多个磁盘上同时存储和读取数据来大幅提高存储系统的数据吞吐量(Throughput)。在RAID中,可以让很多磁盘驱动器同时传输数据,而这些磁盘驱动器在逻辑上又是一个磁盘驱动器,所以在使用RAID后,一个“逻辑磁盘”的I/O速度可以达到单个磁盘的几倍甚至几十倍,这就是RAID条带化的能力,也叫作RAID 0模式。RAID 0的原理就是将原先顺序写入的数据分散到所有的N块硬盘中同时进行读写,N块硬盘的并行操作使得同一时间内磁盘读写的速度提升了N倍。RAID 0模式最大的缺点在于任何一块硬盘出现故障时,整个系统将被破坏,可靠性仅为单独一块硬盘的1/N,但对于一些新的分布式存储来说,RAID 0却是最好的选择,这是因为这些分布式系统本身通过多份存储副本的方式,避免了RAID 0的问题。
○RAID方案一开始主要针对企业级市场,采用的是内接式磁盘阵列卡,阵列卡采用专用的处理单元来实现磁盘阵列的功能,磁盘阵列卡被直接插到服务器主板上,面对的是服务器上专用的高速SCSI硬硬盘系统,系统成本比较高。并且DAS存储或服务器主机的升级扩展,只能由原设备厂商提供,往往受原设备厂商限制。以上关于DAS的种种缺陷,最终加速了SAN这种新型的存储设备在企业业级存储市场的崛起。时代呼唤新技术的诞生,而SAN技术就是在这种情况下应运而生的。SAN(Storage Area Network,存储区域网络)通过光纤通道这种高速网络来连接存储设备和服务器,提供的存储单位是LUN,属于块级别的存储单元。在SAN存储设备中采用了SCSI-3这种效率和速度远高于当时TCP/IP的传输协议来传输I/O数据。SAN实际上是是将一对一的存储设备与服务器变成了一个多对多的存储网络,使多个服务器可以连接到这个存储网上并共享整个存储池。SAN是一个存储网,所以它也有专有的存储网络设备,最早的是以光纤存储网络为媒介的FC SAN,对应的设备是光纤交换机及HBA卡,在每个主机上都插入一个FC HBA卡,通过光纤(光缆)连接到一个光纤交换机上,而这个光纤交换机同时连接了一个SAN存储设备(FC磁盘阵列),这样就组成了一个FC SAN存储网络,如下图所示。
由于光纤交换机及对应的FC HBA卡都属于专有技术,所以FC SAN系统一直比较昂贵,只在一些大型企业和数据中心使用。
○与此同时,传统的以太网发展迅速,早在20世纪90年代末,千兆以太网络技术就已经发展成熟,数据中心随处可见千兆以太网,一般的八口千兆交换机价格不足两千元。因此,SAN存储网络从专有的光纤网迁移到以太网成为大势所趋,迁移的关键是将SAN存储网所使用的SCSI协议和接口变成以太网的TCP/IP并且能在以太网卡和交换机上使用,这就是IBM公司研发的iSCSI协议。iSCSI协议实际上是将SCSI指令封装在TCP/IP之内,采用标准的以太网传输。于是又出现了新的iSCSI HBA卡,采用iSCSI协议,不需要专有的昂贵的光纤接口与光纤交换机。iSCSI的出现大大加速了存储领域的发展,目前SAN其实已经是IP SAN的天下了,特别是,万兆以太网在Intel的大力推进下加速普及,使得IP SAN的性能大大超越传统的FC SAN
○SAN直接提供原始的块存储设备来供其他客户端挂载为本地磁盘,从而第1次在真正意义上实现了“云端磁盘”的概念。
○DAS及SAN都属于“块存储设备”,只面向服务器提供物理存储块的读写指令,即类似于内存读写的功能,并没有提供更为高级的面向最终用户的文件存储功能,针对这一市场需求,另外一种存储设备NAS(Network Attached Storage,网络附属存储)出现了
不管用什么方式,NAS都必须可以访问卷或者物理磁盘;NAS必须具有接入以太网的能力,也就是必须具有以太网卡。客户机可以把NAS当作一个远程文件系统来访问。
○NAS和SAN的融合也是存储设备的发展趋势,比如EMC的新产品VNX系列:通过光纤通道从后端SAN获得块存储空间,经过NAS创建成文件系统后,就变成文件级别的了,最后通过以太网共享给服务器。
○随着虚拟化与云计算的加速发展,越来越多的企业开始使用廉价的X86服务器集群来实现强大的分布式存储。企业无须购买专有硬件和软件,采用开源的分布式存储软件如Swift,就能很快构建一个庞大的、可靠的、弹性扩展的分布式存储集群。
○NFS就是个古老并且生命力顽强的分布式文件系统,它于1984年诞生在Sun的实验室里(比HTTP还古老),因为基于TCP/IP设计,所以成为第1个现代化的网络文件系统。NFS为了保证文件传输的效率,默认采用UDP而不是TCP,这与FTP不同。
○高性能计算领域的分布式文件系统:Google的Global File System(GFS)和IBM的General Parallel File System(GPFS)。这些分布式文件系统管理的系统更复杂,规模更大,性能追求更高,比如直接对物理设备(块存储)访问而不是基于现有的文件系统。GPFS这种基于SAN专有存储系统的大型分布式文件系统有两个明显的短板:首先,SAN存储系统硬件本身很昂贵,大部分人用不起;其次,SAN存储网络的扩展性并不好,当客户端数量庞大,比如面对由成千上万个CPU组成的高性能计算集群时,SAN的集中式I/O就明显成为一个瓶颈。
○企业级分布式文件系统GlusterFS:2003年,Gluster公司参加了一个研制超级计算机的项目,该项目隶属于美国能源部所属的一个国家实验室,代号为Thunder的超级计算机于次年研制成功并投入生产,成为当年世界上排名第二的超级计算机。在这个过程中,Gluster公司积累了丰富的高性能分布式文件系统的研发经验,最终于2007年发布了开源的GlusterFS文件系统,这个新的分布式文件系统也成为除Lustre外的一个新选择。GlusterFS的最初设计目标是简单方便、高性能及高扩展能力,具体表现为以下几个方面。所有模块都运行在Linux用户态,不涉及Linux内核代码,方便编译、安装及使用(与Lustre不同)。消除了集中化的元数据服务器,从而具备更强的弹性扩展能力及更高的性能(与Lustre不同)。采用模块化设计,简化了系统配置并减少了组件之间的耦合性。使用操作系统自身的文件系统,不重新发明轮子(与Lustre不同)。数据被存储为标准Linux文件,不引入新格式。在GlusterFS集群里,我们所存储的文件就位于某个服务器节点上,文件名就是我们指定的文件名,内容就是我们写入的内容,这个文件没有经过任何特殊的加密或编码,我们可以直接用Linux文件命令对其进行操作。因此,即使GlusterFS集群出现故障而导致不可用,所有文件也都在原地,不会出现无法恢复数据的严重问题。
○2011年,RedHat重金收购了Gluster公司,将GlusterFS纳入自己的云计算存储产品中,并且彻底开源了GlusterFS。RedHat将GlusterFS定义为现代企业级工作负载服务的Scale-out NAS,强调其是一个Software Defined File Storage,可以管理大规模的非结构化和半结构化数据,支持私有云、公有云或混合云的部署,同时支持Linux容器。
○Kubernetes中也建议将GlusterFS作为分布式文件存储的首选方案。借助于RedHat的影响力,被收购之后的GlusterFS在开源社区风头更胜,国内外有大量用户在对它进行研究、测试、部署和应用。
○弹性哈希算法是GlusterFS的灵魂设计之一,仅仅通过路径名及文件名(不需要与此文件相关的其他辅助信息)就可以计算出此文件在集群中的存储位置。在实际情况下存在集群服务器数量的增减、磁盘故障导致存储单元数量的变化、重新平衡文件分布时需要移动文件等问题,使得我们无法简单地将文件直接映射到某个存储节点,GlusterFS为了实现这种映射,采用了以下独特设计。
● 设置了一个数量众多的虚拟卷组。使用了一个独立的进程指定虚拟卷组到多个物理磁盘。
● 使用了哈希算法来指定文件对应的虚拟卷组。由于虚拟卷组(Virtual Volume)的数量很多并且不随着存储服务器数量的变化而变化,因此在增加或减少存储服务器的数量时,只要把某些虚拟卷组与这些存储服务器的映射关系修改一下就可以了。Redis 3.0基于哈希槽(Hash Slot)的集群以及FastDFS也借鉴了GlusterFS的这一设计思想。
○弹性哈希算法有一个明显的缺点,即在进行目录遍历时效率低下,因为一个目录下的文件可以被分布到集群中的所有存储节点上,所以GlusterFS需要搜索所有的存储节点才能实现目录的遍历,因此我们的程序要尽量避免这种操作。后来发展起来的对象存储系统干脆取消了文件目录这一特性,就是因为在分布式结构下文件目录是个难以解决的问题,而且在大多数情况下可以通过客户端编程避免该操作,比如在一个文件或者数据库中记录属于同一个目录下所有文件的ID。
○创新的Linux分布式存储系统——Ceph:GlusterFS最早被研究于2003年(第1次公开的时间是2007年),那时的开源软件世界还没有能够承载PB级别的数据并且由成千上万的存储节点组成的大规模分布式存储系统,这方面的学术研究是一个热点领域,也是Ceph的作者Sage Weil攻读博士期间的研究课题。Ceph项目发起于2004年,Sage随后在2006年的OSDI学术会议上发表了介绍Ceph的论文,并在该论文的末尾提供了Ceph软件的下载链接,由此,Ceph开始广为人知。随着Ceph的热度不断增加,从2010年开始,来自Yahoo、Suse、Canonical、Intel等公司的一批开发者进入Ceph社区协作开发。Sage于2011年创立了Inktank公司,主导了Ceph的开发和社区维护。2012年,Ceph被正式纳入OpenStack体系,成为Cinder底层的存储实现,并随着OpenStack的兴起而被广泛接受。2014年年中,Ceph的实际控制者Inktank被RedHat收购,成为RedHat旗下第2个重要的分布式存储产品(继续开源),如今Ceph已经发展成为最广泛的开源软件定义存储项目。
○在Ceph的设计中有如下两个亮点。首先,充分发挥存储设备(X86 Linux)自身的计算能力,而不仅仅是将其当作存储设备。这样,Ceph就可以通过运行在每个存储节点上的相关辅助进程来提升系统的高可用、高性能与自动化水平。比如Ceph的自动化能力就包括数据的自动副本、自动迁移平衡、自动错误侦测及自动恢复等。对于一个大规模的分布式系统来说,自动化运维是至关重要的一个能力,因为自动化运维不但保证了系统的高可靠性与高可用性,还保证了在系统规模扩大之后,其运维难度与运维工作量仍能保持在一个相对较低的水平。其次,与同时代的GlusterFS一样,Ceph采用了完全去中心化的设计思路。之前的分布式存储系统因为普遍采用中心化(元数据服务器)设计,产生了各种问题,例如增加了数据访问的延时、导致系统规模难以扩展及难以应对的单点故障。Ceph因为采用了完全去中心化的设计从而避免了上述种种问题,并真正实现了系统规模线性扩展的能力,使得系统可以很容易达到成百上千个节点的集群规模。Yahoo Flick自2013年开始逐渐试用Ceph对象存储并替换原有的商业存储,目前大约由10个机房构成,每个机房为1~2PB,存储了大约2500亿个对象。Ceph整体提供了块存储RBD、分布式文件存储CephFS(类似于GlusterFS)及分布式对象存储RADOSGW三大存储功能,可以说是目前为数不多的集各种存储能力于一身的开源存储中间件。
○ 星际文件系统IPFS(Inter Planetary File System)是最近才出现的一个新的开源分布式文件系统。IPFS的作者是毕业于斯坦福大学的墨西哥人Juan Benet,他成功创建了Protocal Lab实验室。Juan Benet认为兴盛于21世纪初的以BitTorrent为代表的P2P技术是一个创新性的文件分享技术,比已有的文件分享技术更加高效、开放,但因为在其上分享的内容盗版泛滥而且难以监管,所以在文件分享方面陷入绝境。但是,P2P的理念和优点深深吸引了Juan Benet,IPFS的技术核心之一就是P2P。基于HTTP的互联网文件系统还存在以下下问题。
● 大文件的传输效率太低。
● 网上冗余的文件数量庞大,浪费了很多存储资源,也导致检索效率低下。
IPFS采用了P2P技术来解决上述问题,它将一个大文件分为大小为256KB的一个个独立区块,这些独立区块可以被存储在不同的IPFS节点上,大文件就可以用这些区块的一个地址链表来寻址了,同时,客户端可以并行地从多个节点获取文件的不同内容,从而大大加速大文件的传输效率。为了解决文件重复的难题,IPFS放弃了HTTP基于文件名(URL)的寻址思路,创新地采用了基于文件内容的寻址方案。每个被放入IPFS的文件,其内容都经过SHA2-256的算法得到一个长度为32个字节的哈希值,这个哈希值再经过Base58的编码后得到的可读字符串就是该文件的“唯一标识”,只要知道这个唯一标识,就可以通过IPFS去查找该文件的内容,不管它被分隔成几部分,以及被存储在哪些服务器上。由于相同的文件内容得到的哈希值是相同的,所以IPFS天然具有过滤重复文件的能力,也可以通过指定文件副本数的方式来确定某个(某类)文件存储的副本数量,实现灵活的容灾特性。此外,如果不知道文件内容对应的哈希值,则无法检索该文件,所以IPFS还有天然的文件保密性。
○美国知名交易所双子星Gemini官方发布公告,将为Filecoin(基于IPFS)的代币FIL提供托管支持,并认为Filecoin与之前纯粹竞争消耗算力的挖矿方式来争取虚拟货币的传统区块链不同,Filecoin里的挖矿行为是有对应的实际价值的,并满足了互联网市场中的真实需求及相关交易。用户愿意将自己的存储资源贡献出来并获取相应的报酬。用户愿意为可靠云存储服务付费。用户愿意为高质量数据检索服务付费。
5.7 软件定义存储
与Ceph类似,为了将存储对象均匀分布到后端的多个存储设备上,Swift也用了一套特殊的Hash算法——一致性哈希算法,在Swift里叫作弹性哈希环。Swift的哈希环是存储设备节点线性分布的,无法人工配置和干预;Ceph的CRUSH算法则采
用层级结构,用户可以定义细致的策略,因此从生产应用的角度来说比Swift更合适,加上Ceph同时支持块存储、文件存储及对象存储,因此后来居上。雅虎的Cloud Object Store(COS)是雅虎基于商用硬件的软件定义存储解决方案,雅虎也是在对比了Swift、Ceph及其他一些商业化的解决方案后最终选择了Ceph,其中最重要的一个原因就是Ceph通
过一个固有的架构把对象存储、块存储和文件存储整合到了一个存储层,同时有很好的灵活性。
Actor模型
○Actor模型于1970年年初被提出,为并行计算而生,理念非常简单:所有对象皆Actor,在Actor之间仅通过发送消息进行通信,所有操作都是异步的,不同的Actor可以同时处理各自的消息,使整个系统获得大规模的并发能力。几乎在所有主流开发平台下都有了Actor模型的实现:Java平台下Scala的Actor类库和Jetlang;NET平台下的MS CCR和Retlang;F#平台下的MailboxProcessor;微软基于MS CCR构建的新语言Axum。
○Smalltalk的设计者、面向对象编程之父Alan Kay曾经这样描述面向对象的本质:
很久以前,我在描述“面向对象编程”时使用了“对象”这个概念。很抱歉这个概念让许多人误入歧途,他们将学习的重心放在了“对象”这个次要的方面,而忽略了真正主要的方面——“消息”。创建一个规模宏大且可水平扩展的系统的关键,在于各个模块之间如何交流,而不在于其内部的属性和行为如何表现。
○Actor模型精心设计了消息传输和封装的机制,强调了面向对象。我们可以将一个Actor类比为一个对象,对象提供了方法以供其他对象调用,等价于一个Actor可以处理某些类型的消息并进行响应,但与方法调用不同,Actor之间的消息通信全部是异步模式,避免了同步方法调用可能产生的阻塞问题,因此很适合高度并行的系统。但是,异步编程这种思维模式大大增加了我们在编程中所耗费的脑力劳动,很难被习惯了CRUD的大众程序员们所接受,所以注定了Actor模型曲高和寡的命运。
微服务架构
○微服务架构是当前很热门的一个概念,是技术发展的必然结果。微服务架构也不是一个缥缈、空洞的术语,它的核心理念与架构原则是实实在在的,虽然微服务架构没有公认的技术标准和规范草案,但业界已经有一些很有影响力的开源微服务架构平台,架构师可以根据公司的技术实力并结合项目的特点来选择某个合适的微服务架构平台,稳妥地实施项目的微服务化改造或开发进程。
○Martin Flower曾这样描述它:“微服务”只不过是满大街充斥的软件架构中的一个新名词而已。尽管我们非常鄙视这样的名词,但其描述的软件风格越来越吸引我们的注意。在过去几年里,我们发现越来越多的项目开始使用这种风格,以至于我们的同事在构建企业级应用时,理所当然地认为这是一种默认开发形式。然而,很不幸,微服务风
格是什么,应该怎么开发,关于这样的理论描述却很难找到。
○在互联网时代,在极端情况下每天都有新需求要开发上线。随着代码量及团队成员的增加,传统单体式架构的弊端日益凸显,严重制约了业务的快速创新和敏捷交付,与互联网所追求的“唯快不破”的目标越来越远。这就是微服务架构兴起的时代大背景。
○微服务架构通过将一个庞大的单体进程分解为相互独立的多个微小进程,以分布式的思想巧妙解决了传统单体架构在互联网时代遭遇的各种问题。所以微服务架构这种新的理念被大家快速接受并且迅速流行,是有深刻原因的。
○为了解决传统单体架构面临的挑战,软件架构先后演进出了SOA架构、RPC架构、分布式服务架构,最后演进为微服务架构。但我们需要牢记一点:软件开发从来不存在
在银弹,因此微服务化架构也不是银弹,它更多的是一种架构思想与开发模式的改变,而在具体实施过程中还存在大量的技术问题及团队问题需要妥善解决。
○微服务架构实施过程中所面临的最大技术问题之一就是开发运维过程中的自动化。假如我们要把原来某个中等规模的系统架构改造为微服务架构,则最少也能拆分出十几个微服务,于是这么多微服务进程的编译、部署、调测及升级就演化成一个浩大的工程了,如果没有自动化的手段,则微服务化是无法推动的。说到自动化,就不得不提到容器技术,它是促进微服务架构发展的重要动力,也是微服务架构得以快速流行的重要原因。
○如何全面理解微服务架构:
- 首先,微服务架构是一个分布式系统架构。也就是说,分布式系统设计的原则、经验,以及常用的分布式基础设施和中间件依然是微服务架构中的重要组成部分,如果抛开分布式架构中的这些技术,只是空谈微服务架构,则好像空中楼阁。
- 其次,与SOA架构一样,微服务架构与开发语言无关,它并没有公认的技术标准规范与实施方案,更多地体现了一种被普遍接受的新的设计理念和指导思想,包括:
● 轻量级的服务:每个服务实例都只提供密切相关的一种或几种服务,粒度小、轻量级,便于微团队快速开发、部署、测试与升级。
● 松耦合的系统:微服务之间的调用也是客户端的一种调用方式,仅限于接口层的耦合,避免了服务实现层的深耦合,因此服务之间的依赖性被降到最低,系统的整体稳定性与平衡升级(滚动升级)能力得到切实保障。
● 平滑扩容能力:由于在微服务架构平台中原生地提供了某种微服务负载均衡机制,因此对于无状态的微服务,可以通过独立部署多个服务进
程实例来提升整体的吞吐量。由于每个微服务都可以单独扩容,因此微服务架构具有很强的运行时的性能调优能力。
● 积木式的系统:每个微服务通常都被设计为复杂业务流程中一个最小粒度的逻辑单元(积木),某个完整的业务流程
就是合理编排(搭积木)这些微服务而形成的工作流,升级或者重新开发一个新业务流程变成了简单的积木游戏,而随着微服务越来越多,业务单元(微服务)的复用价值越来越大,因此新业务快速上线的需求变成了一个可准确评估和预测的计划任务。
最后,微服务架构也有某些事实上公认的框架与工具,目前最经典的有以下三个微服务架构开源平台。
● 从RPC架构演变而来的Ice Grid微服务架构平台。
● 基于REST接口演变而来的Spring Cloud微服务架构平台。
● 基于容器技的Kubernetes微服务架构平台
○选择和落地:如果整个团队对容器技术没有什么经验,则排除Kubernetes,否则优先选择它。如果系统的性能要求很高,同时很多高频流程中涉及大量微服务的调用,以及微服务之间也存在大量调用,则先考虑以RPC二进制方式通信的微服务平台,优先考虑Ice,其次是Kubernetes,最后是Spring Cloud。如果系统中更多的是自己内部开发的各种服务之间的远程调用,很少使用中间件,只需要高性能的通信及水平扩展能力,则Ice可能是最佳选择,其次是Spring Cloud,最后才是Kubernetes。因为Kubernetes并没有提供一个RPC架构,所以在这种情况下,反而增加了系统的复杂性。如果项目是用多个语言协同开发的,则在这种情况下,可以优先选择Kubernetes架构与Ice。
1)引入自动化工具与集中运维管理工具。自
2)研究、测评大量相关开源产品(与工具)并引入微服务架构中。微服务架构本质上是一种分布式架构,所以之前在单体架构开发中所写的一些通用代码是无法被应用到
微服务架构系统中的,比如最常见的配置模块、定时任务、同步逻辑等。此外,对于很多中间件来说,原先可能只用了单节点的方式,而在微服务架构下往往要切换成集群模式,在这种情况下也需要对这些中间件进行更为深入的研究测试,甚至可能会因此转向其他类似的中间件。
3)团队的重构。在微服务模式下,整个系统从架构层来看基本只分为展现层与微服务层。考虑到微服务在整个系统中的重要性,建议团队中的骨干技术人员成为微服务层的开发主力,大家作为一个总体对所有微服务代码负责,一起设计每个微服务接口,一起评审所有微服务代码,而在具体的开发过程中,则可以将相似度较高的几个微服务模块交由同一个人研发。这种模式基本符合二八定律。
4)高质量的文档。在微服务架构下,文档特别是每个微服务的接口文档的重要性越来越高,因为每个使用微服务的人都要清楚当前所要调用的微服务是哪个、应该调用哪个接口、参数有什么含义,以及返回值的意义。因此,我们需要一份详细并且准确的微服务接口文档,还要保持文档与代码同步更新。
○如何设计系统中的微服务。一开始,我们其实并不很清楚要将哪些功能和服务设计成一个微服务,以及一个微服务究竟应该包括多少个接口,每个接口应该如何设计。笔者的建议是先粗粒度地划分微服务,每个微服务包括比较多的接口以减少微服务的个数,这样可以减少开发、程序打包、测试及部署的工作量,有利于快速推进项目。
系统中的微服务按照调用客户端的不同,可以划分为流程控制类、接口类及基础核心类三种,一般来讲,这三种不同的微服务的接口设计也有所不同。流程控制类微服务主要面向UI调用,所以它的接口设计应该以页面展示的便利性为第一目标,即大部分情况下采用JSON或TEXT文本的方式传递参数与返回值,并且考虑在调用逻辑出错的情况下告诉客户端错误的代码与原因,于是这类微服务的返回值通常会是下面的结构体:
接口类微服务主要面向第三方系统,所以特别需要注意安全问题,因此在接口设计中必须有安全措施,比较常见的方案是在调用参数中增加Token,并考虑参数加密的问题,同时建议接口类微服务在实现过程中重视日志的输出问题,以方便接口联调,并方便在运行期间排查接口故障,在日志中应该记录入口参数、关键逻辑分支、返回结果等重要信息。
○Spring Cloud微服务架构:Spring Cloud是基于Spring Boot的一整套实现微服务的框架,因此它只能采用Java,这是它与其他几个微服务架构的明显区别。Spring Cloud是一个包含了很多子项目的整体方案,其中由Netflix开发后来又并入Spring Cloud的Spring Cloud Netflix是Spring Cloud微服务架构的核心项目,即可以简单地认为Spring Cloud微服务架构就是Spring Cloud Netflix。
○基于消息队列的微服务架构:除了标准的基于RPC通信(以及类RPC的通信如HTTP REST、SOAP等)的微服务架构,还有基于消息队列通信的微服务架构,这种架构下的微服务采用发送消息(Publish Message)与监听消息(Subscribe Message)的
的方式来实现彼此之间的交互。基于消息队列的微服务架构是全异步通信模式的一种设计,各个组件之间没有直接的耦合关系,也不存在服务接口与服务调用的说法,服务之间通过消息来实现彼此的通信与业务流程的驱动,从这点来看,基于消息队列的微服务架构非常接近Actor模型。网易的蜂巢平台就采用了基于消息队列的微服务架构设计思路,微服务之间通过RabbitMQ传递消息,实现通信。与上面几种微服务架构相比,基于消息队列的微服务架构并不多,案例也相对较少,更多地体现为一种与业务相关的设计经验,各家有各家的实现方式,缺乏公认的设计思路与参考架构,也没有形成一个知名的开源平台。如果需要实施这种微服务架构,则基本上需要项目组自己从零开始设计一个微服务架构基础平台,其代价是成本高、风险大,在决策之前需要架构师“接地气”地进行全盘思考与客观评价。
○深入Kubernetes微服务平台:架构师普遍有这样的愿景:在系统中有ServiceA、ServiceB、ServiceC这3种服务,其中ServiceA需要部署3个实例,ServiceB与ServiceC各自需要部署5个实例,希望有一个平台(或工具)自动完成上述13个实例的分布式部署,并且持续监控它们。当发现某个服务器宕机或者某个服务实例发生故障时,平台能够自我修复,从而确保在任何时间点正在运行的服务实例的数量都符合预期。这样一来,团队只需关注服务开发本身,无须再为基础设施和运维监控的事情头疼了。
○在Kubernetes出现之前,没有一个平台公开声称实现了上面的愿景。Kubernetes是业界第一个将服务这个概念真正提升到第一位的平台。在Kubernetes的世界里,所有概念与组件都是围绕Service运转的。正是这种突破性的设计,使Kubernetes真正解决了多年来困扰我们的分布式系统里的众多难题,让团队有更多的时间去关注与业务需求和业务相关的代码本身,从而在很大程度上提高整个软件团队的工作效率与投入产出比。
Kubernetes里的Service其实就是微服务架构中微服务的概念,每个Service都分配了一个固定不变的虚拟IP地址——Cluster IP。每个Service都以TCP/UDP方式在一个或多个端口(Service Port)上提供服务。客户端访问一个Service时,就好像访问一个远程的TCP/UDP服务,只要与Cluster IP建立连接即可,目标端口就是某个Service Port。
Service既然有了IP地地址,就可以顺理成章地采用DNS域名的方式来避免IP地址的变动了Kubernetes的DNS组件自动为每个Service都建立了一个域名与IP的映射表,其中的域名就是Service的Name,IP就是对应的Cluster IP,并且在Kubernetes的每个Pod(类似于Docker容器)里都设置了DNS Server为Kubernetes的DNS Server,这样一来,微服务架构中的服务发现这个基本问题得以巧妙解决,不但不用复杂的服务发现API供客户端调用,还使所有以TCP/IP方式通信的分布式系统都能方便地迁移到Kubernetes平台上。Kubernetes里的Service与Pod是如何对应的呢?我们怎么知道哪些Pod为某个Service提供具体的服务?答案是“贴标签”。每个Pod都可以贴一个或多个不同的标签(Label),而每个Service都有一个“标签选择器”(Label Selector),标签选择器确定了要选择拥有哪些标签的对象。比如在YAML格式的内容定义了一个被称为ku8-redis-master的Service,它的标签选择器的内容为“app:ku8-redis-master”,表明拥有“app=ku8-redis-master”这个标签的Pod都是为它服务的。
○Kubernetes的组成与原理
● controller manager:负责所有自动化控制事物,比如RC/Deployment的自动控制、HPA自动水平扩容的控制、磁盘定期清理等各种事务。
● scheduler:负责Pod的调度算法,在一个新
Pod被创建后,Scheduler根据算法找到最佳Node节点,这个过程也被称为Pod Binding。
● kubelet:负责本Node节点上Pod实例的创建、监控、重启、删除、状态更新、性能采集并定期上报Pod及本机Node节点的信息。由于Pod实例最终体现为Docker容器,所以Kubelet还会与Docker交互。
● kube-proxy:为Service的负载均衡器,负责建立Service Cluster IP到对应的Pod实例之间的NAT转发规则,这是通过Linux iptables实现的。
○在我们通过kubectrl create命令创建一个RC(资源对象)时,kubectrl通过Create RC这个REST接口将数据提交到API Server,随后API Server将数据写入Etcd里持久保存。与此同时,Controller Manager监听(Watch)所有RC,一旦有RC被写入Etcd中,Controller Manager就得到了通知,它会读取RC的定义,然后比较在RC中所控制的Pod的实际副本数与期待值的差异,然后采取对应的行动。此刻,Controller Manager发现在集群中还没有对应的Pod实例,就根据RC里的Pod模板(Template)定义,创建一个Pod并通过API Server保存到Etcd中。类似地,Scheduler进程监听所有Pod,一旦发现系统产生了一个新生的Pod,就开始执行调度逻辑,为该Pod安排一个新家(Node),如果一切顺利,该Pod就被安排到某个Node节点上,即Binding to a Node。接下来,Scheduler进程就把这个信息及Pod状态更新到Etcd里,最后,目标Node节点上的Kubelet监听到有新的Pod被安排到自己这里来了,就按照Pod里的定义,拉取容器的镜像并且创建对应的容器。在容器成功创建后,Kubelet进程再把Pod的状态更新为Running并通过API Server更新到Etcd中。如果此Pod还有对应
应的Service,每个Node上的Kube-proxy进程就会监听所有Service及这些Service对应的Pod实例的变化,一旦发现有变化,就会在所在Node节点上的iptables里增加或者删除对应的NAT转发规则,最终实现了Service的智能负载均衡功能,这一切都是自动完成的,无须人工干预。那么,如果某个Node宕机,则会发生什么事情呢?假如某个Node宕机一段时间,则因为在此节点上没有Kubelet进程定时汇报这些Pod的状态,因此这个Node上的所有Pod实例都会被判定为失败状态,此时Controller Manager会将这些Pod删除并产生新的Pod实例,于是这些Pod被调度到其他Node上创建出来,系统自动恢复。
○基于Kubernetes的PaaS平台,一个PaaS平台应该具备如下关键特性。
● 多租户支持:这里的租户可以是开发厂商或者应用本身。
● 应用的全生命周期管理:比如对应用的定义、部署、升级、下架等环节的支持。
● 具有完备的基础服务设施:比如单点登录服务、
基于角色的用户权限服务、应用配置服务、日志服务等,同时PaaS平台集成了很多常见的中间件以方便应用调用,这些常见的中间件有消息队列、分布式文件系统、缓存中间件等。
● 多语言支持:一个好的PaaS平台可以支
多种常见的开发语言,例如Java、Node.js、PHP、Python、C++等。
○Kubernetes通过Namespace特性来支持多租户功能。但单纯的Namespace隔离并不能阻止不同Namespace下的网络隔离,如果知道其他Namespace中的某个Pod
的IP地址,则我们还是可以发起访问的。针对多租户的网络隔离问题,Kubernetes增加了Network Policy这一特性,我们简单地将它类比为网络防火墙,通过定义Network Policy资源对象,我们可以控制一个Namespace(租户)下的Pod被哪些Namespace访
问。假如我们有两个Namespace,分别为tenant2、tenant3,各自拥有一些Pod。
○Kubernetes分区与租户可以有多种对应的设计,上面所说的一个分区一个租户的设计是一种典型的设计,也可以将租户分为大客户与普通客户,每个大客户都有一个单独的资源分区,而普通客户可以以N个为一组,共享同一个分区的资源。
○应用的全生命周期管理过程的第一步,就是从源码到Docker镜像的打包,而
这个过程很容易实现自动化,我们既可以通过编程方式实现,也可以通过成熟的第三方开源项目实现,这里推荐使用Jenkins。
○第1类重要的基础中间件是ZooKeeper,ZooKeeper非常容易被部署到Kubernetes集群中,在Kubernetes的GitHub上有一个YAML参考文件。第2类重要的中间件就是缓存中间件了,比如我们之前提到的Redis及Memcache,它们也很容易被部署到Kubernetes集群中,作为基础服务提供给第三方应用使用。第3类重要的中间件是消息队列中间件,不管是经典的ActiveMQ、RabbitMQ还是新一代的Kafka,这些消息中间件也很容易被部署到Kubernetes集群中提供服务。
○Service Mesh:Kubernetes平台很好地解决了大规模分布式系统架构中的一些通用问题,从基本的自动化部署、服务注册、服务发现、服务路由,到全自动化的运维体系,几乎面面俱到。但由于Kubernetes致力于从更基础的TCP/IP层面提供更
更广泛的分布式系统的统一架构方案,因此必定以牺牲上层应用层协议的适配为代价。我们看到Kubernetes在解决一些问题时多少有些“鞭长莫及”:
● 在自动部署方面无法实现灰度发布;
● 在服务路由方面无法按照版本或者请求参数实现精细化路由;
● 在服务保护方面无法实现类似于Spring Cloud中的熔断机制或服务限流;
● 在安全机制方面服务之间的调用安全问题缺失
● 在全链路监控方面几乎空白。
Kubernetes致力于打造一个基于TCP/IP层的大统一的分布式系统支撑平台,Service Mesh则围绕着HTTP的分布式系统提供了更细粒度、更丰富的架构方案。Service Mesh最早的开源版本是Linkerd,它最初采用了Scala,一经公布,就引发业界的广泛关注。随后谷歌、IBM与Lyft(美国第二大打车公司,其愿景是让人们乘坐无人驾驶汽车出行)联手发布了Istio这个开源版本。Linkerd在2.0版本中改为采用Rust和Go后,性能和稳定性大幅提升,并且基于Kubernetes平台部署,但仍难抵Istio的优势。Istio的核心毫无疑问是Envoy,Envoy在本质上是一个(反向)HTTP代理服务器,抓住这个核心,我们就能很好地理解Envoy的配置、功能和使用方法了。
读书笔记的六种符号
符号说明:个人使用如下六种符号进行摘录、总结和分析
○ 参考内容:原书摘录
● 参考内容:原书复述
△ 注意事项:原书注意事项
▲ 注意事项:强调注意事项
☆ 体会总结:值得参考内容
★ 体会总结:强调参考内容