《企业IT架构转型之道》读书笔记

2020-06-17 00:00:00 数据 事务 分布式 业务 服务

本书的全名为:企业IT架构转型之道-- 阿里巴巴中台战略思想与架构实践,作者为钟华,2017年6月第1版。

全书主要分为三大部分:引子(1-2),共享服务体系搭建(3-9),阿里巴巴能力输出与案例(10-11)。

一、阿里启动中台战略

  • 2015年底,启动阿里集团2018年中台战略,构建符合DT时代的更具创新性、灵活性的“大中台、小前台”组织机制和业务机制,即作为前台的一线业务会更敏捷、更快速适应瞬息万变的市场,而中台将集合整个集团的运营数据能力、产品技术能力,对各前台业务形成强力支撑。
  • Supercell模式:一般来说两个员工 ,或5个员工,多不超过7个员工组成独立的开发团队,称之为cell。团队决定自己做什么产品,然后快的时间推出产品的公测版,看游戏是否受用户欢迎。如果用户不欢迎,迅速放弃这个产品,再进行新的尝试,期间几乎没有管理角色的介入。
    • 这种强大的业务试错能力是Supercell相比于其他游戏公司大的差别,也是核心的竞争力。
    • 不可忽略的是Supercell所构建的“中台”能力,抛开个人水平高低的影响,Supercell公司在多年的游戏研发中积累了非常科学的研发方法和体系。
  • “烟囱式”系统建设模式:
    • 普遍的企业IT建设模式,基于业务需求建设系统。导致烟囱林立。
    • 三大弊端:
      • 1. 重复功能建设和维护带来的重复投资。成本和资源浪费。
      • 2. 打通“烟囱式”系统间交互的集成和协作成本高昂。实施SOA项目,构建企业服务产品线,基于服务的方式来解决交互问题,其中牵涉大量的协同和开发成本 。
      • 3. 不利于业务的沉淀和持续发展。ESB是解决不同系统间互联互通的好架构,但各个系统自顶向下的建设模式,导致了新的业务发现现有服务不能很好地满足需要后,原服务方可能不想改造服务,或改造可能对原有业务带来极大风险,导致新业务方不得不再造一个烟囱。
    • 烟囱方式建设的系统体系,导致企业中一个业务领域的数据和业务往往被打散在不同的系统中,采用系统打通的方式解决了眼前的业务交互问题,但治标不治本。
  • SOA理念核心的价值:松耦合的服务带来业务的复用,通过服务的编排助力业务的快速响应和创新。
  • 共享服务中心:
    • 不管前端业务形态如何多样,提供的服务都能很好地包含了核心服务,让前端业务的交易信息和数据回流到对应的服务中心。
    • 原生地将相关业务领域的业务功能和数据做了很好的统一,前端构建的业务实际上没有实现系统业务互通的诉求。大程度避免了“重复功能建设和维护带来的成本浪费”和“打通不同系统的业务交互带来的集成和协作成本”。
    • 服务不需要“业务稳定”。一个服务如果一味追求功能的不变,一定程度上就是固步自封,逼其他业务系统重复造轮子。
    • 服务需要不停的滋养,只有在滋养中才能从初仅提供单薄业务功能的服务逐渐成长为企业为宝贵的IT资产,而服务所需的滋养正是来自新业务的不断进行服务接入。终使这些服务变得更加专业和稳定。
  • 小前端团队:
    • 团队协同效率高,短时间内达成意见的统一和行动步调的一致。
    • 对商机的把握更加敏锐。小团队如同一个小的创业团队,忧患意识更强。
    • 调整方向更加快捷。以小团队的方式试错,一旦业务方向性错误,不管是调整方向还是放弃业务,企业需要投入的资源都在可控范围内。
    • 一旦发现正确目标,全力投入扩大战果。

二、分布式服务框架

  • 淘宝单一系统模式的弊端:
    • 团队协同成本高,业务响应越来越慢。上线前分支合并,各种包冲突,代码冲突,需要各团队间进行确认和协调。
    • 应用复杂度已超出人的认知负载。各种业务错综复杂,牵一发而动全身。
    • 错误难于隔离。非核心功能可能引起整个淘宝平台的业务受影响。所有代码运行在同一个环境中(JVM),任何一个小问题都可能造成应用实例的崩溃。
    • 数据库连接能力很难扩展。数据库集群的连接数量有限,随着应用实例数量增加,越来越不够用。平台也因为过高的数据库连接而处于一个非常不稳定的状态。
    • 应用扩展成本高。通常系统出现业务处理瓶颈时,只是由于一个或几个功能模块负载较高,但因为所有功能打包在一起,没法对单独的几个功能模块进行服务能力扩展,只能将整个应用进行扩容,带来了资源额外配置的消耗。
  • 业务拆分,基于SOA理念新一代服务化框架:
    • 用户服务中心;千岛湖项目(交易中心,类目中心);五彩石项目(商品中心,店铺中心等)
    • 降低不同模块开发团队间的协同成本,业务响应更迅捷。
    • 大大降低系统间的耦合度及整体复杂度,各个开发团队可专注于各自的业务模块。
    • 避免了个别模块的错误给整体带来的影响。各个服务中心之间完全独立部署。
    • 业务拆分后解放了对单数据库集群连接数的能力依赖。每个核心服务中心有各自独立的数据库。
    • 做到针对性的业务能力扩容,减少不必要的资源浪费。
  • 中心化与去中心化服务框架的对比:
    • 中心化服务框架解决的根本诉求是实现异构系统之间的交互。ESB架构降低了系统耦合,在服务负载均衡、服务管控等方面提供了比点对点模式更专业的能力。
    • 去中心化服务框架解决的问题首先是系统扩展性问题。大的区别是服务提供者和调用者之间在进行服务交互时无需通过任何服务路由中介,避免因为中心点带来平台能力难扩展的问题,以及潜在的雪崩影响。
    • 服务调用方式带来的业务响应和扩展成本
      • 传统的ESB的服务调用方式是,每次调用者要向服务提供者进行交互请求时,都必须通过中心的ESB来进行路由。共出现4次网络会话创建和数据传输。
      • 去中心化的服务交互,一次服务调用只有两次网络会话创建和数据传输,在网络上的开销减少了一半。
      • 所有服务都通过服务总线,服务总线的访问和计算压力都很大。一般企业服务产品线包含的功能非常多,如服务发现、注册、路由等,对服务器的要求较高,所以每次扩容升级都会带来在软件授权和硬件资源上的不小投入。另外,服务总线的调用量比较大,网络带宽要求可能会超过目前网络设备的能力范围,成本高。
    • 雪崩效应束缚了中心化服务框架的扩展能力
      • 典型的雪崩效应:达到访问峰值时,每个ESB的负载水位会达到80%,这时如果某个ESB实例出现异常,其余服务器的负载水位就会上涨,高水位运行的服务器出现问题的概率大增,陆续有一些服务器不堪重负,之后,剩余的服务器可能不是一台一台地出问题,而是瞬间被访问洪流冲垮,全军覆没。
      • 雪崩事故恢复的时间和成本都非常高昂。因为不可能一台一台地重启服务器,一旦启动,前端的访问洪流会立即再次压跨服务器,正确的方式是首先切断前端对ESB的服务请求,10台服务器全部启动后再开放服务请求。如果没有来得及定位事故原因,仍然有再次雪崩的风险。
      • 增加中心点ESB实例数量,并不能线性扩展平台的服务能力。
      • 去中心化服务框架可以避免因为个别问题涉及整个平台的业务,多是部分服务出现问题。也更容易定位问题和故障恢复。
  • HSF, High Speed Framework
    • 服务提供者。提供服务功能实现的应用实例,为保障高可用性,一般是集群部署。每个HSF应用均是以war包形式存在,运行在定制的tomcat容器中,在容器层已经集成了hsf框架对服务提供者或服务调用者进行配置服务器发现、服务注册、订阅、失效转移等相关功能,所以应用中无需引入任何HSF相关的jar依赖包。
    • 服务调用者。多数也是以war应用包的方式运行在tomcat容器中。也有部分基于c/c++,php, node.js等服务调用者。
    • 地址服务器。给提供者和调用者提供所有配置服务器和diamond服务器的服务器列表信息,由Nginx提供该服务能力。
      • 在部署HSF服务环境时,会将整个环境中的配置服务集群(服务器IP集群)和DIAMOND服务器集群信息设置在地址服务器上。
      • 实际生产环境中,会部署为多台地址服务器提供负载均衡和高可用性的服务,服务提供者和调用者通过统一域名来访问这些地址服务器,DNS轮询实现地址服务器访问的高可用性。
    • 配置服务器。负责记录环境内所有服务发布和服务订阅信息,并推送到服务节点上。为了发布和订阅的推送效率,所有服务发布和订阅信息均保存在内存中。
      • 配置服务器与所有提供者、调用者均是长连接,采用心跳方式可监控到各服务运行节点的状况。一旦出现提供者节点故障,会自动推送更新后的服务提供者列表给相关的服务调用者端。
      • 生产环境中,会部署多台配置服务器用于服务发布、订阅、推送的负载均衡,在多个配置服务器间会进行实时同步,保证服务发布和订阅信息尽快同步到各服务节点上。
    • Diamond服务器。服务调用过程中对于服务调用安全管控的规则、服务路由权重、服务QPS阀值等配置规则的保存。持久化到后端MYSQL服务器中,同时会自动将这些规则推送到相关的服务节点上,使这些规则能立即在服务运行环境中生效。
      • 设置调用者IP白名单。
      • 通过用户认证方式控制服务调用。
      • 按服务器权重设置调用者对多个提供者节点的访问。
      • 设置某些服务的QPS能力上限值。
    • 网络通信框架netty。大并发量时,服务交互性能达到佳。
      • 这类RPC协议采用多路复用的TCP长连接方式,一个连接交替传输不同请求的字节块,避免了反复建立连接的开销,也避免了连接的闲置,从而减少了系统连接总数,同时还避免了TCP顺序传输中的线头阻塞问题。
    • 默认的数据序列化协议Hession。在数据量较小时性能表现出众,可以充分利用web容器的成熟功能,在处理大量用户访问时有优势。hession是在性能和稳定性同时考虑下的优序列化协议。
    • 容错机制。调用端已经保存了服务提供者列表,随机请求其中一台服务器时,如果发生了超时,会自动重试其他服务提供者。另外,配置服务器也会秒级感知到故障实例,推送新的服务提供者列表。
    • HSF框架的线性扩展支持。真正做到某个服务的业务处理能力随着服务器资源的增加得到线性的增长。

三、共享服务中心建设原则

共享服务中心是中台架构的基石。

  • 一般来说,服务能力包括两个层次:底层PAAS能力,解决大型架构在分布式、可靠性、可用性、容错、监控以及运维层面上的通用需求;业务能力,提供云化的核心业务支撑能力,直接决定是否能真正支持上层业务做到敏捷、稳定、高效。
  • 淘宝的共享服务中心包括多个服务中心:用户中心,商品中心,交易中心,店铺中心,物流中心,营销中心,数据服务中心等。
  • 服务中心的概念:
    • 服务和服务中心都是伴随着业务发展而变化的。所以不做过于超前的设计,也不做过于理想化的架构。
    • 服务中心提供的服务能力不拘泥于接口形式,主要分为三大类:依赖于接口的服务;依赖于工具的服务;依赖于数据的服务。
    • 服务中心是业务领域的概念,是根据业务和数据的完整性和独立性来设立的,服务中心包含的子模块更多是从系统设计和业务架构层面来考虑的。现实的业务往往需要多个子服务模块协作配合,才能更好地实现服务中心对外服务效率的大化。
  • 服务中心的划分原则:
    • 架构本来就是一个追求平衡的艺术,不仅是设计原则上的平衡,还要在技术、成本、资源、性能、团队等各方面进行平衡,以高效地解决主要问题。
    • 共享服务中心的架构目的:通过业务拆分,降低系统复杂性;通过服务共享,提供可重用性;通过服务化,达到业务支持的敏捷性;通过统一的数据架构,消除数据交互的屏障。
    • 服务中心建设要考量的三个重要方面:设计(面向对象的分析和设计方法)、运营(完整的业务模型,要有数据运营和业务整合的价值)、工程(分布式架构的优点和引入的分布式事务、问题排查等难题)。在规划服务中心时,要综合评估业务层对服务中心在数据库、业务以及运营方面的需求和技术上的投入。
    • 高内聚、低耦合原则。一个服务中心内的业务应该是相关性很高,依赖性很高的。
    • 数据完整性原则。服务化架构一个很重要的业务价值就是数据模型统一。不光是业务逻辑的关键数据,还要考虑业务相关性数据,不光是实时在线数据,还要考虑离线计算的数据。
    • 业务可运营性原则。我们期望服务中心是承载业务逻辑、沉淀业务数据、产生业务价值的业务单元。数据模型统一之后,可用很低成本把大数据技术引入到服务中心的架构中,让数据来源、数据分析、业务生产可以自然形成闭环。所以能否用大数据能力提升运营水平是服务中心原则之一。
    • 渐进性的建设原则。如果一开始规划时应用了太多的设计原则,在实施阶段就可能会碰到拆得过细有延迟太长的问题。推荐服务化从简单开始。

四、数据拆分实现数据库能力线性扩展

数据库是容易产生性能瓶颈的服务组件。

  • 读写分离方案:扩展了数据库的读能力,但在主数据库的数据写入能力上没法扩展。并且单表的数据量是有限的,达到一定数量后数据库性能会下滑。
  • 数据库分区方案:当单表数据量过大时,采用水平分区的方式对数据进行拆分。确保单个数据库中保存的数据量在单机数据库能提供良好的读写性能范围之内。但对于跨库的表join、事务操作、数据统计、排序等的支持变困难了。
  • 分布式数据层中间件TDDL,Taobao Distributed Data Layer.
    • 三层数据源每层都按JDBC规范实现,对前端应用没有任何代码侵入。
    • Matrix层:实现分库分表逻辑,持有多个GroupDS实例。
    • Group层:实现数据库的主备/读写分离逻辑,持有多个AtomDS实例。
    • Atom层:实现数据库连接等信息的动态推送,持有原子的数据源。
  • 原则一:数据尽可能平均拆分
    • 不管采用何种分库分表框架或平台,核心思路都是将原本保存在单表中太大的数据进行拆分,将这些数据分散保存到多个数据库的多个表中,避免单表过大带来的读写性能问题。
    • 如果拆分不均匀,还会产生数据访问热点,同样存在热点数据因为增长过快而又面临单表数据过大问题。
    • 数据如何拆分需要结合业务数据的结构和业务场景来决定。
    • 订单数据例子,方案一按订单ID取模,方案二按卖家用户ID取模。方案二可能会出现某些卖家的交易量非常大导致的数据不平均现象。
  • 原则二:尽量减少事务边界
    • 分库分表后,如果每一条SQL语句中都能带有分库分表键,分布式服务层在解析SQL后就能精准地将该SQL推送到数据所在的数据库上执行,这是执行效率高的方式。但不是所有业务场景在访问数据库时都能带上分库分表键,这时会出现全表扫描。
    • 事务边界:单个SQL语句,在后端数据库上同时执行的数量。
    • 典型的事务边界数量过大的例子:一条SQL语句被同时推送到后端所有数据库中运行。
    • 事务边界数量过大的弊端:
      • 系统的锁冲突概率增加。多个事务边界大的SQL并行执行时会出现这种情况。
      • 系统难以扩展。如果每次SQL都要全表扫描,整个平台的数据库连接数量取决于单个数据库的连接能力,也就意味着无法通过增加数据库实例来扩展数据库能力。
      • 整体性能降低。多个数据库请求的结果终要在分布式服务层做聚合、排序、分组等计算,如果不幸遇到了对大数据量的计算,则会占用较大的内存和CPU计算资源,影响整体分布式服务的处理性能。
    • 全表扫描在真实的业务场景中不可避免,但如果访问不频繁,计算数据量不会太大,则不会给数据库整体性能带来太大影响。
    • 如果高并发情况下请求,为了数据库整体的扩展能力,则要考虑异构索引手段来避免这样的情况发生。
    • 如果要在内存中进行大数据量的计算,并且这类SQL频繁调用,则考虑其他平台来满足这类场景需要,比如hadoop做离线分析。如果实时要求高,则可采用内存数据库或HBase这类平台。
  • 原则三:异构索引表尽量降低全表扫描频率
    • 数据异构索引的方式在实践中基本能解决和避免90%以上的跨join或全表扫描的情况,是分布式数据场景下,提升数据库服务性能和处理吞吐能力的有效技术手段。
    • 前例中,按订单ID取模进行分库分表,虽然能很好地满足订单数据均匀地分布在后端数据库中,但对于买家查看自己订单这种业务场景,就会出现全表扫描,而且这种场景是频繁出现的,必然给数据库带来扩展或性能问题,违背了“尽量减少事务边界”的原则。
    • 异构索引表:采用异步机制,将原表内的每一次创建或更新,都换另一个维度保存一份完整的数据表或索引表。本质上是很多互联网公司常用的思路“用空间换时间”。
    • 应用在创建或更新一条按订单ID为分库分表键的订单数据时,也会再保存一份按照买家ID为分库分表键的订单索引数据,使得同一买家的所有订单索引表都保存在同一数据库中。买家查看自己的订单时,先从订单索引表中取出订单号,再根据订单号到订单数据库中查找。这样通过两次访问效率高的SQL请求,解决了之前需要进行全表扫描的问题。
    • 数据全复制:订单按买家ID维度进行分库分表后的字段与订单ID维度分库分表的字段完全一样,就可以只进行一次数据访问了。但这样会带来大量数据冗余,因为一般来说,应用可能会需要按照多个维度创建多个异构索引表,存储成本会非常高。所以建议仅仅做异构索引表,而不是数据全复制。
    • 在数据库层实现异构索引:精卫填海产品。
      • 本质是一个基于MYSQL的实时数据复制框架。除在同步异构索引数据的场景外,可以认为精卫是一个MYSQL的数据触发器+分发管道。
      • 抽取器Extractor:获取数据库中产生的binlog日志并转换为event对象。binlog日志记录了对数据发生或潜在发生更改的sql语句,以二进制形式保存在磁盘中。
      • 过滤器Filter:用户可通过精卫自带的过滤器或基于接口定义开发的过滤器,对event对象中的数据进行处理。
      • 分发器Applier:将处理后的结果 转换为发送给DRDS的SQL语句。
      • 多线程管道实现:同步的数据量非常大的情况下,单线程管道任务成为系统瓶颈。多线程管道带来数据同步的顺序问题,目前精卫的解决思路是保证 同一条记录 或针对同一分库表 发生的数据同步按照顺序执行。
        • 如果SQL语句没有分库键,就对“库名+表名+主键值”哈希后对线程数取模,保证同一条记录的数据同步事件在同一线程中顺序执行。
        • 如果SQL中有分库键,则对“库名+分库键值”哈希后对线程数取模,保证不同逻辑表对针相同分库逻辑的记录变化顺序。
  • 原则四:将多条件频繁查询引入搜索引擎平台
    • 某些业务场景涉及到多条件查询,如淘宝商品搜索,调用非常频繁,如果采用SQL语句方式在数据库全表扫描,必然行不通。这种场景不建议采用数据库的方式提供服务,而是采用专业的搜索引擎平台。如OpenSearch。
  • 原则五:简单就是美
    • 如果“尽量减小事务边界”和“数据尽可能平均拆分”两个原则间发生了冲突,请选择“数据尽可能拆分”作为优先考虑原则。因为事务边界的问题相对好处理,无论是全表扫描或异构索引都可以。
    • 如果对每一个存在跨join或全表扫描的场景都采用异构索引的方式,数据库会出现大量冗余,数据一致性的保障也是个挑战,同时数据库间的业务逻辑关系也复杂很多,给数据库运维带来困难和风险。所以从系统风险的角度考虑,仅针对80%情况下访问的20%场景进行异构索引这样的处理,使这部分场景的性能优。而对其他80%的场景,采用为简单直接的方式?

五、异步化

  • 业务流程异步化:
    • 顺序调用的方式会造成系统处理一次前端请求所花的时间较长,给服务的会话处理线程带来长时间的资源占用,影响系统吞吐量。另一方面,用户等待时间过长也会造成用户体验变差。
    • 对于有严格先后调用关系的服务,保持顺序执行,对于能同步执行的所有服务均采用异步化方式处理。——消息中间件。
  • 数据库事务异步化:
    • 将大事务拆为小事务,降低数据库的资源被长时间事务锁占用而造成的数据库瓶颈,提升平台的处理吞吐量和事务操作的响应时间。
  • 数据库事务的四大属性:ACID
    • 原子性:整个事务中的语句要么全部执行,要么全部不执行
    • 一致性:数据库层面是指在一个事务执行之前和之后,数据会符合你设置的约束,由SQL SERVER保证;业务层面是指业务一致性,由开发人员保证。
    • 隔离性:事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。事务之间的互相影响的情况分为几种,分别为:脏读(Dirty Read),不可重复读,幻读。
    • 持久性:即使出现了任何事故比如断电等,事务一旦提交,则持久化保存在数据库中。
  • CAP理论:
    • 一个分布式系统,多只能同时满足一致性,可用性,分区容错性这三项中的两项。
    • 一致性:在一个系统中不论数据存放在何处,作为一个整体应该是完整和一致的。
    • 可用性:用户在访问时可以得到及时的响应。严格的定义是高性能可用性。可用性的要求里包含了时效性。
    • 分区容错性:分布式系统在遇到某节点或网络分区故障时,仍然能够对外提供满足一致性和可用性的服务。除了整个网络的故障外,其他故障都不能导致整个系统无法响应。
    • 举个栗子!!库存和超卖问题。
      • 简单的方案是建立类似于操作系统中的锁机制,要求所有节点的数据均同步后,才能进行数据读取操作。但这会带来可用性问题。因为不同数据节点间的数据同步是耗时的,大量采用锁机制会给数据层带来严重的性能瓶颈,导致平台在业务繁忙时的服务瘫痪或糟糕的用户体验。
      • 另一个方案是库存只保存一份,不复制。但因为网站的数据量太大,需要分库分表,数据存储到不同的节点上。如果某一时刻数据节点间的网络故障了,就会导致网站可能取不到完整的数据。这就是分区容忍性问题。
  • BASE理论:
    • 对CAP理论的延伸,核心思想是即使无法做到强一致性,但应用可以采用适合的方式达到终一致性。
    • 基本可用:分布式系统出现故障时,允许损失部分可用性,保证核心可用。比如大促时部分用户引导到降级页面,服务层只提供降级服务。
    • 柔性状态:允许系统存在中间状态,而中间状态不会影响系统整体可用性。比如分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时,就是柔性状态的体现。
    • 终一致性:系统中所有数据副本经过一定时间后,终能达到一致的状态。
  • ACID 和 BASE:
    • 两种截然相反的设计哲学。ACID是传统数据库常用的设计理念,追求强一致性。BASE是大型分布式系统中应用的设计理念,通过牺牲强一致性来换取高可用性。
    • 互联网应用的核心需求是高可用。服务不可用除了造成金钱上的损失外,更严重的是造成对平台的伤害。因为服务不可用一定会给客户带来商业损失或糟糕的用户体验,同时也会让客户对平台失去信心。
  • 如何实现高可用:
    • 高可用 = 系统构建在多机 = 分布式系统
    • 高性能 = 分布式系统的副产品
    • 分布式系统通信与单机通信的大区别在于,单机系统总线不会丢消息,而网络会。消息不可靠带来的副作用是数据或状态在多机之间同步的成本非常高。所以,分布式系统的首先不是强同步,而是终一致。终一致就一定会产生柔性状态。
  • 传统的分布式事务:两阶段提交协议。
    • 两阶段提交的关键在于“预备”操作。事务协调者在阶段通过对所有的分布式事务参与者请求“预备”操作,达成关于分布式事务一致性的共识。事务参与者必须完成所有的约束检查,并且确保后续提交或放弃时所需要的数据已持久化。在第二阶段,协调者根据之前达到的提交或放弃的共识,请求所有事务参与者完成相应的操作。
    • 提交事务的过程中需要在多个资源节点之间进行协调,而各节点对锁资源的释放必须等到事务终提交时,所以两阶段提交在执行同样的事务时会比一阶段提交消耗更多的时间。
    • 单机锁 = 时间消耗(微秒级)
    • 跨多机锁 = 时间消耗(毫秒级)= 1000倍单机时间消耗
    • 事务执行时间的延长,意味着锁资源发生冲突的概率增加。当事务并发量达到一定数量时,就会出现大量事务积压甚至出现死锁,系统性能和处理吞吐量就会严重下滑。
  • 柔性事务如何解决分布式事务问题
    • 1. 引入日志和补偿机制。通过日志记录找回事务的当前执行状态,并根据状态决定是重试异常步骤(正向补偿),还是回滚前序步骤(反向补偿)。缺点:技术实现没有XA这样的技术标准和规范,只是简单地采用数据库进行了分布式事务过程中的状态记录,并不能完全满足业务的终一致性。
    • 2. 可靠消息传递。由于“网络通信危险期”(分布式系统除单点可靠性之外需要考虑的另一个问题),节点间的消息传递会有三种状态:成功,失败,未知。对于未知状态,只能重复投递,这就要求消息处理程序必须实现幂等。
      • 根据业务场景的不同,实现幂等的方法也会有所不同。简单的是根据业务流水号写日志,阿里内部一般把这种日志叫做排重表。
    • 3. 实现无锁。
      • 如何很好地解决数据库锁问题是实现高性能的关键所在。但放弃锁并不意味着放弃隔离性。
      • 避免事务进入回滚。如果业务不管出现任何情况,只能向事务处理流程的顺向处理,这样即使中间状态对外可见,由于事务不会回滚,也不会导致脏读。
      • 辅助业务变化明细表。譬如在订单创建事务中只是在“库存预减明细表”中添加一条对应商品的库存预减记录,等成功付款才真正地扣减库存。而读取商品库存时:商品表中库存 - 预减库存之和。
      • 乐观锁。版本号方式。但乐观锁往往基于应用中的数据存储逻辑,有一定的局限性。如某个应用没有遵循乐观锁机制就可能造成脏数据。
  • 阿里内部的三套成熟的分布式事务解决方案
    • 1. 消息分布式事务。基于MQ提供的事务消息功能。
      • 通过消息进行事务异步,保证了事务的一致性,避免了两阶段提交事务方式对数据库长时间的资源锁定,所以数据库整体的吞吐和性能大大提升。
      • 本质上来说,对比柔性事务解决分布式事务的思路,消息服务扮演了事务日志的职能,事务参与者通过订阅消息建立了事务间的关联。如果出现异常,一般会采用正向补偿的方式,避免回滚。
      • 缺点是发起方要实现事务消息的发送,本地事务的执行,同时还要实现本地事务状态检查以及异常时的业务回滚机制。对开发人员提出了更高的要求。
    • 2. 支付宝XTS框架。基于BASE思想,类似两阶段提交的分布式事务方案。用来保障在分布式环境下高可用性,高可靠性的同时兼顾数据一致性的要求。
      • XTS可同时支持正向和反向补偿。
      • XTS是TCC(Try/Commit/Cancel)型事务,属于典型的补偿型事务。
      • 本质上给开发人员提供了一个实现分布式事务的事务框架,主要负责事务日志的记录,事务参与者需要实现XTS提供的接口。但因为需要开发人员实现事务的补偿机制,对开发人员的必智负担过于沉重?
    • 3. AliWare TXC事务服务。
      • 标准模式下不需开发人员自行实现事务回滚或补偿,平台支持自动按事务中事务操作的顺序依次回滚和补偿。
      • Client是与Server进行交互的客户端,其中部分客户端是事务发起者,事务的创建提交由事务发起者发起。另一部分客户端则是在事务中调用的服务提供者。在业务 异常时,由TXC的客户端发起事务的回滚。
      • Server扮演了事务协调者的角色,负责对整个事务上下文的日志记录以及在事务处理过程中全局的协调和控制。
      • RM为资源管理器,一般管理多个TXC数据源,负责在TXC客户端进行数据源访问时,与TXC服务器进行事务的注册 和状态更新。
      • TXC数据源,在原有的数据源上做了一层较薄的封装,因为TXC需要拦截到所有数据修改行为,从而为事务回滚提供数据的原始值。

六、缓存

略。

七、打造数字化运营能力

  • 业务服务化带来的问题:各个服务间的服务调用关系变得纷繁复杂,每天海量调用,并且所有服务都是点对点交互,导致出现问题时很难定位。
  • 鹰眼:针对分布式服务调用链跟踪平台。
    • JStorm流式计算引擎,对应用集群接收到的日志进行内容的解析拆分,按照不同业务场景的需求将拆分后的数据保存到不同的存储系统中。对于需要对日志信息进行实时业务统计的需求,会将日志信息保存到HBase中,实时汇总计算后给鹰眼服务器提供实时业务统计数据,比如某一服务实时的QPS值,交易金额的实时变化等。
    • 在每个应用集群的运行环境中,每当应用中进行了远程服务调用、缓存、数据库访问等操作时,会生成相关的访问日志并保存到应用所在的服务器上。
    • 每个应用所在的服务器上均有一个代理程序,专门负责实时地将生成的日志文件增量发送到鹰眼的处理集群上。
    • 实现分布式服务跟踪系统的主要思路 是通过服务调用链路各服务处理节点生成相应的日志信息,通过同一请求中生成的日志具有同一个ID,将不同系统或服务的日志串在一起,重组还原出更多有价值的信息。
    • 阿里在中间件层面上统一实现了鹰眼的上下文创建以及日志埋点功能,让调用上下文在中间件的网络请求中传递,同时将上下文信息保存在了本地ThreadLocal中。
    • TraceID,一般包含:IP地址,创建时间,顺序数。
    • RCPID,用于标识日志埋点顺序和服务调用间的嵌套关系。
  • TLOG:海量日志分布式处理平台。
    • 可以根据用户定制的处理流程,持续不断地对目标机器生成的日志数据进行解析,计算,入库等操作,对日志的处理流程提供了所见即所得的可视化配置界面。
  • 典型业务场景
    • 1. 服务实时监控。
    • 2. 服务调用链跟踪。根据traceId,搜索出服务调用链记录,详细查看出问题的请求是哪里。
    • 3. 服务调用链分析。为业务架构师度身定制的一个统计分析功能,对业务链路在实际生产中的运行状况有一个直观的了解,更有针对性地优化业务链路流程或提升某些服务的质量。
    • 4. 业务全息排查。将服务链路信息与业务事件进行了集成,将业务事件通过服务调用链的traceId&rcpId进行双向关联。当业务事件发生时,在应用代码中将该业务事件所在的服务调用链路、所在服务的信息以及当前业务事件的信息以日志的方式输出。这样,运维和开发人员就能通过业务轨迹的方式,查看某一业务请求的服务调用跟踪和相关的业务主键。——鹰眼从运维平台向运营平台转型。
    • 5. 业务实时监控。所有的业务事件日志都要求应用在发生时输出到日志中,再由TLOG日志处理平台实现对这些日志的采集、将任务下发到流式引擎JStorm中,将不同类型的数据保存到在线数据库HBase中,后通过API方式提供数据服务。

八、打造平台稳定性能力

  • 限流。
    • 服务就是给其他应用提供服务的,用户怎么调用服务是很难控制的,所以必须从服务自身做好保护,否则可能因为一个小问题造成平台级的故障。
    • 限流的作用相当于电路上的保险丝,过载时掐掉一些流量,让系统有能力集中资源以较快的速度处理平台处理能力范围内的业务请求。
    • 首先要对服务实例的部署量的能力有一个准确的评估——模拟数据压测。
    • 然后要针对服务资源的使用情况进行监控,如果超过服务处理上限则启动限流。
    • 接入层限流:在nginx上实现的扩展组件TMD,域名类限流,cookie限流,黑名单,以及一些安全策略等。
    • 服务限流:Sentinel平台。四大功能模块:授权,限流,降级,监控。
    • Sentinel平台有两大基础概念:资源和策略。对特定的资源采取不同的控制策略。
  • 降级。
    • 从服务调用者的角度,对所依赖的下游服务采取停止 调用的措施,以保证当前服务的处理效率。
    • 有些业务请求处理过程中,有些服务是否正常被调用或成功处理,对整个业务请求不会产生决定性影响,在调用服务链路中就会被标记为弱依赖服务。
    • 如果发现平台的整体水位已经逼迫大处理能力,限流是层保护,还可以将标记为弱依赖的服务平滑下线,节省资源。
  • 流量调度。
    • 核心是能过秒级获取服务器系统运行指标以及业务指标,通过流量调度平台设置的决策算法以及规则,当发现满足规则条件的指标状态发生时,对线上环境的服务器进行下线等操作,以屏蔽这些单点或局部出现故障的应用实例对整体平台产生扩展式的影响 。
    • HSF服务框架中的ConfigServer,在进行流量调度时,只要推送给消费者的服务提供者列表中带上权重信息,就可以控制所有服务提供者被请求的流量大小。当发现某些服务提供者出现服务响应慢或系统资源负载飙高时,实时降低对该服务器的服务路由权重,终达到自动流量调度来隔离故障。
  • 业务开关。
    • Switch,轻量级的开关集成框架。
  • 容量压测及评估规划。
  • 全链路压测平台。
  • 业务一致性平台。
    • 实时业务审计平台BCP,统一解决平台服务化后越来越突显的业务一致性问题。

相关文章