随着云原生与微服务技术的逐步发展,业界也逐步构建出一整套比较完整的微服务技术体系。
面向云原生时代,微服务架构是从业人员绕不开的一个话题,腾讯云AI&腾讯优图的内容风控安全审核能力也与微服务技术息息相关。
本文总结了业内最新的技术沉淀,从相对宏观的角度去讲述微服务的问题域与挑战点,并深入细节讲述一些微服务关键技术,包括微服务拆分微服务间通信机制,分布式事务微服务,可观测安全性等。
目前微服务还在不断发展中,有很多技术还未发展到成熟阶段,希望本文能够帮助大家拥有基本的了解。
01.什么是云原生
上图是CNCF对云原生的定义,从字面意义上来讲,cloud native就等于cloud+native。简单来说,云原生代表着因云而生。它主要包含以下方面:
02.微服务架构的优缺点:没有银弹
(1)问题的产生背景:
1)单体架构本身并无错
①适合于项目早期阶段,应用简单、规模小。
②开发、测试、部署、运维简单
③横向扩展简单但随着时间推移,功能越来越复杂、开发团队越来越大,开发、测试、部署、扩展变得更加困难。
2)单体地狱的到来
①系统变得庞大而复杂,开发者望而生畏
②开发速度缓慢
③CICD变成遥不可及
④扩展困难
⑤高可用交付困难
⑥历史包袱重,不得不面对过时的技术栈
(2)具体来说:
1)通常,在设计阶段要设计 10 到 100 倍左右的逻辑容量,因为在后期修改设计会带来很高的难度,所以要提前设计好冗余容量。
2)在实现阶段,通常要按照 5 到 10 倍左右的容量进行实现,实现阶段需要付出一定的成本,没有必要为非常长远的将来实现,可以随业务的进展而逐步实现设计时最大容量。
3)部署阶段,以 2 到 5 倍的容量进行部署,可以应付一段时间内的容量增长。
4)但如果是预期的增长非常大,就要采用更加灵活的云部署手段,并为突发峰值做好预案准备。
(3)"银弹"来源 ?
在欧洲中世纪的传说中,有一种叫“人狼”的妖怪,就是人面狼身。它们会讲人话,专在月圆之夜去袭击人类。而且传说中对“人狼”用一般的枪弹是不起作用的,普通子弹都伤不到也打不死它,只有一种用银子做成的特殊子弹才能把它杀死。
*s在他最著名的随笔文章《No Silver Bullet》里引用了这个典故 ,说明在软件开发过程里是没有万能的终杀性武器的,只有各种方法综合运用,才是解决之道。而各种声称如何如何神奇的理论或方法,都不是能杀死“软件危机”这头人狼的银弹。他当时大胆声称并预言方法学家们10年之内绝找不到什么好的的神奇银弹。他的文章发表后,被广泛引用,后来他的随笔结集成书,《人月神话》。
从此,在软件界,银弹(Silver Bullet)成了一个通用的比拟流行开来。1975年所出版的《人月神话》—被称为软件工程圣经。
(4)微服务的特性与优缺点
1)微服务的两个关键特性
①微服务之间松耦合,仅通过API进行通信
②每个微服务都有自己独立的数据库
2)微服务的优点
①使得大型复杂持续可以持续交付持续部署
②每个服务都相对较小并且易于维护
③服务可以独立部署
④服务可以独立扩展
⑤微服务架构可以实现团队的独立自治
⑥更容易实验和采纳新技术
⑦更好的容错性
3)微服务的缺点
①服务拆分和定义是一项挑战
②分布式系统带来的复杂性,使得开发、测试、部署变得更加困难
③当部署跨越多个服务的功能时,需要谨慎的协调更多的开发团队
④开发者需要思考在什么阶段使用微服务
03.如何拆分单体服务:领域驱动设计大放异彩
(1)什么是领域驱动?
Eric Evans于2003年提出的。主要解决随着业务越来越复杂,大量的逻辑堆积在一个巨型类中的例子屡见不鲜,代码的复用性和扩展性无法得到保证。DDD是一套前人总结出来的模式,用于解决上述的业务问题。
(2)领域驱动设计是如何解决上述问题的?
1)第一步考虑把需求分解成一个一个子问题域。
2)第二步把每个子问题域分解成一个一个聚合对象,应用程序通过各种子问题域之间的编排与协作,从而实现复杂的业务逻辑满足业务需求。
3)DDD是解决复杂中大型软件的一套行之有效方式,在微服务领域已成为主流技术。
(3)DDD的标准使用姿势
1)产品需求与愿景对产品的顶层价值设计,对产品目标用户、核心价值、差异化竞争点等战略层信息达成一致,避免产品在演进过程中偏离方向。
参与角⾊:业务需求方、产品经理、开发
2)用户旅程分析针对核心用户及顶层服务的一种定性分析,从⽤户视角出发,探索问题域中的典型场景分析。同时也是从用户视角对问题域的探索,产出问题域中需要支撑的场景分类及典型场景,用以支撑领域建模阶段。
参与角色:产品经理、开发、测试
3)领域建模通过对业务和问题域进⾏分析,建⽴领域模型,向上通过限界上下⽂指导微服务的边界设计,向下通过聚合指导实体的对象设计。领域建模主要采用事件风暴方法。
参与角色:领域专家、架构师、产品经理、开发和测试
4)微服务Map整个产品服务架构的体现。结合业务与技术因素,对服务的粒度、边界划分、集成关系进⾏梳理,得到反映系统微服务层面设计的服务地图。
参与角色:产品经理、开发、测试
5)需要结合业务与技术进行综合考虑:
①聚焦限界上下⽂边界
②基于不同业务特点,区分稳定与易变动
③考虑系统非功能性需求,如HA、扩展性、性能、安全性等
④考虑团队组织和沟通效率
(4)最重要的几条设计准则
1)职责单一原则改变一个类只有一个理由。
2)闭包原则如果要对包做出修改,则需要涉及修改的类都在包内。
(5)拆分单体服务的难点在哪里?
1)网络延迟
2)整体可用性降低
3)数据一致性
4)获取一致的数据查询视图
5)上帝类
04.微服务进程间通信模式
(1)微服务进程间通信模式选择的结论
1)首选基于异步消息通讯模式
2)主要考虑因素
①微服务之间如何交互
②IPC技术选型
③API如何持续迭代
④如何处理失败情况
⑤功能层面对延迟的容忍性
(2)具体要点如下:
1)微服务之间如何交互
①同步还是异步?
②一对一还是一对多?
2)IPC技术选型
主要三大类主流技术选型:
①REST
优点:HTTP简单门槛低;易于Debug测试;防火墙友好;不需要中间层,架构简单。
缺点:服务端与客户端必须同时在线;客户端必须知道每个服务端实例的地址。
②RPC
优点:设计复杂API的工作比较简单;数据交互更加紧凑;支持双向流式。
缺点:客户端使用门槛更高,尤其是JS前端;旧式防火墙限。
③基于消息
优点:客户端解耦;消息缓冲;更加灵活的交互方式。
缺点:额外操作的复杂度,增加了消息中间件;实现方式复杂度更高,还需要综合考虑使用二进制消息还是文本消息、以及如何解决消息的顺序消费、重复消息等问题。
3)API如何持续迭代
①版本兼容的改变:新增操作、增加可选项等
②语义化版本控制:当不得不做非兼容的API变更时基于HTTP的,可以在路径的第一个元素使用版本号;基于消息的,在消息内容增加版本号。
4)如何处理部分服务失败情况
①所有的同步服务,必须设置超时时间
③断路器模式
③限流功能:必须限制客户端向服务端发送的请求数
5)功能层面对延迟的容忍性
①异步交互带来的延迟性增加
②客户端多次API交互带来的延迟性增加
05.如何实现多微服务之间的高效数据分发
(1)问题产生的背景
基于微服务架构设计的系统,消息队列是首选的中间件。在一个微服务里,经常会出现既要写本地数据库,又要同时把数据写到MQ供外部的微服务进行消费处理这两个步骤。
(2)使用双写解决存在两个比较大的问题
1)因为网络等原因,MQ数据写成功了,但是双写逻辑已经未成功,DB回滚了,数据不一致?
2)如果MQ临时不可用,整个用户请求需要被取消,有些时候无法接受,耦合也更大。
(3)事务发件箱两种实现方式
(4)采用的主流开源
1)canal:https://github.com/alibaba/canal
2)debezium:https://github.com/debezium/debezium
06.如何实现跨多个微服务的分布式事务
(1)什么是事务
1)传统关系型数据库事务,主要包括四点:
① 原子性要么全做,要么全不做
②一致性从一种一致性状态转移到另一种一致性状态。这里的一致性状态主要是两个维度:
1.数据的完整性约束,如主键唯一性约束、外键约束、函数约束等。
2.系统的状态满足真实世界的一致性状态。比如转账前后两个账户总和加一起相等。
3.隔离性并发执行的事务不会相互影响。
4.持久性事务一旦提交,结果就是永久性的。
③从以上说明可以看出来:一致性是根本追求,原子性与隔离性是实现一致性的前提。
2)分布式事务
①分布式事务的问题域分布式事务是为了解决分布式系统中不同节点之间的数据一致性问题。即一个请求在多个微服务调用链中,所有参与的微服务的数据处理要么全部成功,要么全部回滚。
②什么是分布式系统的数据一致性一致性,是指对每个节点的任何数据的更新,整个集群都知道更新,并且拥有一致的视图。需要满足几点条件:全认同、值合法、可结束
③分布式事务的面临的问题是什么消息传递异步无序、节点宕机、节点宕机恢复、网络分裂、拜占庭将军问题。
(2)从2PC、3PC到TCC、SAGA
1)2PC协议
①阶段一:准备阶段
由协调者发起并传递带有事务信息的请求给各个参与者,询问是否可以提交事务,并等待返回结果。各个参与者执行事务操作,将Undo和Redo放入事务日志中(但是不提交)。
②阶段二:提交阶段提交事务:(所有参与者均反馈YES)
协调者向所有参与者发出正式提交事务的请求(即Commit请求)。参与者执行Commit请求,并释放整个事务期间占用的资源。各参与者向协调者反馈Ack完成的消息。协调者收到所有参与者反馈的Ack消息后,即完成事务提交。
③中断事务:(任何一个参与者反馈NO或者发生超时)
协调者向所有参与者发出回滚请求(即Rollback请求)。参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。各参与者向协调者反馈Ack完成的消息。协调者收到所有参与者反馈的Ack消息后,即完成事务中断。
④2PC协议存在的问题:
性能问题:所有参与者的事务处理逻辑都处在同步阻塞状态。
单点问题:协调者存在单点问题,如果协调者故障,参与者将一直处在锁定状态。
脑裂问题:阶段2 Commit阶段,如果部分参与者执行,会出现数据不一致问题。
容错性差:任何一个节点失败都会导致整个事务失败。
2)3PC协议
①阶段一:CanCommit
协调者向所有参与者发出包含事务内容的CanCommit请求,询问是否可以提交事务,并等待所有参与者答复。参与者收到CanCommit请求后,如果认为可以执行事务操作,则反馈YES并进入预备状态,否则反馈NO。
②阶段二:PreCommit
如果canCommit阶段所有参与者都返回OK,则进入事务预提交阶段。与2PC阶段一类似。这里多引入了参与者超时机制
③阶段三:DoCommit
和2PC的阶段2基本类似
④3PC相比2PC究竟优化了什么
1.性能优化。引入了canCommit阶段,减少了事务的阻塞范围。
2.单点问题优化。引入了参与者超时机制,避免了协调者宕机后,参与者长期锁定状态。
⑤存在的缺点:
脑裂问题依然存在,面对数据一致性问题,3PC依然无法很好地解决。面对2PC提到的无解的问题,3PC有了一定程度的优化。
3)TCC(Try-Confirm-Cancel)
①Try阶段:对下游服务做状态检测以及进行资源预留。
②Confirm阶段:确认下游服务操作,将预操作变成正式操作,完成事务。
Cancel阶段:取消下游服务的预留操作,恢复到之前状态,完成事务。
③TCC适用场景:
(同步模式)适用于执行时间确定且较短的核心业务,一般像金融、电商领域的支付交易等。
(异步模式)基于MQ来实现,一般适用于对响应时间不敏感的辅助业务,如消息推送等。
④优点:
应用层面的2PC协议,可以让开发人员基于自身的业务特点,合理的选择DB操作的粒度、控制锁定的范围,降低冲突,提升性能与吞吐。
②缺点:
对应用的侵入性很强,每个应用服务都需要提供Try-Confirm-Cancel接口,还需要处理各种复杂的异常处理,以及设计回滚策略,以及接口必须满足幂等性要求。
⑥主流的开源框架:Himly、ByteTCC、 TCC-transaction
4)SAGA
①Saga最初出现在1987年Hector Garcaa-Molrna & Kenneth Salem发表的论文SAGAS
②Saga用于解决Long Live Transaction(LLT)
③Saga分布式事务 = N个本地事务T1、T2、T3……TN
④每个事务Tx都有一个对应的补偿事务Cx
⑤采用逆向补偿流程:T1、T2、T3(失败)、C3、C2、C1
⑥实现上主要有两种主流的方式
协同式Saga:Saga的决策与执行逻辑分布在各个参与方,通过交换事件的方式沟通协调。
编排式Saga:Saga的决策与执行逻辑集中在编排器内,编排器发送命令式消息给各个saga参与方。
⑦开源方案:
Apache ServiceComb Pack :
https://github.com/apache/servicecomb-pack
⑧SAGA与TCC的简单对比
1.都是基于补偿的分布式事务实现方式,满足最终一致性,柔性事务。
2.TCC业务倾入较之Saga更大,多了一个confirm接口。
3.Saga缺乏数据隔离性支持,数据不一致风险更高;TCC的try接口对数据一致性提供了支持。
4.Saga基于异步消息机制,对延迟要求高的场景下不如TCC。
07.如何获取一致性的数据视图:API组合+CQRS
(1)问题产生的背景
采用微服务架构后,不可避免地出现,从产品功能维度看,某些客户端请求需要一次性获取多个微服务的聚合数据结果。
(2)API组合模式
顾名思义,通过查询下游相关的微服务的结果,对数据进行组合返回。
(3)API组合的问题域
1)架构层面,API组合器放在哪里来实现?有三种选择:
①放在客户端来实现
②放在API Gateway
③独立的API组合器服务
2)如何编写有效的聚合?
需要妥善的处理执行顺序、并发执行等问题
3)增加了额外的开销
4)整体可用性的降低
5)缺乏数据一致性的视图
(4)CQRS
(Command Query Responsibility Segregation)
1)命令查询职责隔离。将系统分为:命令端和查询端。命令端实现CUD操作,查询端实现查询(Query)。查询端通过订阅命令端发布的事件,使其数据与命令端数据保持同步一致。
2)Why CQRS?
①API组合实现性能低,无法满足
②API组合功能层面的无法支持
③需要数据一致性视图的场景
④架构解耦,职责分离
3)使用场景与优缺点CQRS的优势
①查询性能更好
②支持更加丰富的查询
③优化的数据结构:命令端、查询端均可聚焦核心需求选择数据结构
④扩展性更好:命令端、查询端可以独立扩展
⑤职责分离带来的关注点分离
4)CQRS的劣势
①架构更加复杂
②增加延迟 ,最终一致性
08.微服务架构演进:API Gateway + BFF
(1)API Gateway
1)什么是API Gateway
首先是一个服务(service),是外部API客户端进入应用系统的入口点。
2)API Gateway的核心功能
①统一接入、请求路由
① 协议转换
② API组合器
④实现非功能性的边缘功能:认证鉴权、限流、缓存、指标收集、日志等。
(2)BFF(Backend For Frontend)
1)什么是BFF
为每种类型的客户端实现单独的API gateway功能
2)产生背景
每种不同的设备,需要使用功能相似却又不同的API版本
3)主要功能
API裁剪、API组合、协议适配
4)BFF的优点
较之单一通用的API接口,BFF可以解决其接口不稳定、职责不单一的问题。较之单一通用的API接口,BFF只返回所需的数据,性能更好。可以充当部分API组合器的工作,提升响应延迟。
5)BFF的缺点
存在大量的重复代码工作,加大了开发的工作量。
(3)架构设计的原则(来自架构即未来The Art of Scalability)
(4)分布式系统架构演进史
1)第一阶段:web应用时代
2)第二阶段 无线应用开始
3)第三阶段 无线应用高速发展
4)第四阶段 中台开放平台时代
①架构发展相对成熟,职责清晰
②API网关聚焦边缘功能
③BFF聚焦裁剪与适配
④微服务层稳定、功能聚焦
09.微服务可观测性:OpenTelemetry
(1)什么是OpenTelemetry?它的边界在哪里?
(2)OpenTelemetry的问题域:
1)OpenTelemetry提供的是一组API、SDK规范,规范trace、metrics、logs 等数据的生成格式。
2)OpenTelemetry不提供与可观测相关的后端服务,如存储、查询、可视化等。3)OpenTelemetry支持第三方开发各种插件化的exporter将标准格式的数据导入到如Prometheus、ES甚至各种存储。
(3)公司级:OpenTelemetry Oteam
满足标准的有:天机阁(支持完整)、腾讯云APM(trace)等。
10.微服务的安全性:Oauth2&JWT
(1) 微服务安全性的问题域
1)主要聚焦在身份验证、访问授权两块
2)HTTP协议无状态特性。
(2)Cookie:客户端缓存技术
1)Http Cookie:服务器发送给浏览器的一块数据,浏览器存储在本地,再浏览器后续请求服务器时均带上Cookie信息。
2)主要存在的问题:
1)用户信息都存储在客户端,一旦劫持全部泄露。
2)Cookie信息多,每次请求都带上,流量大。
(3)Session机制:服务端缓存
1)Session机制:与Cookie机制将所有的用户信息存储在本地不同,Session机制将用户信息存储在服务端,给用户分配一个代表其唯一性身份的ID。客户请求带上SessionID。
2)实现方式上:
①SessionID存储在客户端Cookie
②改写URL或者HTTP Body等
3)Session机制存在的问题:
①大量的Session上下文数据存储在服务端,成本大
①分片策略带来的扩展复杂
(4)Token机制:客户端存储+服务端校验
1)客户端发送登录请求到服务端。
2)服务端验证登录信息,生成Token。
3)客户端存储Token,后续请求带上Token。
4)服务端校验客户端的Token,验证通过则提取Token的信息进行后续逻辑,否则拒绝访问。
(5)JWT(Json Web Token)
1)原理服务器认证后,生成一个 JSON 对象,发回给用户。这个Json对象可以附带关键性的用户信息,如ID、角色、过期时间等。
2)数据格式:
Header.Payload.SignatureHeader:主要记录采用的加密算法等信息
Payload:用户数据消息体Signature:根据header的加密算法,以及payload信息以及密钥来生成。
3)JWT存在的问题
①过期之前,服务端无法终止用户请求
②与Token问题一样,一旦泄露,任何人均可以获取此令牌的所有权限所以实际使用时:过期时间要设置较短,采用Https安全传输
(6)OAuth2.0
1)什么是OAuth2.0?
一个经过验证的安全标准,其中的关键概念包括:授权服务器、访问令牌、刷新令牌、资源服务器、客户端。
11.服务治理:ServiceMesh技术
(1)服务治理
微服务的服务治理主要包含
(1)服务注册
(2)服务发现
(3)流量管理:如负载均衡、限流等。
(2)什么是ServiceMesh
服务网格是一个基础设施层,用于处理服务间通信。云原生应用有着复杂的服务拓扑,服务网格保证请求在这些拓扑中可靠地穿梭。在实际应用当中,服务网格通常是由一系列轻量级的网络代理组成的,它们与应用程序部署在一起,但对应用程序透明。
(3)ServiceMesh的几大特点
1)微服务之间的通信中间件
2)应用程序无感知
3)屏蔽应用程序网络通信的复杂性,如重试/超时、监控、追踪和服务发现等。
(4)发展历程:参考《Pattern: Service Mesh》
1)第一代开发人员要自己处理各种网络通信面临的一系列丢包、乱序、流量控制、拥塞控制等问题,实现可靠传输。
2)第二代TCP协议出现,开发人员可以从协议栈相关功能中解放出来,基于TCP/IP协议栈进行编程。
3)第三代:随着分布式系统的发展,一些面向分布式系统的技术逐步沉淀,开始出现一些如服务发现、熔断机制、限流策略等新的行业技术。
4)第四代:技术持续发展,大家开始将一些共性的技术开始进行抽象剥离,形成统一的服务框架,比较典型有Dubbo,Spring Cloud等。
5)第五代:ServiceMesh各种框架门槛高、对业务代码侵入性相对较强,且支持语言有限。
(5)ServiceMesh技术的问题
1)通过代理转发带来的通信延迟增加,系统性能损失
2)引入ServiceMesh带来的系统复杂度与运维复杂度
(6)关于ServiceMesh技术的看法
对技术Open心态,生产环境使用谨慎!
更多是了解技术发展背景以及背后的驱动力,开拓技术视野!
12.参考与推荐阅读
《The Art of Scalability》架构即未来
《微服务架构设计》
《企业IT架构转型之道》
《从Paxos到Zookeeper:分布式一致性原理与实践》
《领域驱动设计》
《MICRO-SERVICES ARCHITECTURE WITH OAUTH2 AND JWT》
欢迎关注“腾讯云AI平台”公众号
获取《2021年中国计算机视觉市场报告》
回复【入群】可添加云AI小助手,加入云AI产品、技术、认证等相关社群
回复【云梯计划】可了解更多TCA腾讯云人工智能从业者认证限时免费相关信息
回复【产品手册】可获得最新腾讯云AI产品及解决方案手册